-
Notifications
You must be signed in to change notification settings - Fork 28
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
Proposal: add the response details to the offline request queue #393
Comments
Brick intentionally doesn't support the serialization of the server response because of the extremely varied case in associating a request to a response. For example, say you're upserting 5 However, even if the implementation is aware of the domain, Brick needs to assume it could receives responses out of order from when the request was made (in case the requests are transmitted The last option you could use is making the queue somewhat more stateful and storing the response immediately to a separate table using the local table's request id as a foreign key. However, in this solution, do you store the response for every request? Just the latest request? How much information would the end user need to determine if the request should be voided? And if you store these raw responses, do you need to worry about any data sanitization since the queue isn't encrypted by default (the model logic may transform strip/encrypt sensitive information)? Will disk space size become a factor? Will performance of the queue's primary function be affected? So, overall, it's doable, but I would strongly consider the end user's interface (how they access this in their own app code) first - what's needed and how can it be accessed efficiently - and then work back to the solution. I agree that the |
Re this concern: in the Request 1 Request 1 succeeds |
Thanks for all this input @tshedor! The way you describe the stateful queue (storing the response immediately in a separate table) is what I had in mind. I would store every response which has an HTTP Status Code >= 400, or every response which status code is in the |
Regarding the serial processing: I am aware of the flag but the requests in my app, or to be more precise, some requests have to be processed in serial. This is due to the associations. Imagine a customers and a projects table. Every customer is associated with one or more projects. In this case, a request which creates a new customer has to be sent before a request which creates a new project. On the other hand, for two requests updating different projects, the order is not relevant. So I could not opt out of serial processing completely. |
I finally had some time to revisit this topic and came up with a potential solution. Quick Recap: Problem: There’s no straightforward way in Brick to detect if a request sent by the Context: In my app, upsert requests can be rejected by the database when a newer version of the dataset has been saved to the remote database in the meantime. This can occur when one user goes offline and edits data while another user modifies the same data. When the first user comes back online, the offline request queue becomes blocked as Brick keeps retrying the request indefinitely which always gets rejected. Previously, I thought it would be necessary to make somewhat larger changes/adjustments to brick, such as storing responses in a separate local table or making the request queue more stateful. However, I now realize these changes might be unnecessary. My new idea is to introduce an optional callback in the void Function(http.Request, http.StreamedResponse)? onRequestFailed; This would allow me, within my application code, to check the currently attempted response HTTP code indicates a rejection (e.g., HTTP 409 Conflict). With that information, I could notify the user that the request was rejected and provide options on how to handle it (e.g., giving the user the chance to export the data and discard the request to unblock the queue). (Additionally, we could extend this idea further by allowing the callback to return a This is still a rough idea and not fully thought out, but @tshedor, what are your thoughts on this? I think this approach would give specific applications (like mine) the flexibility to handle such cases without requiring major changes to Brick, making it more suitable for the average user. |
@devj3ns I think this is actually a very good solution:
The The only problem I imagine happening is |
@tshedor, glad you like the idea!
This approach requires the To avoid this conflict, what do you think about introducing the method directly in
I've opened a PR with my proposed implementation. I'd love to hear your thoughts and am happy to explore alternative solutions if needed! |
Context
I am currently adding a conflict detection system via triggers to my Postgres database, which rejects an update operation when a client who was offline before tries to sync its changes using the offline request queue, but the object was already changed meanwhile. This prevents the loss of data when synchronizing. In the above case, I would like the user to give the opportunity to decide whether to keep the local or remote changes. (In my app, it is not possible to automatically discard the local change in the case it is rejected by the remote database because this would lead to data loss).
Current situation
In cases where a request inside the offline queue is rejected by the remote provider, the offline queue gets blocked until the request is removed.
I already created a page in my app which displays all requests which are inside the offline queue so that the user can see the sync status. Now I want to give the user the option to delete requests that got rejected by the remote database because of a conflict. This would unblock the request queue and other requests could be sent to the remote provider.
Proposal
What is missing from brick to do this is the ability to see the response details. Currently, brick only increments the “attempts” number inside the offline queue when a request fails. Therefore, I would like to propose a change that the HTTP-Status-Code and body of the latest attempt is stored inside the offline queue database table as well. This way, the app could identify which request got rejected and give the user the ability to remove the request, which frees up the queue.
I am willing to create a Pull Request which extends brick to support this but wanted to get some feedback on this idea first. Especially @tshedor, what do you think of this?
The text was updated successfully, but these errors were encountered: