On Wed, Jul 27, 2005 at 10:21:10AM -0700, Dean Arnold wrote:
> 
> Could either you or Stas provide the executive summary (aka
> "Passing Resources Between Perl Threads for Dummies") of how this works ?
> The tarball Stas pointed me at doesn't have any real POD (just a template
> README), and trying to glean the info from the mail archives is (at best)
> challenging. I'm having a serious bout of cognitive dissonance trying
> to reconcile what I know about
> 
>       - Perl's thread model (esp. wrt sharing data)
>       - DBI
>       - writing DBD's
> 
> with what you're telling me wrt DBI::Pool. Does DBI::Pool require
> that the thread being passed the connection already have the DBI
> connection context as a result of being spawned out of the
> thread in which the connection was created ?

No.

> Will it work for
> pure-Perl DBDs (seems like there'd be lots of driver-specific
> context copying required...) ?

It can be made to work for pure-Perl DBDs.

Let's start with the docs for take_imp_data() (added in DBI 1.36):

---snip---

  $imp_data = $dbh->take_imp_data;

Leaves the $dbh in an almost dead, zombie-like, state and returns a
binary string of raw implementation data from the driver which describes
the current database connection. Effectively it detaches the underlying
database API connection data from the DBI handle. After calling
take_imp_data(), all other methods except DESTROY will generate a
warning and return undef.

Why would you want to do this? You don't, forget I even mentioned it.
Unless, that is, you're implementing something advanced like a
multi-threaded connection pool.

The returned $imp_data can be passed as a dbi_imp_data attribute to a
later connect() call, even in a separate thread in the same process,
where the driver can use it to 'adopt' the existing connection that the
implementation data was taken from.

Some things to keep in mind...

* the $imp_data holds the only reference to the underlying database API
  connection data. That connection is still 'live' and won't be cleaned
  up properly unless the $imp_data is used to create a new $dbh which
  can then disconnect() normally.

* using the same $imp_data to create more than one other new $dbh at a
  time may well lead to unpleasant problems. Don't do that.

---snip---

The key point is that $imp_data is a plain simple string.
It just happens to contain (typically) a chunk of binary data.
The only useful thing you can do with that data is pass it to
a connect call for the same driver:

  DBI->connect(..., { dbi_imp_data => $imp_data })

The driver then says to itself "I don't need to actually connect to the
database because I can just copy $imp_data which contain a previously
established connection".

In terms of the internals, $imp_data is a copy of the imp_xxh struct.

Pure perl drivers are free to return any chunk of data, as a string, so
long as it can be used to recover the connection information. So for a
pure perl driver using a socket, $imp_data could be the integer file
descriptor of the socket. Note that it can't (shouldn't) be a reference
to a filehandle object since references can't easily be passed between
threads.

Tim.

Reply via email to