Esta es una excepción común que recibo diariamente en el registro de mi aplicación, generalmente 5/6 veces al día con un tráfico de 1K visitas/día :Tiempo de espera de Google App Engine: se agotó el tiempo de espera de la operación del almacén de datos o los datos no estaban disponibles temporalmente
db error trying to store stats
Traceback (most recent call last):
File "/base/data/home/apps/stackprinter/1b.347728306076327132/app/utility/worker.py", line 36, in deferred_store_print_statistics
dbcounter.increment()
File "/base/data/home/apps/stackprinter/1b.347728306076327132/app/db/counter.py", line 28, in increment
db.run_in_transaction(txn)
File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 1981, in RunInTransaction
DEFAULT_TRANSACTION_RETRIES, function, *args, **kwargs)
File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 2067, in RunInTransactionCustomRetries
ok, result = _DoOneTry(new_connection, function, args, kwargs)
File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 2105, in _DoOneTry
if new_connection.commit():
File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_rpc.py", line 1585, in commit
return rpc.get_result()
File "/base/python_runtime/python_lib/versions/1/google/appengine/api/apiproxy_stub_map.py", line 530, in get_result
return self.__get_result_hook(self)
File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_rpc.py", line 1613, in __commit_hook
raise _ToDatastoreError(err)
Timeout: The datastore operation timed out, or the data was temporarily unavailable.
la función que está levantando la excepción anterior es la siguiente:
def store_printed_question(question_id, service, title):
def _store_TX():
entity = Question.get_by_key_name(key_names = '%s_%s' % \
(question_id, service))
if entity:
entity.counter = entity.counter + 1
entity.put()
else:
Question(key_name = '%s_%s' % (question_id, service),\
question_id ,\
service,\
title,\
counter = 1).put()
db.run_in_transaction(_store_TX)
Básicamente, el cheque store_printed_question
función de si una cuestión ha sido impreso previamente, incrementando en ese caso el contador relacionado en una sola transacción.
Esta función se agrega por un WebHandler
a un trabajador deferred predefinido utilizando la cola de default que, como ustedes sabrán, tiene una tasa de rendimiento de cinco invocaciones de tareas por segundo.
En una entidad con seis atributos (dos índices) pensé que usar transactions regulado por un límite de tasa de tarea diferida me permitiría evitar los tiempos de espera del almacén de datos pero, mirando el registro, este error aún se muestra diariamente.
Este contador que estoy almacenando no es tan importante, así que no estoy preocupado por obtener estos tiempos de espera; de todos modos, tengo curiosidad por saber por qué Google App Engine no puede manejar esta tarea correctamente, incluso a una tasa baja, como 5 tareas por segundo, y si bajar la tasa podría ser una posible solución.
Un sharded counter en cada pregunta para evitar tiempos de espera sería una exageración para mí.
EDIT:
he puesto el límite de velocidad a 1 de tareas por segundo en la cola predeterminada; Todavía estoy recibiendo el mismo error.
Las tareas diferidas no son "más ligeras" que las tareas normales en cualquier sentido, excepto que son más fáciles de escribir. Debajo del capó, están implementados con controladores regulares. En cualquier caso, eso no tendría ningún impacto en la sobrecarga de la transacción en sí. –