#what does this error mean

30 messages · Page 1 of 1 (latest)

crude kite
#

my understanding is that mutations are transactions that also include built in conflict resolutions. I'm not sure what this means?

#

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?

hybrid locust
# crude kite my understanding is that mutations are transactions that also include built in c...

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.

crude kite
#

yeah I mean the mutation just does those 2 lines

#

fetches the plan

#

patches the plan.plan property

hybrid locust
#

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

crude kite
#

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

hybrid locust
crude kite
#

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']),
hybrid locust
#

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

crude kite
#

oh I forgot value

hybrid locust
#

cool yeah

crude kite
#

does the composite index make sense in this situtation do you think?

hybrid locust
#

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

crude kite
#

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?

floral anvil
#

Yep, you got it right!