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 )