Race condition: uploading without terasender (#208)
Race condition: uploading without terasender (#208)

This one is quite subtle. transfer.js/uploadChunk increments the
file_index if it was the last chunk and then goes on to call
putChunk() to actually send that last blob. Since there are no workers
it doesn't seem to make for a race. But there are timeout callbacks so
similar things can happen if you are not careful.

In the done callback passed to putChunk() the
transfer.reportComplete() is called which will complete the
transaction. Digging into transfer.reportComplete we see a guard for
status done which ensures it will only be able to fire once. Then
filesender.client.transferComplete is called after a 300ms delay.

To stimulate a race, add two files to the upload and make the last
file very small. This way in the call to 'done' for the first file,
lets call it firstfile, by the time the file_index test is performed
the file_index will have been updated by the start of the putChunk
call to upload the lastfile. I have verified this with ui.log()
messages at select locations. What is perhaps better to compare for
potential scheduling of transaction complete in the done callback is
if this *was* the last chunk of the last file before we started
uploading the chunk. That we were uploading the second last file will
not change no matter if the last file is 20 bytes or is 20gb in size.

I have only seen this as being a race locally. I didn't invest the
time to work out the exact delays to introduce that might be needed so
that the second putChunk() is called after file_index is incremented
and the transaction is closed before the filesender.clinet.call() ajax
call that is under transaction.putchunk() gets a chance to complete.
filesender/filesender,filesender/filesender,Veredior/filesender,filesender/filesender,filesender/filesender,Veredior/filesender,Veredior/filesender,Veredior/filesender,filesender/filesender,Veredior/filesender