2014-09-01 3 views
5

Ich muss Datei als Argument an die Sellerie-Aufgabe übergeben, aber die übergebene Datei wurde irgendwie geschlossen. Es passiert nur, wenn ich die Aufgabe asynchron ausführe. Ist das ein erwartetes Verhalten?Dateiinstanz als Argument an die Sellerie-Aufgabe übergeben löst "ValueError: I/O-Vorgang bei geschlossener Datei"

Ansichten:

from engine.tasks import s3_upload_handler 
def myfunc(): 
    f = open('/app/uploads/pic.jpg', 'rb') 
    s3_file_handler.apply_async(kwargs={"uploaded_file" : f,"file_name" : "test.jpg"}) 

Aufgaben:

def s3_upload_handler(uploaded_file,file_name): 
    ... 
    #some code for uploading to s3 

Zurückverfolgungs:

Traceback (most recent call last): 
    File "/usr/local/lib/python2.7/dist-packages/celery/app/trace.py", line 240, in trace_task 
    R = retval = fun(*args, **kwargs) 
    File "/usr/local/lib/python2.7/dist-packages/celery/app/trace.py", line 437, in __protected_call__ 
    return self.run(*args, **kwargs) 
    File "/app/photohosting/engine/tasks.py", line 34, in s3_upload_handler 
    key.set_contents_from_file(uploaded_file) 
    File "/usr/local/lib/python2.7/dist-packages/boto/s3/key.py", line 1217, in set_contents_from_file 
    spos = fp.tell() 
ValueError: I/O operation on closed file 

Blume Protokolle:

kwargs { 
     'file_name': 'test.jpg', 
     'uploaded_file': <closed file '<uninitialized file>', 
      mode '<uninitialized file>' at 0x7f6ab9e75e40> 
     } 

Antwort

5

Ja, natürlich würde die Datei dort geschlossen werden. Asynchrone Sellerie-Aufgaben laufen in einem völlig separaten Prozess (außerdem können sie sogar auf einer anderen Maschine laufen) und es gibt keine Möglichkeit, eine offene Datei an sie zu übergeben.

Sie sollten die Datei in dem Prozess, von dem aus Sie die Aufgabe aufrufen, schließen und dann ihren Namen und ggf. die Position in der Datei an die Aufgabe übergeben und dann in der Aufgabe erneut öffnen.

+1

das bedeutet, es gibt keine Möglichkeit, Speicher-Datei-Instanz an die asynchrone Aufgabe übergeben, und ich sollte es vorher speichern? –

+0

@ValentinKantor wenn mit "speichern" meinst du "schließen", dann ja, du musst die Datei-Instanz schließen –

0

Eine andere Möglichkeit wäre, die Datei zu öffnen und einen binären Blob zu erhalten, den Sie über die Leitung übertragen. Natürlich, wenn die Datei wirklich groß ist, dann ist das, was @Vasily sagt, besser, wird aber nicht funktionieren, wenn der Worker auf einem anderen Rechner läuft (es sei denn, Ihre Datei befindet sich in einem freigegebenen Speicher).

+0

Hallo, könntest du bitte erklären, wie man einen binären Blob aus der Datei bekommt? – kardaj

Verwandte Themen