Closed LegacydbAdmin closed 4 years ago
This is right up my alley — I often use flow.js and Flask together.
The 500 is a response code from the Flask backend, so this is very likely to be a server-side issue, not an issue with flow.js. Could you post the example code, along with a minimal version of templates/upload/upload.html
to a GitHub repo that could be cloned and run to attempt to reproduce the error?
Thanks! I'll work on the minimal version, but I think you're right - it's failing in these two places:
os.unlink(stored_chunk_file_name)
with:
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process.
if upload_complete:
target_file_name = os.path.join(Config.DATA, resumableFilename)
with open(target_file_name, "ab") as target_file:
for p in chunk_paths:
stored_chunk_file_name = p
stored_chunk_file = open(stored_chunk_file_name, 'rb')
target_file.write(stored_chunk_file.read())
stored_chunk_file.close()
os.unlink(stored_chunk_file_name)
and then sometimes:
if not os.path.isdir(temp_dir):
os.makedirs(temp_dir, 0o777)
with
FileExistsError: [WinError 183] Cannot create a file when that file already exists
Neither of these happened which resumabls.js, which is why I was leaning towards the issue being with flow, and because this code is basically the same as what I had with resumable.
I wonder if the issue has to do with the number of simultaneous chunks being uploaded? Since you're using "ab"
mode to append bytes, maybe a second, simultaneous chunk upload is also causing a file create or append to happen at the same time. Does it work more reliably if set the flow.js simultaneousUploads
option to 1 instead of the default 3?
Oh, hmm, that might only adjust the number of simultaneous file uploads, not simultaneous chunk uploads. I suppose chunk uploads happen sequentially — I don't see anything about that in the docs. If there's any overlap, you'll get those file open and file write OS errors. I'm curious if you write the chunks to separate files, just as a test, if you encounter the same issue.
I think simultaneousUploads
is the issue! Changed to 1, ran a few dozen files no problem - change to 3, first file freezes.
Hate to ask, but would you have any recommendations on my flask end to help with this? I'd really like for that function to work, if possible.
Thanks again for all the help!
In the past, I've uploaded each chunk to separate files. When the last chunk arrives, I merged them together with something like:
import shutil
destination = open(path, 'wb')
for chunk in chunks:
shutil.copyfileobj(open(chunk.path, 'rb'), destination)
destination.close()
Depending on the total file size, though, combining the chunks can be time consuming. In that case, processing uploaded files might be best handed off to something that can process them separately (like a Dramatiq task queue) so your final chunk HTTP request doesn't take too long and keep the user waiting.
Some block storage APIs like SwiftStack can accept chunks of files (even directly from flow.js!) and present them as a single, unified file without the time overhead of actually merging the chunks: https://docs.openstack.org/swift/latest/overview_large_objects.html
Alternatively, if using 1 simultaneousUploads
doesn't impact performance much, leave it at that.
Awesome, the SwiftStack looks interesting. Thanks so much for all the help!
For reference (about Swift + flow.js):
Hello! Recently switched to flow from resumable.js, from what I can tell I've made the necessary adjustments to my code. However, sometimes the files upload perfectly, then other times flow.js is posting a 500 error and the upload quits. I'm having trouble figuring out the pattern/reason it sometimes doesn't work... any help would be great!
My backend is flask.