Je lis beaucoup de données de ldap qui doivent être comparées aux enregistrements respectifs dans la base de données. Pour réduire le nombre de requêtes SQL, je veux traiter plusieurs enregistrements LDAP en une seule requête. Tout cela est assez simple: un thread pour produire des résultats ldap, et un thread pour consommer ces résultats et exécuter la requête SQL.Notifier le consommateur quand le producteur est fini
ldap_results = Queue.Queue(10) def producer(): for result in ldap_results(): ldap_results.put(result) def consumer(): buffer = [] buffer_size = 5 while True: record = ldap_results.get() buffer.append(record) if len(buffer) >= buffer_size: do_sql(buffer) buffer = []
Le problème est le suivant: Si ldap ne retourne que, disons, 3 résultats et buffer_size
est 5, il va finir par bloquer pour toujours. Je me rends compte que je pourrais mettre un jeton spécial dans le buffer, comme None
, ou "EOF"
, mais ça a l'air d'un mauvais design: "itérer jusqu'à ce que tu aies fini, oh, à moins que tu vois cette valeur spéciale, ça veut dire que tu as fini ".
Je suis venu avec deux idées alternatives. La première est d'avoir une variable eof
partagée, mais je ne sais pas comment la synchroniser correctement.
def producer(): while data: buffer.put() eof = True def consumer(): while not eof: buffer.get()
La seconde est d'avoir une méthode ProduceChunks(chunk_size)
pour le producteur, et il va gérer la mise en batching des résultats, mais je ne aime pas ça parce qu'il suppose que le producteur saura mieux pour un buffer résultats , quand, vraiment, je pense que c'est la responsabilité du consommateur.
Est-ce que quelqu'un a des conseils?