-
Notifications
You must be signed in to change notification settings - Fork 102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow a PATCH request to restart at an offset of 0 #82
Comments
Can you elaborate on why creating a new upload instance is not acceptable for you in this case?
Are you referring to an actual issue in TUSKit's implementation here or a more general problem? |
The way that TUSKit has background uploads implemented, they will not continue long after the app closes. The only way that you can continue background uploads if the app is closed for an extended period of time is to use the NSURLSession framework, which retries on wire failures. (See here.) Here is an example of the problem I am encountering implementing TUS on that framework:
The only way around this that I can see is to break up the file into chunks, which are either uploaded sequentially to a single resource (resetting the offset as appropriate) or to partial files that are reset to zero each time. Therefore, having a way to reset offsets would allow us to implement truly background uploads (e.g. your app is not running) on iOS, just like DropBox or other services do. You can see the effect I describe in my example by running the background example app in our fork (there are some bugs in the example, so you can only select one file to upload each time you run it). If you set up tusd to limit the read to 1,000,000 bytes, then the connection is dropped which should result in a second PATCH request. However, iOS never makes the callback to the application because from iOS's perspective, the request has not succeeded and wire failures are ignored. |
Thank you for this detailed description and I do understand your struggles but are there no alternatives to using |
The long-running tasks you've pointed to mostly just wake the application up when something has changed. You can't just run an arbitrary process in the background, sadly. You can request more time to complete an upload, but you can't expect it to be an extended period (this is what the latest TUSKit version does). |
Could alternative libraries, such as AFNetworking, help? For example, https://github.com/AFNetworking/AFNetworking#creating-an-upload-task |
@cjhenck @Acconut AFNetworkign would require a little bit of a rewrite, but is do-able if if this will solve the problem @cjhenck's having using their background upload functionality - but it might be the just give us the same problem. I'll have to do a little more digging on coming up with a perfect solution. The idea of a "locker" has been brewing up in my mind where the upload is cached with its progress if it loses connection and continues when connection is found again. @cjhenck how big are the files you are uploading? Generally - I'd like to create a scenario that is close to yours |
The files may be up to 70 or 80mb in size, but the problem is that we have a number of users in developing markets who may not have very good access to the internet, but I still want to support their uploads. E.g. I want them to be able to hit "upload" in the app when they have no internet, and to have that upload complete even if they go in and out of network connection. Because you cannot keep the app running indefinitely in the background, that means letting the OS (NSURLSessions) handle the uploads. AFNetworking will still rely on the NSURLSessions, so will still have the same problems (or not work at all if your app is closed, since it is set up to use callbacks). |
Thanks for pointing this out and making tus better @cjhenck! I think I understand what you're saying. I'm going to summarize in my own words so you can help spot mistakes in my version. So the workaround is to split the 70mb file up in say 10x 7mb chunks with tus, and then basically have iOS do 10 non-tus uploads (they may look like tus uploads, but they are not resumable, only retryable, and this, iOS will fiercely attempt). For this reason, with every retry, the server needs to allow going back in time, discarding what it had already received, alloing the client (iOS) to retry its 7mb chunk from the beginning. I wonder, since we're not doing actual tus uploads, if the protocol is the place to accomodate that. This may sound like I made a call in my mind already but I honestly wonder. I would be very happy to have background uploading on iOS feature-wise. The use case you describe seems like that covers a large portion of mobile upload behavior, and it addresses the main problem why tus was created. I could also see scenarios however where this could lead to confusion, bugs, corrupt files, and these uploads are not truly resumable. I guess I wanted to make super double extra sure there is no way to do actual resumable uploads in the background. For this to make it in the protocol, I personally feel it would be helpful if we could also think of other scenarios where a Reset would be useful. I could still be tipped both ways. What do you think @Acconut @bhstahl? |
I agree that we probably shouldn't modify the protocol just for one use case, but if we can think of other suitable worthwhile reasons, then I could be swayed. I guess the real question is, if the client has complete control, unlike NSURLSessions, are there cases for resetting an upload instead of creating a new one? |
@kvz your description is absolutely correct. At the moment I can't think of alternative uses, but I do have a revised "flow" for iOS that would make use of the full protocol while the app is running (though the code would be more complicated):
I agree with everyone that this is a bit of a hack, but I cannot think of any other way to support rapid background uploads in iOS, though there are workarounds for occasional uploading that I have added to the TUSKit issue and which may be sufficient for most use cases. |
I guess there may even be a better approach to solving @cjhenck issues on iOS. In the past some people suggested to allow sending the first chunk for the upload already in the initial POST request (when using the Creation extension), mainly for reducing the overhead of a second attempt but since then it hasn't made its way into the protocol specification. Anyway, the way this solution is meant to work is following:
What do you think? |
I think this is an excellent solution. It solves the exact same problem and is more generally useful. |
Love this solution @Acconut! ❤️ Should we explicitly update the protocol to accommodate this in a 1.1 version you think? |
@cjhenck @kvz @bhstahl @MMasterson I, finally (sorry), got the time to start adding this feature to the specification. I would be pleased to hear your feedback: #88 |
I also plan to add this to tusd as soon as possible. |
Closing this in favor of #88. |
It would be useful to allow a PATCH request to start at an offset of 0. In particular, iOS's upload mechanism for closed/background apps aggressively retries uploads and will not call your application if there is a wire error, so I would like to use the concatenation extension in order to pre-chunk the data and send it to the background uploader.
The text was updated successfully, but these errors were encountered: