Re: How cache invalidations work (and hack to listen in) (was Re: Applause for ZODB! And a question: How do you get pending change info from a transaction object?)

Jim Fulton <[email protected]> Sat, 5 May 2018 07:11:28 -0600
Newsgroups gmane.comp.web.zope.zodb
Message-ID <CAPDm-FhHip=EaC2boidzJCtuCVXYE5wXy4=ChMkW5zZmcxnmrA@mail.gmail.com>
On Fri, May 4, 2018 at 11:52 AM, David Pesta <[email protected]> wrote:

> Your solution/hack is elegant. As I make progress toward implementing it
> (still getting the kinks out in my free time, but coming along), I had a
> couple questions.
>
> - In cases where I'm wanting a socket to keep track of a completely new
> object and establish that relationship before the transaction is committed,
>

This sounds fishy.  What's keeping you from committing a transaction?

More importantly, why would you want to notify clients about an objects
who's creation might be aborted?

...


- In my testing, I noticed that the connection cannot get details for an
> existing object using an oid until that object was at least accessed from
> some path using root first.
>

Nope...


> I'm guessing that the connection "get" with oid looks for it in the cache
> and does not go all the way to the database.
>

Nope. See:
https://github.com/zopefoundation/ZODB/blob/c75a197deebc3a65aa521bda11bdaa83dadd8b48/src/ZODB/interfaces.py#L139

The get method gets an object given its oid, regardless of whether it is
cached.  The object returned may be a ghost, meaning its state hasn't been
loaded, but the state will be loaded automatically when you access the
object's attributes. You shouldn't care in either case.


> A listening socket will only be given the oid when the object gets an
> update, but all of this is ok so far because a listening socket will have
> needed the actual object at some point in order to initiate the listening,
> thus the object will be in the cache and just the oid will work. Or will it?
>

Not necessarily.

First, your subscriber should be outside the context of a connection. If it
needs the object when it gets the invalidation, it should open a connection
to access it at which point the object will likely have been invalidated,
unless you happen to get the connection in which the object was modified. *None
of this actually matters*, because *the cache should be transparent to you*
.

def notified(oid):
      with mydb.transaction() as conn:
          ob = conn.get(oid)
          ... do whatever with ob


Doesn't cache invalidation mean the object (or its updated details) is no
> longer in the cache? Once that happens and the socket is informed with the
> oid, it no longer can use the oid to get the details? Or is that not the
> case?
>

You're overthinking this.  If you want object information, use get, in a
new transaction, to get the object and just use it. ZODB will take care of
cache management for you.



> Another idea for me that might work is if I store not just the oid but
> also a reference to the object.
>

*Never* keep references to objects outside the context of a
connection/transaction. (I probably need to add something to the
documentation about this.)

Jim

-- 
Jim Fulton
http://jimfulton.info

-- 
You received this message because you are subscribed to the Google Groups "zodb" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.