Best practice for large, multi-mutation sequence with convex
I'm trying to create a series of mutation calls to handle the event where the user deletes their account.
When a user deletes their account, I need to:
- update every thread the user created (recursive scheduled tasks)
- update every comment the user created (recursive scheduled tasks)
- update user details
- update or delete every message the user created (recursive scheduled tasks)
Given resource limits for each mutation, i'm guessing invoking 4 separate mutations from the client (rather than inside a single parent mutation) is the way to go here...maybe not..
Should one of these mutations fail, I'll either need to rollback the updates and throw an error or ... I need to think of a better way to handle this altogether. I could also be going about this rather inefficiently...hence me bringing this up here, in case im making an incorect assumption about Convex.
4 Replies
I suppose i could add a db field to verify the current state of deletion..
The way I've handled this is through cascading deletes, and adding an
isDeleted
field to most of my tables. If you delete a high level item with lots of nested relations, you mark a "parent" deleted, but don't actually delete it until all children/relations are deleted. So in your case the last thing to actually be deleted would be the account itself.
Cascading deletes do take a bit of work to do correctly in Convex if you have a lot of relations. I haven't tried Ents, but it has support for cascading deletes and probably handles this problem as well.
I would also recommend making it a single call from the client and scheduling out whatever functions are necessary from the backend, just less points of failure that way.
One benefit of this approach is, by marking the thing you're deleting as deleted first, you can have your app react to that data regardless of the status or success of the actual operation. So if it fails somewhere, as long as that initial mutation successfully set the account to deleted, your app can treat it as deleted. You can have a cron job that cleans up failed deletes if that starts to become a problem.I'd start it as one mutation from the client that schedules out the other mutations to do cleanup
I agree with what erquhart says too
Hmm...the first part is a bit unclear to me but I completely agree with the rest, and i think i have what i need...great reminder about the nuances of how scheduling works
1. initiate single mutation call
2. delete first "part" of the user using a scheduled fn. Within that scheduled fn, invoke the second part.
3. update/delete (for me its updating rather than deleting) in the second part, recursively updating each batch until complete, to which then i invoke the third part, and so on...
@erquhart @ian Much thanks