POE-Component-Lightspeed
view release on metacpan or search on metacpan
lib/POE/Component/Lightspeed/Introspection.pm view on Meta::CPAN
# We export some stuff
require Exporter;
our @ISA = qw( Exporter );
our @EXPORT_OK = qw( list_kernels list_sessions list_states );
# Lists all kernels
sub list_kernels {
# Get the heap from the router session
my $heap = $POE::Kernel::poe_kernel->_resolve_session( $POE::Component::Lightspeed::Router::SES_ALIAS )->get_heap();
# Get the list of kernels
my @kernels = $heap->{'GRAPH'}->vertices();
# Return it!
return \@kernels;
}
# Lists all sessions in kernel X
sub list_sessions {
my( $dest, $rsvp ) = @_;
# Validate the kernel
if ( ! defined $dest ) {
return undef;
} elsif ( ref( $dest ) ) {
if ( ref( $dest ) eq 'POE::Component::Lightspeed::Hack::Session' ) {
# Cool! Convert it :)
$dest = $dest->remote_kernel();
} elsif ( ref( $dest ) ne 'ARRAY' ) {
return undef;
}
}
# Validate the RSVP
$rsvp = POE::Component::Lightspeed::Router::ValidateDestination( $rsvp );
if ( ! defined $rsvp ) {
return undef;
}
# Get the heap from the router session
my $heap = $POE::Kernel::poe_kernel->_resolve_session( $POE::Component::Lightspeed::Router::SES_ALIAS )->get_heap();
# Get the session alias
my @list = $POE::Kernel::poe_kernel->alias_list( $POE::Kernel::poe_kernel->get_active_session() );
if ( ! defined $list[0] ) {
$list[0] = $POE::Kernel::poe_kernel->get_active_session()->ID;
}
# Construct the from array
my $from = [];
$from->[ FROM_KERNEL ] = $heap->{'MYKERNEL'};
# Add the session
$from->[ FROM_SESSION ] = $list[0];
# Add the state
$from->[ FROM_STATE ] = $POE::Kernel::poe_kernel->get_active_event();
# Add the file/line
push( @$from, (caller)[1,2] );
# Is it a local introspection request?
if ( $dest eq $heap->{'MYKERNEL'} or $dest eq '*' ) {
# Send it to the router to emulate a "packet"
$POE::Kernel::poe_kernel->post(
$POE::Component::Lightspeed::Router::SES_ALIAS,
'ACTION_' . ACTION_INTROSPECTION,
[
$heap->{'MYKERNEL'}, # MSG_TO
$heap->{'MYKERNEL'}, # MSG_FROM
ACTION_INTROSPECTION, # MSG_ACTION
[ # MSG_DATA
'SESSION', # INTROSPECTION_WHAT
$from, # INTROSPECTION_FROM
$rsvp, # INTROSPECTION_RSVP
],
],
);
}
# Send it off!
if ( $dest ne $heap->{'MYKERNEL'} ) {
POE::Component::Lightspeed::Router::SendMessage( $heap, [
$dest, # MSG_TO
undef, # MSG_FROM
ACTION_INTROSPECTION, # MSG_ACTION
[ # MSG_DATA
'SESSION', # INTROSPECTION_WHAT
$from, # INTROSPECTION_FROM
$rsvp, # INTROSPECTION_RSVP
],
] );
}
# All done!
return 1;
}
# Lists all states in session X in kernel Y
sub list_states {
my( $dest, $rsvp ) = @_;
# Validate the destination
if ( ! defined $dest ) {
return undef;
} elsif ( ! ref( $dest ) ) {
# Okay, before we send it to ValidateDestination, we have to make sure there's a '/' at the end to make it happy
if ( $dest =~ m|^poe://(?:[^/]+)/(?:[^/]+)$| ) {
$dest .= '/';
}
# If it's terribly corrupt, who cares, ValidateDestination will catch it for us :)
$dest = POE::Component::Lightspeed::Router::ValidateDestination( $dest );
if ( ! defined $dest ) {
return undef;
}
} elsif ( ref( $dest ) eq 'ARRAY' ) {
# Must have 2 parts
if ( scalar( @$dest ) != 2 ) {
return undef;
}
} elsif ( ref( $dest ) eq 'HASH' ) {
# Must have 2 parts
if ( ! exists $dest->{'KERNEL'} or ! exists $dest->{'SESSION'} ) {
return undef;
} else {
# Change it into an array
$dest = [ $dest->{'KERNEL'}, $dest->{'SESSION'} ];
}
} elsif ( ref( $dest ) eq 'POE::Component::Lightspeed::Hack::Session' ) {
# Cool! Convert it :)
$dest = [ $dest->remote_kernel(), $dest->remote_session() ];
} else {
# What the hell is it?
return undef;
}
# Validate the rsvp
$rsvp = POE::Component::Lightspeed::Router::ValidateDestination( $rsvp );
if ( ! defined $rsvp ) {
return undef;
}
# Get the heap from the router session
my $heap = $POE::Kernel::poe_kernel->_resolve_session( $POE::Component::Lightspeed::Router::SES_ALIAS )->get_heap();
# Construct the from array
my $from = [];
$from->[ FROM_KERNEL ] = $heap->{'MYKERNEL'};
# Add the session
my @list = $POE::Kernel::poe_kernel->alias_list( $POE::Kernel::poe_kernel->get_active_session() );
if ( ! defined $list[0] ) {
$list[0] = $POE::Kernel::poe_kernel->get_active_session()->ID;
}
$from->[ FROM_SESSION ] = $list[0];
# Add the state
$from->[ FROM_STATE ] = $POE::Kernel::poe_kernel->get_active_event();
# Add the file/line
push( @$from, (caller)[1,2] );
# Is it a local introspection request?
if ( POE::Component::Lightspeed::Router::FindOurself( $heap->{'MYKERNEL'}, $dest->[ DEST_KERNEL ] ) ) {
# Send it to the router to emulate a "packet"
$POE::Kernel::poe_kernel->post(
$POE::Component::Lightspeed::Router::SES_ALIAS,
'ACTION_' . ACTION_INTROSPECTION,
[
$heap->{'MYKERNEL'}, # MSG_TO
$heap->{'MYKERNEL'}, # MSG_FROM
ACTION_INTROSPECTION, # MSG_ACTION
[ # MSG_DATA
'STATE', # INTROSPECTION_WHAT
$from, # INTROSPECTION_FROM
$rsvp, # INTROSPECTION_RSVP
$dest->[ DEST_SESSION ], # INTROSPECTION_ARGS
],
],
);
}
# Send it off!
POE::Component::Lightspeed::Router::SendMessage( $heap, [
$dest->[ DEST_KERNEL ], # MSG_TO
undef, # MSG_FROM
ACTION_INTROSPECTION, # MSG_ACTION
[ # MSG_DATA
'STATE', # INTROSPECTION_WHAT
$from, # INTROSPECTION_FROM
$rsvp, # INTROSPECTION_RSVP
$dest->[ DEST_SESSION ], # INTROSPECTION_ARGS
],
] );
# All done!
return 1;
}
# End of module
1;
__END__
=head1 NAME
POE::Component::Lightspeed::Introspection - Discovering your network!
=head1 SYNOPSIS
use POE;
use POE::Component::Lightspeed::Client;
use POE::Component::Lightspeed::Server;
use POE::Component::Lightspeed::Introspection qw( list_kernels list_sessions list_states );
# Spawn your client/server session here and connect to the network
# Find out the kernels in the network
my $kernels = list_kernels();
print "Kernels:", join( " ,", @$kernels );
# Query a specific kernel for it's sessions
( run in 0.697 second using v1.01-cache-2.11-cpan-7f9471e7e0a )