2011-03-09 27 views
9

Używam cloudfile module przesyłanie plików do plików Rackspace chmurze, używając coś takiego Pseudokod:Jak przesłać wiele plików w tym samym czasie do plików w chmurze za pomocą Pythona?

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) 

Mój problem jest, że mam dużo małych plików do przesłania, a to trwa zbyt długo w ten sposób .

Pochowany w dokumentacji, widzę, że istnieje klasa ConnectionPool, która podobno może być używana do przesyłania plików w równych odstępach.

Czy ktoś mógłby pokazać, w jaki sposób mogę przesłać ten fragment kodu więcej niż jednego pliku naraz?

Odpowiedz

7

Klasa ConnectionPool jest przeznaczona do aplikacji wielowątkowej, która czasami musi wysłać coś do rackspace.

W ten sposób możesz ponownie wykorzystać połączenie, ale nie musisz utrzymywać 100 połączeń otwartych, jeśli masz 100 wątków.

Po prostu szukasz narzędzia do przesyłania wielowątkowego/wieloprocesowego. Oto przykład przy użyciu biblioteki 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

Nie musisz 'multiprocessing' dla zadań związanych IO jeśli' cloudfiles' API jest bezpieczny wątku. 'pool = multiprocessing.Pool(); pool.map (upload_file, get_filenames()) 'wydaje się być prostszą alternatywą, jeśli zdecydowałeś się użyć' multiprocessing'. – jfs

+0

@WoLpH: Dziękuję bardzo za odpowiedź! Kiedy próbuję twojego kodu, napotkam obiekt 'TypeError: 'Kolejka' nie jest iterowalna", czy to błąd, który popełniłem? – Hobhouse

+0

@ J.F. Sebastian: Jak rozumiem, klasa ConnectionPool ma być wątkowo bezpieczna. Po prostu nie mogę się skupić na tym, jak włączyć sugestie do kodu. – Hobhouse

Powiązane problemy