Locking & Drafting in RedwoodJS

Problem 1 - Locking

We have developed a job management system that integrates with various other job systems.
Within our application, there can be multiple actors accessing our jobs at any given time.

Approach - Locking

We think we can achieve an integral job model using database locking.

We are thinking of doing this by adding the following

Prisma

model Job {
    ...
    Lock: ModelLock @relation(...)
}
 
model Lock {
    id Int @id @default(autoincrement())
    lockedBy User
    lockedAt DateTime
    locked Boolean
    takeOverMessage? String
    takeOverAt? DateTime
    Job? Job @relation(...)
    ...
}

Logic

When there is an active lock, anyone else opening the job will be prompted that it’s locked. They can read only or kick out the other user.

It is assumed the editing user will be polling the Lock model to ensure no one is trying to kick them out.
They will then have a certain amount of time to respond to the takeover request.

Problem 2 - Drafting

Our users should be able to save the form at any point in its completion and other actors be able to access this data across devices.

Approach 2 - Drafting

Save json data under the job table

Prisma

model Job {
    ...
    draft?: JSON
}

Logic

Save the json data under the job periodically, and on load of the form pre-fill the fields. On submit the draft is reset.

Any help is appreciated!

Hi @declanb – interesting case.

Many years ago when I was writing some Rails app with a Job queue I wanted to ensure jobs didn’t clobber each otehr so when a job was triggered it checked if any task for that job was currently running. I kept an audit trail of sorts (similar to your Lock). essentially it was a Run. A job was the logic, and a Run was an instance of the running Job. A run could not be added if any other Run for that Job was currently running and not ended. It was crude, but for my not so critical use cases, was adequate.

That said, other Job runners like Inngest take a much more reliable approach and they discuss various techniques here: Handling idempotency - Inngest Documentation

You might be able to replicate those techniques.

Also, I’d double check that “Lock” isn’t a reserved word for your database provider. When I read this are fist, I thought you were locking the database itself.

As for the draft, I am a but confused. Is the Job a Draft (the logic) or is the Run a draft (schedule a run of the Job in some indefinitely future)? If the first: that seems difficult unless the Job is some data criteria for the actual Process Task logic. In the latter, I’m not sure If the “Lock” or rather the “Run” is where the draft might be.

1 Like