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.

In reply to RFC: RPC_OO.pm by Necos

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.