Google App Engine's ndb provides a _post_put_hook(self, future)
, documented as follows:
Hook that runs after put()
To understand this hook better, I am wondering when self
will differ from the result of the future
argument.
The Model Hooks documentation provides:
If you use post-hooks with asynchronous APIs, the hooks are triggered by calling check_result(), get_result() or yielding (inside a tasklet) an async method's future. Post hooks do not check whether the RPC was successful; the hook runs regardless of failure.
All post- hooks have a Future argument at the end of the call signature. This Future object holds the result of the action. You can call get_result() on this Future to retrieve the result; you can be sure that get_result() won't block, since the Future is complete by the time the hook is called.
However, when I call put
asynchronously like this:
from google.appengine.ext import ndb
class MyModel(ndb.Model):
xyz = ndb.StringProperty()
def _post_put_hook(self, future):
print "self.xyz: {}, future.xyz: {}".format(
self.xyz, future.get_result().get().xyz))
m = MyModel()
f = m.put_async()
f.wait()
m.xyz = 'abc'
f = m.put_async()
f.wait()
Outputs:
self.xyz: None, future.xyz: None
self.xyz: abc, future.xyz: abc
In the context of a 'put_async', I think one might reasonably expect the self
to be the model before modification, and the future
to be the model as now saved. Otherwise it is not clear what purpose future
would have in the put
context.
When would self
and future
be different in the context of a put
? What is the purpose of the future
here?
I believe the answer is in the description:
Post hooks do not check whether the RPC was successful; the hook runs regardless of failure.
The future can contain the reason for a failure when doing a put()
. You can use this knowledge to handle when a put fails by using a hook. For instance, if your _post_put_hook
was responsible for incrementing an associated SUM aggregation model based on properties of the model, it could first check to see if the put
succeeded before trying to increment the associated SUM aggregation model. I do not believe the value of self
and future.get_result().get()
will ever be different, as long as the RPC did not fail.
There is always the possibility that another request updated the model after this request's put
but before the _post_put_hook
was executed, in which future.get_result().get(use_cache=False)
may return a different value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With