MapleLeaf 🍁
MapleLeaf 🍁17mo ago

Collection size limit

I have a collection of items that'll get created frequently, and I don't need to store them forever, so I want to delete old entries to preserve space. My current strategy is to delete extra items once the collection size is over some arbitrary max. I'm not that worried about performance since the collection isn't that big, nor is the limit, but I still wonder if there's a more performant/idiomatic way to accomplish this. Here's my code:
const maxRolls = 250

export const roll = mutation({
args: {
type: v.optional(v.string()),
label: v.optional(v.string()),
characterId: v.optional(v.id("characters")),
dice: v.array(v.object({ sides: v.number(), count: v.number() })),
},
handler: async (ctx, { dice, ...data }) => {
const user = await requirePlayerUser(ctx)

// make dice rolls
const rolls = []
for (const dieItem of dice) {
for (let i = 0; i < dieItem.count; i++) {
rolls.push({
sides: dieItem.sides,
result: Math.floor(Math.random() * dieItem.sides) + 1,
})
}
}

// add new dice roll
await ctx.db.insert("diceRolls", {
...data,
discordUserId: user.discordUserId,
dice: rolls,
})

// remove old dice rolls if there are too many
const allRolls = await ctx.db.query("diceRolls").collect()
const excessRolls = allRolls.slice(0, -maxRolls)
await Promise.all(excessRolls.map((r) => ctx.db.delete(r._id)))
},
})
const maxRolls = 250

export const roll = mutation({
args: {
type: v.optional(v.string()),
label: v.optional(v.string()),
characterId: v.optional(v.id("characters")),
dice: v.array(v.object({ sides: v.number(), count: v.number() })),
},
handler: async (ctx, { dice, ...data }) => {
const user = await requirePlayerUser(ctx)

// make dice rolls
const rolls = []
for (const dieItem of dice) {
for (let i = 0; i < dieItem.count; i++) {
rolls.push({
sides: dieItem.sides,
result: Math.floor(Math.random() * dieItem.sides) + 1,
})
}
}

// add new dice roll
await ctx.db.insert("diceRolls", {
...data,
discordUserId: user.discordUserId,
dice: rolls,
})

// remove old dice rolls if there are too many
const allRolls = await ctx.db.query("diceRolls").collect()
const excessRolls = allRolls.slice(0, -maxRolls)
await Promise.all(excessRolls.map((r) => ctx.db.delete(r._id)))
},
})
3 Replies
ballingt
ballingt17mo ago
Re: idiomatic, could be a cron job or a job that gets scheduled to run immediately — could cut down the latency a tiny bit. What you've got here is how I'd do it, curious if others have ideas.
sshader
sshader17mo ago
I've used a mix of a cron job or an immediately scheduled job for this for one of my apps. I have a little card game where clicking "end game" essentially schedules a mutation that deletes the cards and other game state I don't need anymore.
jamwt
jamwt17mo ago
I've done the same thing in one or two of my apps

Did you find this page helpful?