http://www.perlmonks.org?node_id=1010607


in reply to Re^2: Seeking design improvements for Perl code library remote server
in thread Seeking design improvements for Perl code library remote server

Your package doesn't match the filename, see Simple Module Tutorial , the filename should match the package name.

Instead of comments write documentation :) Tutorials: POD in 5 minutes and maybe

See Modern Perl and Class::Inspector AND Howto create a Moose baseclass/superclass/contract? Moose equivalent of Module::Pluggable? Favorite way to create base/super class?

You might start with

module-starter --author="David Luu" --email=man...mail.com --license=LGPL --module=RobotRemoteServer,RobotRemoteServer::Frontier,RobotRemoteServer,RobotRemoteServer::RPCXMLServer

Added to MANIFEST: Changes
Added to MANIFEST: ignore.txt
Added to MANIFEST: lib/RobotRemoteServer.pm
Added to MANIFEST: lib/RobotRemoteServer/Frontier.pm
Added to MANIFEST: lib/RobotRemoteServer/RPCXMLServer.pm
Added to MANIFEST: Makefile.PL
Added to MANIFEST: MANIFEST
Added to MANIFEST: README
Added to MANIFEST: t/00-load.t
Added to MANIFEST: t/boilerplate.t
Added to MANIFEST: t/manifest.t
Added to MANIFEST: t/pod-coverage.t
Added to MANIFEST: t/pod.t
Created starter directories and files

Then maybe write something like


package RobotRemoteServer;
use Class::Inspector;

sub get_keyword_names { my ($self) = @_; my $class = $self->lib; my @methods = Class::Inspector->methods( $class, 'public' ); return \@methods; } sub run_keyword { my $self = shift; my ($stdout, $stderr) = capture { ... }; } sub start_server { my $self = shift; $self->backend->start_server; }

package RobotRemoteServer::Frontier; sub _shut_down_request { RobotRemoteServer::Frontier sub start_server { my ($self) = @_; my $svr = Frontier::Daemon->new( methods => { get_keyword_names => sub { $self->get_keyword_names(@_) }, run_keyword => sub { $self->run_keyword($_[0], eval{@{$_[1]}}) } +, stop_remote_server => sub { $srv->_shutdown('yes please'); $self->schedule_shutdown; return; }, .... } sub schedule_shutdown { my $self = shift; my $url = $self->url; if( eval { require threads; } ){ threads::async { sleep 5; require Frontier::Client; Frontier::Client->new( 'url' => $url )->call('stop_remote_s +erver'); }; } elsif( eval { require Proc::Background; } ){ Proc::Background->new( $^X, '-e', q{ use Frontier::Client; sleep 5; my $url = shift @ARGV; Frontier::Client->new( 'url' => $url )->call('stop_remote_server'); exit; }, $url, ); } } sub Frontier::Daemon::_shutdown { my( $self, $true ) = @_; ${*$self}{'_Frontier::Daemon::_shutdown'} = !!$true if $true; return ${*$self}{'_Frontier::Daemon::_shutdown'} ; } sub Frontier::Daemon::accept { ## monkeypatch package Frontier::Daemon; my $self = shift; if( $self->_shutdown ){ close $self; return; } else { return $self->SUPER::accept; } }

To handle shutdown in similar way as https://robotframework.googlecode.com/hg/tools/remoteserver/robotremoteserver.py you could monkeypatch shutdown, but writing your own frontier deaemon ( Frontier::Daemon::Forking ) is probably the correct way to do it

backend is the new argument, RobotRemoteServer::Frontier by default

use RobotRemoteServer; #my $rob = RobotRemoteServer->new (qw' host localhost port 666 '); my $rob = RobotRemoteServer->new (qw' host localhost port 666 backend Frontier lib ExampleLibrary '); $rob->start_server;

Maybe it makes more sense for backends to be named as RobotRemoteServer::Backend::Frontier ...

But that is a start, pod beats comments, seperate backends into seperate modules, use existing modules for introspection , has-a not isa-a ...

Future direction:
maybe Moo/Moose or Badger for accessors/mutators...
Maybe POE server ( ex Hopkins::Plugin::RPC ), ex?Catalyst::Plugin::Server::XMLRPC, Plack for ideas
maybe cooperation with Daemon::Generic, AnyEvent::XMLRPC, ...

If I were more knowledgeable, I might make better suggestions ;)

Replies are listed 'Best First'.
Re^4: Seeking design improvements for Perl code library remote server
by daluu (Initiate) on Dec 29, 2012 at 03:05 UTC

    Thanks, that's good constructive comment/criticism. I'll look into those when I have time. I hope to get more feedback from others, if there is any more feedback that can be offered.

    One question to add, if anyone can provide feedback: how might I best test this Perl remote server implementation and package the tests for CPAN module distribution? And any tutorial links for testing Perl code?

Re^4: Seeking design improvements for Perl code library remote server
by daluu (Initiate) on Feb 09, 2015 at 02:38 UTC
    Well, I procrastinated until now with looking into the details of the suggested code. Now that I'm really looking, not being a Perl guru, I'm confused with how the breakdown of the code is between the backend and the server interface. I was thinking of having the server (frontend) component be packaged as RobotRemoteServer::Server or keep it as RobotRemoteServer as it originally was.

    But right now, I don't see how the backend links to the frontend in the suggested code in terms of things like using statements (to use front/back end package in the other) along with how the actual object instance shares method & properties between the packages.

    Can you/someone elaborate? FYI, I've never built multi-file packages, only single file contained packages.