Web Dev Cody
Web Dev Cody14mo ago

what does this error mean

my understanding is that mutations are transactions that also include built in conflict resolutions. I'm not sure what this means?
No description
22 Replies
Web Dev Cody
Web Dev CodyOP14mo ago
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,
},
},
});
},
});
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
Web Dev Cody
Web Dev CodyOP14mo ago
No description
Web Dev Cody
Web Dev CodyOP14mo ago
is this related to me having a .any() field where I store a giant json object?
Web Dev Cody
Web Dev CodyOP14mo ago
I guess I can also ask about this one
No description
Web Dev Cody
Web Dev CodyOP14mo ago
convex ai helper says network glitches can cause this, but is this something rare?
ballingt
ballingt14mo ago
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.
Web Dev Cody
Web Dev CodyOP14mo ago
yeah I mean the mutation just does those 2 lines fetches the plan patches the plan.plan property
ballingt
ballingt14mo ago
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
Web Dev Cody
Web Dev CodyOP14mo ago
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
ballingt
ballingt14mo ago
roughly
defineTable("planKeys", {
planId: v.id('plan'),
key: v.string(),
value: v.any(),
});
defineTable("planKeys", {
planId: v.id('plan'),
key: v.string(),
value: v.any(),
});
Web Dev Cody
Web Dev CodyOP14mo ago
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']),
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']),
ballingt
ballingt14mo ago
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
Web Dev Cody
Web Dev CodyOP14mo ago
oh I forgot value
ballingt
ballingt14mo ago
cool yeah
Web Dev Cody
Web Dev CodyOP14mo ago
does the composite index make sense in this situtation do you think?
ballingt
ballingt14mo ago
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
Web Dev Cody
Web Dev CodyOP14mo ago
No description
Web Dev Cody
Web Dev CodyOP14mo ago
how do I re-use the same v.union I defined in the schema?
Web Dev Cody
Web Dev CodyOP14mo ago
No description
Web Dev Cody
Web Dev CodyOP14mo ago
like can I just define like this at the top of the schema, then import in my action for defining my args?
Michal Srb
Michal Srb14mo ago
Yep, you got it right!
ian
ian14mo ago
Argument Validation without Repetition
In the first post in this series, the Types and Validators cookbook, we shared several basic patterns & bes...
Types and Validators in TypeScript: A Convex Cookbook
It can be tough to wrangle types to behave how you want them to. Thankfully, Convex was designed to make the experience with types perfect. Learn why ...

Did you find this page helpful?