As many of you know, I have been struggling with a lightweight RPC module. This module was originally written by Sriram in Advanced Perl Programming. It was meant to be used in conjuction with subs, not OO code. Unfortunately, the codebase I was working on is OO based. So, I went about deconstructing the RPC module, looking at the way the code was frozen (using FreezeThaw) and thawed out (again, using FreezeThaw). After a week or two of struggling, I accomplished the code rewrite.

The rewritten RPC module is modeled for client-server use. The code (which can be improved) is:

package RPC_OO; use Msg; use strict; use Carp; use vars qw(@ISA); @ISA = qw(Msg); use FreezeThaw qw(freeze thaw); #----------------------------------------------------------------- # Server side sub new_server { my ($pkg, $my_host, $my_port) = @_; return $pkg->SUPER::new_server($my_host, $my_port, sub {$pkg->_log +in(@_)}); } sub _login { return \&_event_dispatcher; } sub _event_dispatcher { my ($conn, $msg, $err) = @_; return if ($err); # Need better error handling. return unless defined($msg); my ($dir, $id, $gimme, $obj, $method, @params) = thaw ($msg); my ($result, @results); if ($dir eq '>') { # Incoming msg. (outgoing msg from client, that is) eval { no strict 'refs'; # Because we call the subroutine using # a symbolic reference if ($gimme eq 'a') { # Want an array back @results = $obj->$method(@params); } else { $result = $obj->$method(@params); } }; if ($@) { $msg = bless \$@, "RPC::Error"; $msg = freeze('<', $id, $msg); } elsif ($gimme eq 'a') { $msg = freeze('<', $id, @results); } else { $msg = freeze('<', $id, $result); } $conn->send_later($msg); } else { #Someone tried to send a bogus command... $conn->disconnect(); } } #----------------------------------------------------------------- # Client side sub connect { my ($pkg, $host, $port) = @_; my $conn = $pkg->SUPER::connect($host,$port, \&_response); return $conn; } my $send_err = 0; sub handle_send_err { $send_err = $!; } my $g_msg_id = 0; sub rpc { my $conn = shift; my $obj = shift; my $method = shift; my $gimme; $gimme = wantarray ? 'a' : 's'; my $msg_id = ++$g_msg_id; my $serialized_msg = freeze ('>', $msg_id, $gimme, $obj, $method, +@_); # Send and Receive $conn->send_later ($serialized_msg); if ($send_err) { die "RPC Error: $!\n"; } do { Msg->event_loop(1); # Dispatch other messages until we get a r +esponse } until (exists $conn->{rcvd}->{$msg_id} || $send_err); # Dequeue message my $rl_retargs = delete $conn->{rcvd}->{$msg_id}; # ref to list if (ref($rl_retargs->[0]) eq 'RPC::Error') { die ${$rl_retargs->[0]}; } wantarray ? @$rl_retargs : $rl_retargs->[0]; } sub _response { my ($conn, $msg, $err) = @_; return if ($err); # Need better error handling. return unless defined($msg); my ($dir, $id, @data) = thaw ($msg); $conn->{rcvd}->{$id} = [@data]; } 1;
I decided to use the same Msg.pm library that Sriram developed in Advanced Perl Programming. Some of the code even has comments from the original RPC module. When I develop better socket programming skills, I'll go and write my own Msg.pm library with more features and such. I just wanted to know what the monks here think of this module. Is it CPAN worthy? Should I just email Sriram with this newer module and ask him to include it in a reprint of Advanced Perl Programming? Or should I just stick this module in my backpack and pull out as needed? Also, any constructive criticism on how to make this module a little better is appreciated.

Theodore Charles III
Network Administrator
Los Angeles Senior High
4650 W. Olympic Blvd.
Los Angeles, CA 90019
323-937-3210 ext. 224
email->secon_kun@hotmail.com

Update: Fixed a small typo in copying the module into the form at line 6 of the code.

Replies are listed 'Best First'.
Re: RFC: RPC_OO.pm
by Juerd (Abbot) on Mar 18, 2002 at 07:40 UTC

    package RPC_OO;

    This is not a CPAN-worthy script (yet), because it has very bad error handling (if any). Referencing a global special scalar ($@ here) is probably not a very good idea. There are two kinds of false wantarrays, namely defined and undefined - you should think about handling them both.

    RPC_OO is a bad package name, because it's top-level, and there already are a lot of RPC modules in the RPC:: namespace. _IF_ (and I think you really should not) you decide to put this on CPAN, at least rename it to RPC::OO.

    And all modules should have detailed documentation, of course!

    I haven't used RPC in any way, but I think it needs to be easy to use. That is, I think you should know only a line or five to get it running, and not have to copy/paste a given synopsis.

    U28geW91IGNhbiBhbGwgcm90MTMgY
    W5kIHBhY2soKS4gQnV0IGRvIHlvdS
    ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
    geW91IHNlZSBpdD8gIC0tIEp1ZXJk
    

      Thanks for the constructive criticism. I've already talked with a few monks about rewriting the code for this module once I have the time to do so. I've been going over a few very nice error handling routines in my head that I think would work well with the code (of course, it's kind of mean to look into someone's message). Chances are, when I put this little RPC module up for comments again, it will be named something completely different (like RPC::OO, which you suggested... or something more exotic, like Net::RPC).

      Ironically enough, I was told that RPC could be done via SOAP and POE, but this was something I had been planning on doing (just to see if I could) for a long time. Thanks to all the folks around here at the Monastery that put up with my fits of madness. For the time being, this module will run in my production code for thorough testing before I begin rewrites of code. Maybe someday this code will become CPAN worthy. Only time will tell...

      Theodore Charles III
      Network Administrator
      Los Angeles Senior High
      4650 W. Olympic Blvd.
      Los Angeles, CA 90019
      323-937-3210 ext. 224
      email->secon_kun@hotmail.com
Re: RFC: RPC_OO.pm
by perrin (Chancellor) on Mar 18, 2002 at 15:28 UTC
    The trouble is, you're hacking on an unsupported demo module which the author explicitly said was not production-ready. To me, it would make more sense to go with one of the other RPC options on CPAN than to try and make this one catch up with them.
      True. Sriram did say that the module was not production ready. However, I did like the ideas he used to develop the module, so I used it as a basis for rewriting his RPC module. Hopefully, in the near future (which I pointed out before), after a little more studying, I can begin rewriting the messaging library. I know there are other modules (SOAP and POE are the first that come to mind) that are very powerful. This was mainly a project that I set out to do just to see if I could do it. Also, I think that this module might come in handy for people that can't have any HTTP services running on their network (like myself). Of course, like Juerd pointed out, there is still lots of work to be done before this module is even close to CPAN worthy.

      Theodore Charles III
      Network Administrator
      Los Angeles Senior High
      4650 W. Olympic Blvd.
      Los Angeles, CA 90019
      323-937-3210 ext. 224
      email->secon_kun@hotmail.com