Note that post hooks do not check whether the RPC was successful. The hook
runs regardless of failure that might have occurred due to issues, more
specifically the contention
<https://cloud.google.com/appengine/docs/standard/python/ndb/creating-entity-models>
which is when you attempt to write to a single entity group too quickly.
Also note that it is normal that a small number of datastore operations
will result in timeout in normal operation. Read more here
<https://cloud.google.com/appengine/articles/handling_datastore_errors>
about the most common datastore issues and here
<https://cloud.google.com/appengine/articles/scaling/contention> how to
avoid the contention.
In case you need any coding assistance, I suggest you post your inquiries
on Stack Overflow where the community of developers are better prepared to
assist you in that matter. Google Groups is oriented more towards general
opinions, trends, and issues of general nature regarding Google Cloud
Platform.
On Monday, September 2, 2019 at 11:17:01 AM UTC-4, Rob Curtis wrote:
>
> Hi,
>
> I have some code that queues up a task inside *_post_put_hook*.
> The task retrieves the key and fetches the entity. However sometimes the
> worker fails because the object for that key hasn't been created yet, but
> will succeed when it next runs.
> Note that we're retrieving the object by key, so I expect the data to be
> consistent.
>
> I want to understand WHY the object isn't available. I'm only calling the
> enqueue on commit, but it seems this isn't always working.
> Below is the example code which does the committing of the entity.
>
>
> @ndb.synctasklet
> def log_usage(self):
>
> @ndb.transactional_tasklet(xg=True)
>
> def _txn():
>
> # some other stuff happens here, but trying to make this example as
> simple as possible.
> yield Log.insert_document_log_async()
>
>
>
> yield _txn()
>
>
>
> class Log(ndb.Expando):
>
> @classmethod
>
> @ndb.tasklet
>
> def insert_document_log_async(cls):
>
> log = cls()
>
> logging.debug("insert document log in transaction:
> {}".format(ndb.in_transaction()))
>
> yield log.put_async()
>
>
>
> @ndb.synctasklet
>
> def _post_put_hook(self, future):
>
>
> @ndb.synctasklet
>
> def _callback_on_commit():
>
> key = future.get_result()
>
> yield SqlTaskHelper.enqueue_syncronise_sql_model_async(key)
>
>
> logging.debug("_post_put_hook In transaction:
> {}".format(ndb.in_transaction()))
>
> ndb.get_context().call_on_commit(lambda: _callback_on_commit())
>
>
>
>
>
> 1. *log_usage *is called.
> 2. When calling *insert_document_log_async* logging indicates that
> we're in a transaction (insert document log in transaction: *True*).
> 3. But the post put hook* _post_put_hook* In transaction: *False *(so
> call_on_commit is executed immediately). The task runs shortly after an
> occasional fails.
>
>
> Can someone please shed some light on where the problem is?
>
> Thanks
> Rob
>
--
You received this message because you are subscribed to the Google Groups
"Google App Engine" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/google-appengine/2a78bb0e-79a4-4e4e-97c4-1dd76a2fb6e3%40googlegroups.com.