#what does this error mean
30 messages · Page 1 of 1 (latest)
this is what my mutation is doing
export const setPlanSectionStatus = internalMutation({
args: {
planId: v.id('plans'),
key: v.string(),
status: v.union(v.literal('generating'), v.literal('complete')),
},
handler: async (ctx, args) => {
const plan = await ctx.db.get(args.planId);
await ctx.db.patch(args.planId, {
plan: {
...plan?.plan,
[args.key]: {
...plan?.plan[args.key],
status: args.status,
},
},
});
},
});
I have maybe 10 other tasks that might run this same mutation at the same time
is this related to me having a .any() field where I store a giant json object?
I guess I can also ask about this one
convex ai helper says network glitches can cause this, but is this something rare?
my understanding is that mutations are transactions that also include built in conflict resolutions. I'm not sure what this means?
that's right, the built-in conflict resolution works by rolling back the effects of a mutation if it steps on another mutation's toes and carefully rerunning the mutation. There's a limit on retries though: if these keep failing the system returns a failure like this.
is this related to me having a .any() field where I store a giant json object?
That can increase the length of time the mutation takes and therefore that the transaction is open for so this could be related.
I have maybe 10 other tasks that might run this same mutation at the same time
Are these mutations reading and writing the same planId?
If not this is really unexpected.
yeah I mean the mutation just does those 2 lines
fetches the plan
patches the plan.plan property
One way to hve less contention would be to split out keys to be records in a different table so that modifying one key doesn't interfere with modifying another key
I have 1 action which uses the scheduler to run 11 actions, each of those actions runs a query to fetch the plan info, updates the plan to "generating" status, then it uses openai to generate some data, then it writes back to the plan the generated data
yeah I may look into doing that
roughly
defineTable("planKeys", {
planId: v.id('plan'),
key: v.string(),
value: v.any(),
});
was prototyping as well and i got htis
plans: defineTable({
userId: v.string(),
idea: v.string(),
targetUser: v.string(),
plan: v.any(),
version: v.number(),
}).index('by_userId', ['userId']),
section: defineTable({
userId: v.string(),
planId: v.string(),
type: v.union(v.literal('summary'), v.literal('icons')),
status: v.union(v.literal('generating'), v.literal('completed')),
}).index('by_planId_type', ['planId', 'type']),
We're thinking about how to help people debug these situations, this error message text changed fairly recently I think, trying to describe the read/write conflicts
oh I forgot value
cool yeah
does the composite index make sense in this situtation do you think?
yeah, it lets you get a specific type or all types for a planId
which is a common query since you need that to construct the plan
how do I re-use the same v.union I defined in the schema?
like can I just define like this at the top of the schema, then import in my action for defining my args?
Yep, you got it right!