B
Bryan Castillo
I've been looking through CPAN and the newsgroups for information on
calling on objects asynchronously from perl. Basically, I was
thinking about a Tk application I was working on that used DBI and had
some SQL statements that may take 10 to 30 seconds. I really didn't
want the screen to freeze for that long.
So I've been searching for methods of asynchronous operations on
objects. There are of course threads, however I seems that it is not
reccomended to use multiple database connections with threads, or to
even have more than 1 thread use the DBI module, even when protected
through synchronization.
What I've come up with is the start of a module that uses IPC::Open2
to start a new perl interpreter. The process is givin a package name
containing methods it should delegate out to. The process reads in
complex hashes that have been serialized with the Storable module, one
element in the hash contains the name of the method to call in the
delegate package. The method is called and the results are also
returned serialized with the storable module.
Ive then been building a client library build around select(4-arg
form) to try to send and received the data (method call and argumentS)
non-blocking.
# it kind of works like this....
my $timeout = 10;
my $server = AsyncObject::Server::IPCO2->new();
# Internally the line above is doing this to start a new process
my $command =
'use AsyncObject::Server; '.
'my $server = AsyncObject::Server->new(\\*STDIN,\\*STDOUT); '.
'$server->start();';
my $pid = open2(
$rdrfh, $wtrfh,
$Config{perlpath},
'-e',
$command
);
#-----------------------
my $request = $server->command('load', 'Async:elegate::database');
my $reply;
while (!$reply = $request->getReply($timeout)) {
# whatever
}
if ($reply->{status} != 1) {
die $reply->{error};
}
$request = $server->call('connect', $user, $pass);
while (!$reply = $request->getReply($timeout)) {
# ....
}
if ($reply->{status} != 1) {
die $reply->{error};
}
Then i was planning on exposing the input and output handles, which
could be
used from Tk fileevent, or with select, (to handle more than one
asynchronous object call.)
# just pseudo - code.
$request = $server->call('exec_sql', 'select count(*) from blah');
my $in = $request->getInputHandle();
# use select on $in to determine when request can be sent to server
# perhaps in a fileevent
# can use more granular methods on callback from select
$request->send($timeout);
if ($request->sendComplete()) {
my $out = $request->getOutputHandle();
# use select with output handle or fileevent
on_callback:
$request->receive($timeout);
if ($request->complete()) {
my $result = $request->getResult();
}
}
Is there anything out there like this? I haven't been able to find
anything on CPAN. There is RPC:lServer and RPC:lClient, however I
was looking for something where the client would start the server on
demmand (theoreticaly this could still be done with
RPC:l(Server|Client), but I didn't want to use sockets), and I was
looking for something that would allow asynchronous calls on the
objects.
calling on objects asynchronously from perl. Basically, I was
thinking about a Tk application I was working on that used DBI and had
some SQL statements that may take 10 to 30 seconds. I really didn't
want the screen to freeze for that long.
So I've been searching for methods of asynchronous operations on
objects. There are of course threads, however I seems that it is not
reccomended to use multiple database connections with threads, or to
even have more than 1 thread use the DBI module, even when protected
through synchronization.
What I've come up with is the start of a module that uses IPC::Open2
to start a new perl interpreter. The process is givin a package name
containing methods it should delegate out to. The process reads in
complex hashes that have been serialized with the Storable module, one
element in the hash contains the name of the method to call in the
delegate package. The method is called and the results are also
returned serialized with the storable module.
Ive then been building a client library build around select(4-arg
form) to try to send and received the data (method call and argumentS)
non-blocking.
# it kind of works like this....
my $timeout = 10;
my $server = AsyncObject::Server::IPCO2->new();
# Internally the line above is doing this to start a new process
my $command =
'use AsyncObject::Server; '.
'my $server = AsyncObject::Server->new(\\*STDIN,\\*STDOUT); '.
'$server->start();';
my $pid = open2(
$rdrfh, $wtrfh,
$Config{perlpath},
'-e',
$command
);
#-----------------------
my $request = $server->command('load', 'Async:elegate::database');
my $reply;
while (!$reply = $request->getReply($timeout)) {
# whatever
}
if ($reply->{status} != 1) {
die $reply->{error};
}
$request = $server->call('connect', $user, $pass);
while (!$reply = $request->getReply($timeout)) {
# ....
}
if ($reply->{status} != 1) {
die $reply->{error};
}
Then i was planning on exposing the input and output handles, which
could be
used from Tk fileevent, or with select, (to handle more than one
asynchronous object call.)
# just pseudo - code.
$request = $server->call('exec_sql', 'select count(*) from blah');
my $in = $request->getInputHandle();
# use select on $in to determine when request can be sent to server
# perhaps in a fileevent
# can use more granular methods on callback from select
$request->send($timeout);
if ($request->sendComplete()) {
my $out = $request->getOutputHandle();
# use select with output handle or fileevent
on_callback:
$request->receive($timeout);
if ($request->complete()) {
my $result = $request->getResult();
}
}
Is there anything out there like this? I haven't been able to find
anything on CPAN. There is RPC:lServer and RPC:lClient, however I
was looking for something where the client would start the server on
demmand (theoreticaly this could still be done with
RPC:l(Server|Client), but I didn't want to use sockets), and I was
looking for something that would allow asynchronous calls on the
objects.