2011-03-09 9 views
9

Sto utilizzando la cloudfile module per caricare i file in file Rackspace cloud, utilizzando qualcosa di simile pseudocodice:Come faccio a caricare molti file al momento per creare file cloud con Python?

import cloudfiles 

username = '---' 
api_key = '---' 

conn = cloudfiles.get_connection(username, api_key) 
testcontainer = conn.create_container('test') 

for f in get_filenames(): 
    obj = testcontainer.create_object(f) 
    obj.load_from_filename(f) 

Il mio problema è che ho un sacco di piccoli file da caricare, e ci vuole troppo tempo in questo modo .

Sepolto nella documentazione, vedo che esiste una classe ConnectionPool, che presumibilmente può essere utilizzata per caricare file in parallelo.

Qualcuno potrebbe mostrare come posso caricare questo pezzo di codice più di un file alla volta?

risposta

7

La classe ConnectionPool è pensata per un'applicazione multithreading che occasionalmente deve inviare qualcosa al rackspace.

In questo modo è possibile riutilizzare la connessione ma non è necessario mantenere aperte 100 connessioni se si dispone di 100 thread.

Stai semplicemente cercando un uploader multithreading/multiprocessing. Ecco un esempio utilizzando la libreria multiprocessing:

import cloudfiles 
import multiprocessing 

USERNAME = '---' 
API_KEY = '---' 


def get_container(): 
    conn = cloudfiles.get_connection(USERNAME, API_KEY) 
    testcontainer = conn.create_container('test') 
    return testcontainer 

def uploader(filenames): 
    '''Worker process to upload the given files''' 
    container = get_container() 

    # Keep going till you reach STOP 
    for filename in iter(filenames.get, 'STOP'): 
     # Create the object and upload 
     obj = container.create_object(filename) 
     obj.load_from_filename(filename) 

def main(): 
    NUMBER_OF_PROCESSES = 16 

    # Add your filenames to this queue 
    filenames = multiprocessing.Queue() 

    # Start worker processes 
    for i in range(NUMBER_OF_PROCESSES): 
     multiprocessing.Process(target=uploader, args=(filenames,)).start() 

    # You can keep adding tasks until you add STOP 
    filenames.put('some filename') 

    # Stop all child processes 
    for i in range(NUMBER_OF_PROCESSES): 
     filenames.put('STOP') 

if __name__ == '__main__': 
    multiprocessing.freeze_support() 
    main() 
+0

Non è necessario 'multiprocessing' per le attività legate IO se' API cloudfiles' è thread-safe. 'pool = multiprocessing.Pool(); pool.map (upload_file, get_filenames()) 'sembra un'alternativa più semplice se si decide di usare' multiprocessing'. – jfs

+0

@WoLpH: Grazie mille per la risposta! Quando provo il tuo codice mi imbatto in un oggetto TypeError: l'oggetto 'Queue' non è iterable ', è un errore che ho fatto? – Hobhouse

+0

@ J.F. Sebastian: A quanto ho capito, la classe ConnectionPool dovrebbe essere thread-safe. Non riesco a spiegarmi come incorporare i suggerimenti del codice nel codice. – Hobhouse

Problemi correlati