Tengo páginas de descarga de Crawler de Gevent Powered todo el tiempo. El patrón de productores de Crawler adopta, que alimento la cola con datos como este {método: get, url: xxxx, other_info: aaa yyyy}.
Ahora quiero reunir alguna respuesta en los archivos. El problema es que no puedo abrir y escribir cuándo termina cada solicitud, que IO es costosa y los datos no están en orden correcto.
Supongo que puede ser que numere todas las solicitudes, la respuesta de caché en orden, abra un Greenlet para enrollar y ensamblar archivos, el código de pseudo puede ser así:
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
¿Hay mejor solución? Hay miles de solicitudes concurrentes, y dudo que el uso de la memoria sea creciente demasiado rápido, o demasiados bucles al mismo tiempo, o algo inesperadamente.
Actualizar:
Los códigos anteriores solo demuestran cómo lo hace el almacenamiento en caché de datos y la redacción de archivos. En una situación práctica, tal vez se ejecutaran los 1 cien bucles para esperar en caché y escribir en diferentes archivos.
Actualización2
@IT Ninja sugiere usar el sistema de cola, por lo que escribo una 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()
Se ve un poco mejor, pero dudo que si guardar datos grandes en Redis es una buena idea, ¡espero más sugerencias!