0

Pourriez-vous s'il vous plaît conseiller sur la façon de périodiquement exécuter une tâche qui prend plus de temps à exécuter que l'intervalle périodique?python: comment-faire une recherche périodique non-bloquante

Par exemple:

def lookup(): 
    # do some lookups, retrieve info, let's assume it takes 60sec to complete 
    msg = {'abc':123} 
    time.sleep(60) 
    return msg 

class Publisher(object): 
    def __init__(self): 
     self._TIMEIT = 0 
     self._INTERVAL = 5 
     self._counter = 0 

    def xxx(): 
     t_start = time.time() 
     msg = lookup() 
     # do something with the value returned 
     save_msg_to_db(msg) 
     self._counter += 1 
     t_end = time.time() 
     self._TIMEIT = int(math.ceil(t_end - t_start)) 

    def run(): 
     while True: 
      # let's do the lookup every 5sec, but remember that lookup takes 60sec to complete 
      time.sleep(self._INTERVAL) 
      # the call to xxx() should be non-blocking 
      xxx() 

Mais la méthode run est responsable de la planification de la tâche périodique, et comme il itère ne doit pas bloquer lors de l'appel de la fonction xxx.

Je pense à créer une boucle d'événement sur chaque appel à xxx fonction, comme décrit dans A Bad Coroutine Example mais comment faire l'appel à xxx non-bloquant?

PS. J'utilise Python3.4 new asyncio (utilisait gevent dans le passé), pas sûr si je demande sth stupide ici.

Donc, lookup va créer une boucle asynchrone qui prendra 60 secondes à compléter. Mais, dans la méthode run il ya une boucle sans fin en cours d'exécution que je voudrais faire la recherche tous les 5sec, en d'autres termes je voudrais (1) combien de fois j'appelle la fonction de recherche, indépendante de (2) comment le temps qu'il faut recherche pour compléter

+0

est-ce votre 'recherche() 'fonction CPU-intensive ou il prend juste beaucoup de temps à terminer en raison des opérations d'E/S? – zwer

+0

: "il faut juste beaucoup de temps pour terminer à cause des opérations d'E/S" – iamsterdam

+0

Et que se passe-t-il pendant que le 'lookup()' est en cours d'exécution? Si vous voulez l'exécuter en arrière-plan (non-bloquant) et que cela prend 60 secondes pour terminer et que vous l'appelez toutes les 5 secondes, vous en aurez bientôt des milliers. Donc, quelque chose doit donner - soit votre intervalle de vérification (extension) ou les appels à la fonction 'lookup()' (ne faites pas un autre appel si le précédent ne s'est pas terminé). – zwer

Répondre

0

Depuis votre lookup() est principalement E/S intensive, vous pouvez exécuter votre méthode xxx() comme un fil et parfaitement bien (code raccourci par souci de concision):

import threading 
import time 

class Publisher(object): 

    def __init__(self): 
     self._INTERVAL = 5 
     self._counter = 0 
     self._mutex = threading.Lock() 

    def xxx(self): 
     msg = lookup() 
     save_msg_to_db(msg) 
     with self._mutex: # make sure only one thread is modifying counter at a given time 
      self._counter += 1 

    def run(self): 
     while True: 
      time.sleep(self._INTERVAL) 
      t = threading.Thread(target=self.xxx) 
      t.setDaemon(True) # so we don't need to track/join threads 
      t.start() # start the thread, this is non-blocking 
+0

merci @zwer laissez-moi l'évaluer, et je reviendrai à vous – iamsterdam