2011-04-05 11 views
5

Tengo un trabajo de cron todos los días para hacer una llamada a una API y buscar algunos datos. Para cada fila de datos, inicio una cola de tareas para procesar los datos (lo que implica buscar datos a través de más API). Una vez que todo esto haya terminado, mis datos no cambian durante las próximas 24 horas, así que lo Memcaché.Ejecutar la función cuando la cola de tareas está vacía en appengine

¿Hay alguna manera de saber cuándo terminaron todas las tareas que hice para que pueda almacenar en caché los datos?

Actualmente lo hago de una manera muy sucia con sólo dos programación de trabajos de cron como esto:

class fetchdata(webapp.RequestHandler): 
def get(self): 
    todaykey = str(date.today()) 
    memcache.delete(todaykey) 
    topsyurl = 'http://otter.topsy.com/search.json?q=site:open.spotify.com/album&window=d&perpage=20' 
    f = urllib.urlopen(topsyurl) 
    response = f.read() 
    f.close() 

    d = simplejson.loads(response) 
    albums = d['response']['list'] 
    for album in albums: 
     taskqueue.add(url='/spotifyapi/', params={'url':album['url'], 'score':album['score']}) 

class flushcache(webapp.RequestHandler): 
    def get(self): 
     todaykey = str(date.today()) 
     memcache.delete(todaykey) 

Entonces mi cron.yaml se parece a esto:

- description: gettopsy 
    url: /fetchdata/ 
    schedule: every day 01:00 
    timezone: Europe/London 

- description: flushcache 
    url: /flushcache/ 
    schedule: every day 01:05 
    timezone: Europe/London 

Básicamente - Soy adivinando que todas mis tareas no tardarán más de 5 minutos en ejecutarse, así que simplemente descargué el caché 5 minutos más tarde y esto garantiza que, cuando los datos estén en caché, estén completos.

¿Hay una forma mejor de codificar esto? Se siente como mi solución no es la mejor ....

Gracias Tom

Respuesta

6

No hay actualmente ninguna manera de determinar cuando sus tareas se han terminado de ejecutarse. Su mejor opción sería insertar registros de marcador en el almacén de datos y hacer que cada tarea elimine su registro cuando esté listo. Cada tarea puede verificar si es la última tarea y realizar su limpieza/almacenamiento en caché si es así.

+0

gracias nick - es bueno saber que no me perdí de algo obvio. Probaré lo que sugieras – tomcritchlow

2

encontré esta pregunta al tratar con el mismo problema. se me ocurrió una solución diferente que estoy publicando aquí en caso de que sea útil para otros.

esto no es un reemplazo directo de lo que está preguntando, pero está relacionado: mi problema era que quería saber cuándo una cola estaba vacía porque eso significa que un proceso de fondo complejo había terminado de ejecutarse. por lo que podría reemplazar comprobar el tamaño de la cola con la comprobación de un "temporizador de hombre muerto"

un tiempo de hombre muerto es un temporizador que se restablece constantemente por algún proceso. cuando ese proceso finaliza, el temporizador no se reinicia y, finalmente, expira. así que hice que todas las tareas diferentes que formaban parte de mi complejo proceso de fondo reiniciaran el temporizador y, en lugar de verificar cuando la cola estaba vacía, tuve un trabajo cron que verificó cuando expiró el temporizador.

por supuesto, para que esto sea eficiente, el temporizador debe evitar escribir en el almacén de datos todo el tiempo. el código en http://acooke.org/cute/Deadmantim0.html lo evita relajando ligeramente el comportamiento y usando memcache para mantener una copia del objeto del temporizador y solo restablecerlo en la tienda después de que ha transcurrido una cantidad significativa de tiempo.

ps esto es más eficiente que lo que describes porque no necesita escribir con tanta frecuencia en la base de datos. también es más robusto porque no tiene que hacer un seguimiento exacto de lo que está sucediendo.

+0

Y también es menos robusto ya que el contador puede caducar debido a que todas las tareas en ejecución son demasiado lentas. En la práctica, esto puede ser lo suficientemente improbable, supongo. – maaartinus

Cuestiones relacionadas