Question

I am trying to have a pool of shared connections that can be accessed by Net::Server instances. Unfortunately IPC::Shareable does not allow me to store the connections as they are code references. This is a stripped down version of the code:

use IPC::Shareable (':lock');
use parent 'Net::Server::Fork';
use MyConnectClass;

sub login {
    return MyConnectClass->new();
};

my %connection;
tie %connection, 'IPC::Shareable', 'CONN', {
  'create'    => 1,
  'exclusive' => 0,
  'mode'      => 0666,
  'destroy'   => 'yes',
}
or croak 'Can not tie connection variable';

sub add_connection {
    my $id  = shift(@_);
    my $con = shift(@_);
    $connection{$id} = $con;
};

sub get_connection {
    my $id = # .. find unused connection
    return $connection{$id};
}

sub process_request {
  my $self       = shift(@_);

  eval {
    my $connection = get_connection();
    my $line       =  <STDIN>;
    # .. use $connection to fetch data for user
  };
};

for (my $i=0; $i<10; $i++) {
    add_connection($i, &login);
};

main->run(
  'host'        => '*',
  'port'        => 7000,
  'ipv'         => '*',
  'max_server'  => 3,
};

Unfortunately the program dies after the first login: 'Can't store CODE items at ../../lib/Storable.pm'. This happens even when hiding $connection in an anonymous array. I am looking for an alternative to utilize the pool.

I appreciate your support

No correct solution

OTHER TIPS

I am unable to propose an alternative module, but make a suggestion which may or not be of use. While you cannot store CODE, you can store strings which can be evaluated to run. would it be possible to pass a reference to the string q!&login! which you can dereference call after being assigned to $connection. ?

#!/usr/bin/perl
use warnings;
use strict;

use Storable;

my $codestring = q'sub { q^japh^ };' ;

#my $codestring = q'sub { return MyConnectClass->new(); }';
#
# for (0..9){ add_connection($i, $codestring) }

open my $file, '>', '.\filestore.dat' or die $!;

store \ $codestring, $file;

close $file;

open $file, '<',  '.\filestore.dat' or die " 2 $!";

my $stringref = retrieve $file;    # my $con = get_connection()

close $file;

print &{ eval $$stringref } ;      # &{eval $$con} ; 
exit 0;                            # my $line = <STDIN>; ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top