Ich habe die ganze Zeit über einen Gevent Powered Crawler Download -Seiten. Das Crawler übernimmt das Produzenten-Verbraucher-Muster, das ich die Warteschlange mit solchen Daten {Methode: get, url: xxxx, other_info: yjyy} füttere.
Jetzt möchte ich einige Antwort in Dateien zusammenstellen. Das Problem ist, dass ich nicht einfach öffnen und schreiben kann, wenn jede Anfrage endet, dass IO kostspielig und die Daten nicht in korrekter Reihenfolge sind.
Ich gehe davon aus, dass ich alle Anfragen nummerieren sollte, um eine Cache -Antwort in der Reihenfolge zu eröffnen, ein Greenlet zum Loop- und Zusammenbau von Dateien zu öffnen. Pseudocode kann wie folgt sein:
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
Gibt es eine bessere Lösung? Es gibt Tausende gleichzeitige Anfragen, und ich bezweifle, dass der Speichergebrauch zu schnell oder zu viele Schleifen gleichzeitig oder etwas unerwartet wachsen kann.
Aktualisieren:
Die obigen Codes zeigen nur, wie das Abschnitt und das Schreiben von Dateidateien das Schreiben von Dateien. In der praktischen Situation gibt es vielleicht 1hundert Schleife, um das Warten zu warten, um das Cacheeinzum fertigzustellen und in verschiedene Dateien zu schreiben.
Update2
@It ninja empfehlen, das Warteschlangensystem zu verwenden, daher schreibe ich eine Alternative mit 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()
Sieht ein bisschen besser aus, aber ich bezweifle, dass es eine gute Idee ist, große Daten in Redis zu speichern, hoffe auf weitere Vorschläge!