Skip to content

Conversation

@lexuzieel
Copy link
Contributor

Hello, I have encountered a somewhat weird edge case which this PR aims to fix.

I am currently developing a package that uses Verrou under the hood. I am using knex adapter for postgres and in my project I am using testcontainers to spin up ephemeral postgres instance.

Somehow during testing there occurs a race condition where Verrou tries to create table twice & as a result it tries to create primary key multiple times as well. Here is the error that I get:

error: create table "verrou" ("key" varchar(255) not null,
"owner" varchar(255) not null, "expiration" bigint null,
constraint "verrou_pkey" primary key ("key")) - duplicate
key value violates unique constraint "pg_type_typname_nsp_index"

Wrapping table creation logic into a transaction and issuing an advisory lock fixes this for my case.

Take note, that I have not tested it with kysely but I think it is the same with that one.

The only caveat with this PR is the hash generation for cache (I am not that familiar with postgres) but I suppose it should be safe since it is inside transaction.

@Julien-R44
Copy link
Owner

Hey, thanks a lot for investigating

what about using CREATE TABLE IF NOT EXIST instead? i think it should also solve your issue? Maybe you already tried

@lexuzieel
Copy link
Contributor Author

Yeah I tried using it briefly through .raw(), however it didn't have any effect. I think this might be because primary index creation is a separate operation.

I tried using raw SQL like so:

error: 
      CREATE TABLE IF NOT EXISTS verrou (
        key varchar(255) NOT NULL PRIMARY KEY,
        owner varchar(255) NOT NULL,
        expiration bigint NULL
      )
     - duplicate key value violates unique constraint "pg_type_typname_nsp_index"

@Julien-R44 Julien-R44 closed this in 3703ba8 Dec 6, 2025
@Julien-R44
Copy link
Owner

Hey man, I attempted a fix in the commit jsut above. your solution could indeed work, but issue is that its Postgres-specific, and the Knex driver is used with other databases too

So lets see if the next release fixes your issue. If not, a reproduction would be super helpful!

@lexuzieel
Copy link
Contributor Author

Awesome, looks like your fix works!

I've updated the package to 0.5.2 and added some debug logging to verify - catch branch executes, but the code does not throw anymore, so it works as intended.

Anyway, I have created a reproduction branch in case you are curious: https://github.com/lexuzieel/lavoro/tree/verrou-knex-race

Since the test is flaky, you better run it like so (it will automatically spin up postgres in docker):

for i in {1..100}; do npm run test postgres_lock_provider; done

This is an error that I was getting:

изображение

P.S. Yes, the name of the package is in fact inspired by verrou in a way :) and the package has adonisjs integration. Actually, I have in my plans to open a discussion with you guys in adonisjs forum, but after I draft up some docs & motivation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants