J'ai tout le temps une pages de téléchargement de robottes alimentées sur gevent. Le Crawler adopte le modèle producteur-consommateur, que je nourris la file d'attente avec des données comme celle-ci {méthode: get, url: xxxx, autre_info: yyyy}.
Maintenant, je veux assembler une réponse dans les fichiers. Le problème est que je ne peux pas simplement ouvrir et écrire lorsque chaque demande se termine, que IO coûte et que les données ne sont pas dans un ordre correct.
Je suppose que je dois numéroter toutes les demandes, la réponse au cache dans l'ordre, ouvrir un vert pour faire boucle et assembler des fichiers, le code pseudo peut être comme ceci:
max_chunk=1000
data=[]
def wait_and_assemble_file(): # a loop
while True:
if len(data)==28:
f= open('test.txt','a')
for d in data:
f.write(d)
f.close()
gevent.sleep(0)
def after_request(response, index): # Execute after every request ends
data[index]=response # every response is about 5-25k
Y a-t-il une meilleure solution? Il y a des milliers de demandes simultanées, et je doute que l'utilisation de la mémoire puisse se développer trop rapidement, ou trop de boucle en même temps, ou quelque chose de manière inattendue.
Mise à jour:
Les codes ci-dessus démontrent simplement comment la mise en cache des données et la rédaction de fichiers font. Dans une situation pratique, il y a peut-être 1 cents boucle pour attendre le cache complet et écrire dans différents fichiers.
Mise à jour2
@It ninja suggère d'utiliser le système de file d'attente, donc j'écris une alternative à l'aide de redis:
def after_request(response, session_id, total_block_count ,index): # Execute after every request ends
redis.lpush(session_id, msgpack.packb({'index':index, 'content':response})) # save data to redid
redis.incr(session_id+':count')
if redis.get(session_id+':count') == total_block_count: # which means all data blocks are prepared
save(session_name)
def save(session_name):
data_array=[]
texts = redis.lrange(session_name,0,-1)
redis.delete(session_name)
redis.delete(session_name+':count')
for t in texts:
_d = msgpack.unpackb(t)
index = _d['index']
content = _d['content']
data_array[index]=content
r= open(session_name+'.txt','w')
[r.write(i) for i in data_array]
r.close()
Ça a l'air un peu mieux, mais je doute que la sauvegarde de grandes données dans Redis soit une bonne idée, espérez plus de suggestions!