Ho sempre un download di crawler alimentato a gevent. Il crawler adotta il modello di consumatore del produttore, che alimenta la coda con dati come questo {metodo: get, url: xxxx, altro_info: yyyy}.
Ora voglio assemblare un po 'di risposta in file. Il problema è che non posso semplicemente aprire e scrivere quando ogni richiesta finisce, che io costoso e i dati non sono in ordine corretto.
Suppongo che dovrei essere numerato tutte le richieste, la risposta della cache in ordine, aprire un greenlet per loop e assemblare i file, il codice pseudo potrebbe essere così:
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
C'è una soluzione migliore? Esistono migliaia di richieste simultanee e dubito che l'uso della memoria possa crescere troppo velocemente, o troppi loop contemporaneamente o qualcosa di inaspettatamente.
Aggiornare:
I codici sopra sono solo dimostrare come fanno la memorizzazione nella cache dei dati e la scrittura di file. Nella situazione pratica, ci sono forse 1cento cicli per aspettare la memorizzazione nella cache e scrivere su file diversi.
Aggiornamento2
@It ninja suggerisce di utilizzare il sistema coda, quindi scrivo un'alternativa usando 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()
Sembra un po 'meglio, ma dubito che salvare grandi dati in Redis è una buona idea, spero in un ulteriore suggerimento!