[Zope-Perl] Benefits of Zope multithreading
Gisle Aas
gisle@ActiveState.com
08 Sep 2000 12:52:19 +0200
--=-=-=
Monty Taylor <mtaylor@information-innovation.com> writes:
> Gisle Aas wrote:
>
> > The consequence of this is really that PerlMethods should not be used
> > for anything that will not return fast. This probably also make the
> > ZDBI_DA not very usable.
> >
>
> Damn it.
Fear not. Perl ithreads is going to save us :-)
>
> >
> > I'm now investigating if there is a way to fix this. If we make sure
> > references to perl data do not escape to python (that means not
> > providing the "perl ref objects") then we can probably let there be
> > separate perl interpreters for each thread. Then we don't need any
> > perl lock at all and PerlMethods will be able to run in true parallel
> > on multiple CPUs. When these PerlMethods call back to python in order
> > to invoke methods on the Zope objects passed as argument(s) they will
> > be sequentialised though.
> >
>
> Would this mean we couldn't instatiate a Perl Object from within Python? What
> happens to dbi.py/ZDBI_DA in that case?
We have to drive all the DBI logic in perl then. The attached
stripped down test works for me now. It runs a separate DBI
connection from each thread even though we only have a single python
DB object.
For ZDBI_DA it means that if you enable one such connection you will
after a while have as many database connections as you have threads
running in Zope (and it will be hard to close them down :-( ).
Regards,
Gisle
--=-=-=
Content-Type: text/python
Content-Disposition: attachment; filename=thread-dbi.py
Content-Description: Test program
import time
import perl
import sys
import thread
class DB:
def __init__(self, source):
self.source = source
self.query("select 1")
def query(self, sql):
if not perl.defined("ZopeDBI::query"):
self.dbi_init()
return perl.call("ZopeDBI::query", self, sql);
def dbi_init(self):
perl.require("ZopeDBI")
def close(self):
pass
db = DB("DBI:mysql:database=fotodb")
print db.query("select count(*) from img")
def f(wait_time):
id = thread.get_ident()
print "Thread", id
for i in range(10):
print str(id)+":", db.query("select id from img limit 3")
time.sleep(wait_time)
for i in range(10):
thread.start_new_thread(f, (0.1,))
f(1)
print "waiting..."
time.sleep(10*60)
--=-=-=
Content-Type: text/perl
Content-Disposition: attachment; filename=ZopeDBI.pm
Content-Description: Perl library to go with it.
package ZopeDBI;
print "Loading ZopeDBI\n";
use DBI;
use Python;
sub dbi_connect {
my $self = shift;
my $source = $self->source;
print "Connecting to $source\n";
DBI->connect($source, "gisle", "",
{
RaiseError => 1,
PrintError => 0,
AutoCommit => 1,
}
);
}
my %dbh; # cache of DBI handles
sub query {
my($self, $sql) = @_;
my $id = Python::id($self);
my $dbh = $dbh{$id} || ($dbh{$id} = dbi_connect($self));
my $sth = $dbh->prepare($sql);
$sth->execute;
my $rows = Python::list();
while (my @row = $sth->fetchrow) {
$rows->append(Python::list(@row));
}
$rows;
}
1;
--=-=-=--