Russ <russandheat...@gmail.com> wrote:

> I have a case where I 'm using threadlocal scoped_sessions and I'm storing a 
> file during a transaction.  I want to delete the file if the transaction 
> rolls back for any reason.  To handle this I use the event system, something 
> like so:
> 
>     def write_data(file_path, data):
>         with open(file_path, "w") as fp:
>             fp.write(data)
>     
>         #set up a rollback handler...
>         def delete_file(session, previous_transaction):
>             os.remove(file_path)    # <--- BREAKPOINT HERE
>     
>         ormSess = globalenv.LocalThreadData.OrmSess
>         sa.event.listen(orm_session, "after_soft_rollback",
>                     delete_file, once=True)

do you mean to say event.listen(ormSess) here ?   

> 
> What I'm currently finding is that the delete_file handler is firing off long 
> after the session it was hooked to is gone.  I'm definitely calling .remove() 
> on the scoped_session.
> 
> When I put a breakpoint inside the handler, you can see that there are two 
> entirely different sessions.
> 
> The rollback is being called (code not shown) on an object at 0x7f18f8154910:
> 
> >>> orm_session.rollback
> <bound method scoped_session.do of <sqlalchemy.orm.scoping.scoped_session 
> object at 0x7f18f8154910>>
> 
> This fires off the handler for dead-and-gone (or so I thought) session.  Down 
> the stack and inside the handler you can see that the session passed in does 
> not match:
> 
> >>> session   # the listener arg 
> <sqlalchemy.orm.session.Session object at 0x5462b90>
> 
> Again, these are within the same call stack.
> 
> Why would the handler on an old session be getting called?  Am I 
> misunderstanding something here?  Is there a proper way to get rid of all 
> event handlers on a session?  I know that listeners can be removed 
> individually, but I thought scoped_session.remove() would make this 
> unnecessary.

if you have set an event listener on a single session that is definitely the
actual Session object and not the thread local or the scoped_session or
anything, and that Session is hit by .remove(), it will be garbage
collected, and the events associated with it will also go. The event is
associated with the Session within a system that does involve using the
Session itself as a hash key and also uses some weak references with
callbacks for cleanup. It’s not too far fetched that there might be some
issue here, but this would need to be demonstrated. Is this issue only under
high concurrency, is it relatively infrequent otherwise, and what happens if
you actually remove() the event ahead of time?

> Thanks,
> Russ
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to sqlalchemy+unsubscr...@googlegroups.com.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> Visit this group at http://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to