Open itsramiel opened 1 year ago
Hi @itsramiel , this seems to be due to a race condition where the first save sends the mutation to update the record in the DB and when that succeeds the record version will have incremented. This happens before the rest of the requests are sent out, which means they are sent with a lower version than is now on the server, resulting in the updates being ignored. This can be confirmed by checking the network activity and the payloads sent to appsync for each mutation.
One workaround might be to add a short delay between the saves, or wait for the outboxMutationProcessed event before performing the next save.
Hey @chrisbonifacio Thank you for the reply. Yes I am aware of why it happens. Adding a short delay between saves could save it but it depends on the internet speed. Listening for the outboxMutationProcessed event would require to handle offline state.
Also it doesnt make sense for all amplify users to have their own workarounds. It is better if it was baked into it. Is this something the team is aware of and looking to fix?
Hi @itsramiel I've marked this as a feature request so we can look into a more holistic solution. Thank you 🙏
@chrisbonifacio
I've been digging deeper into this issue and read through some PRs such as this: https://github.com/aws-amplify/amplify-js/pull/7354
At a surface level this should be fixed by the PR mentioned above. But it still seems like the "race condition" explanation is still pretty rampant every time someone posts this issue.
My question is, where is the supposed race condition exactly? If it is the case of inflight requests wouldn't @iartemiev 's changes in that PR fix this? At what point does DataStore decide to merge models in the outbox? Why do we have to wait for outbox mutation to be processed before attempting to save (won't it queued in outbox and merged automatically when the response comes back)?
In our project we've created a shim on top of DataStore save to be aware of outbox mutations based on model id, such that saves are enqueued and merged if there is an outbox mutation in process. But this begs the question, what's the point of the outbox merger if that's what I have to do?
Before opening, please confirm:
JavaScript Framework
React Native
Amplify APIs
DataStore
Amplify Categories
api
Environment information
Describe the bug
I have a model that I update by querying, copying and then saving it:
When I try to update the model multiple times sequentially like this:
Observing the model and logging the name shows:
The updates after the first one are discarded.
Expected behavior
I should not lose update to a model, and the latest update should be reflected
Reproduction steps
import { Amplify, DataStore } from "aws-amplify"; import awsExports from "./src/aws-exports"; import { Todo } from "./src/models"; import { useEffect } from "react"; import { Button, View } from "react-native"; Amplify.configure(awsExports);
const App = () => { useEffect(() => { const subscription = DataStore.observeQuery(Todo).subscribe( ({ items, isSynced }) => { console.log(items[0]?.name); } );
}, []);
const updateTodo = async (name: string) => { const todo = (await DataStore.query(Todo))[0];
};
return ( <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}> <Button title="update" onPress={async () => { await updateTodo("1"); await updateTodo("2"); await updateTodo("3"); await updateTodo("4"); }} /> ); };
export default App;
Log output
aws-exports.js
No response
Manual configuration
No response
Additional configuration
No response
Mobile Device
No response
Mobile Operating System
No response
Mobile Browser
No response
Mobile Browser Version
No response
Additional information and screenshots
No response