acid icon indicating copy to clipboard operation
acid copied to clipboard

(even) better approach to request contexts

Open dw opened this issue 11 years ago • 2 comments

Currently a request context is simply an object that manages a reference to the active transaction for the duration of some conceptual "request". The default request context implementation uses TLS, so here "request" means "since the user invoked with Store.begin() and until that with statement terminates".

The reason contexts are modular at all is for non-hardware-threaded environments like Twisted, where twisted.python.context can be used instead. But more generally, neither the stack nor the hardware thread is a clean enough abstraction to prevent the library's reuse in more diverse, or more custom environments.

Transactions aren't the only potentially context-specific resource: with meta.py, it is possible that Store instances would also be usefully swapped on a per-request basis. Imagine:

site_store = store_broker.get(domain=wsgi_env['HTTP_HOST'])
if not site_store:
    raise http 404

with acid.store_context(site_store):
    user = models.Pages.get(wsgi_env['PATH_INFO'])
    # ...

And for the duration of the request, all the models module's subclasses magically became associated with a site-specific store.

In order for this to work, it seems the 'request context object' needs to become process-global instead of Store-global, and needs to encompass not only the active transaction, but possibly also the active store.

Needs more thought

dw avatar Sep 09 '13 02:09 dw

Given environments like Twisted where there really is basically no global state automatically managed for you, another alternative comes to mind: Store becomes some kind of descriptor object, inert and incapable of anything by itself, instead only exporting begin(), which would yield a complete Store-within-that-transaction object. Any object returned by the store would be similarly bound.

This would mean many, many more temporary objects being constructed (potentially), but it would avoid the nasty requirement to pass explicit txn= everywhere, as things used to work.

This approach would work well on Twisted, Gevent, and regular Python

dw avatar Oct 11 '13 22:10 dw

That approach would have a nice side-effect: currently there is an ambiguity about which metadata lives outside a transaction, and which lives inside it. E.g. Collection objects are cached outside the transaction. If we simply made metadata reads exceedingly fast, then potentially we could reconstruct all store/encoder/counter/collection state exactly as it was during that transaction.

This would make migrations way more principled

dw avatar Oct 11 '13 22:10 dw