Subject Re: [firebird-python] FDB v1.4.2
Author Pavel Cisar
Hi Dominik,

Dne 17.11.2014 v 14:54 Dominik Psenner dominik.psenner@...
[firebird-python] napsal(a):
>
> I believe that I have found a solution by shuffling the
> __wait_for_events() invoke. This is the patch (also available as
> attachment):

Your solution is sound, change will appear in next release (1.4.4).

> While inspecting gc.garbage I have further noticed that it does
> contain several fdb.fbcore.PreparedStatement items. According to
> https://docs.python.org/2/library/gc.html#gc.garbage :
...
> Please note also that the memory foodprint of the
> fdb.fbcore.PreparedStatement items in question is minimal because all
> containing data in fdb.fbcore.PreparedStatement is freed. Due to this
> this issue is not problematic in "normal" environments, but might
> become critical in an environment that runs for a long time under
> heavy load.

Well spotted. I missed a small crack in FDB machinery.

PreparedStatements are tricky beasts.

1. Firebird statements (presented as handles) could be closed and then
used for another execution (releases server resources bound to
particular execution) or dropped (permanently). PreparedStatement is
designed to be reused, so PS.close() only closes the underlying handle,
and permanently drops it in destructor __del__.

2. PreparedStatements are bound to Cursor, because they work in
connection and transaction contexts and need access to them (for
Firebird API calls). However, PS could be instantiated internally by
Cursor class, or externally by application developer through
Cursor.prep, in both cases they're bound together. Circular reference is
inevitable. Internal PS lifetime is managed by Cursor, while external
are managed by application (i.e. cursor lifetime is managed by PS held
by application). Internal PS use weakref to Cursor, so there shouldn't
be a problem with circular reference. On the other hand when PS is
created externally with hard ref to Cursor and then executed, Cursor
keeps the reference to it in self._ps, so hard circular reference is
created and it's broken only when another statement (internal or
external) is executed, or Cursor.close() is called. Obvious fix is to
use weakref.proxy to explicit PS in Cursor.execute.

best regards
Pavel Cisar
IBPhoenix