Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Foreign key constraint error when deleting queue #514

Open
OyugoObonyo opened this issue Oct 16, 2024 · 3 comments
Open

Foreign key constraint error when deleting queue #514

OyugoObonyo opened this issue Oct 16, 2024 · 3 comments

Comments

@OyugoObonyo
Copy link

I am using pgBoss v10 on node version 22 and postgresql 16. I have tried deleting a queue existing in my DB by invoking the .deleteQueue("myQueueName") method. However, the queue isn't being deleted and I get this error:

Uncaught:
error: update or delete on table "queue" violates foreign key constraint "q_fkey" on table "j40563acd0ea36d7a20c7d0e7f76db3b9ed117babebab6a4149a0781a"

 length: 654,
  severity: 'ERROR',
  code: '23503',
  detail: 'Key (name)=(test-trial) is still referenced from table "j40563acd0ea36d7a20c7d0e7f76db3b9ed117babebab6a4149a0781a".',
  hint: undefined,
  position: undefined,
  internalPosition: undefined,
  internalQuery: undefined,
  where: 'SQL statement "WITH deleted as (\n' +
    '        DELETE FROM pgboss.queue\n' +
    '        WHERE name = queue_name\n' +
    '        RETURNING partition_name\n' +
    '      )\n' +
    '      SELECT partition_name from deleted"\n' +
    'PL/pgSQL function pgboss.delete_queue(text) line 5 at SQL statement',
  schema: 'pgboss',
  table: 'j40563acd0ea36d7a20c7d0e7f76db3b9ed117babebab6a4149a0781a',
  column: undefined,
  dataType: undefined,
  constraint: 'q_fkey',
  file: 'ri_triggers.c',
  line: '2621',
  routine: 'ri_ReportViolation'

Am I strictly limited to manually deleting queues from my DB instead of invoking the deleteQueue API?

@OyugoObonyo
Copy link
Author

Update: I've since been able to delete the queue by first deleting all the queue's jobs before deleting the queue itself. I've now tried setting up a queue with the same name and it has very unpredictable behaviour: sometimes it works, sometimes it doesn't. On times it doesn't work, I get the error like so:

error: relation "je95d8092e95eab390e11d733b07e00753bff292667445dbb4f0fe298" already exists

I've tried manually deleting all the referenced partitions like so:

DELETE FROM pg_inherits
USING pg_class parent, pg_class child
WHERE pg_inherits.inhparent = parent.oid
AND pg_inherits.inhrelid = child.oid
AND parent.relname = 'job'
AND child.relname <> 'j3f168501ed9816b51a9f5765e0742e1eb034ab6bf72c9ae3f3a975e3';

I've been able to successfully delete the partitions but somehow the relation already exists error keeps on showing up when I try creating a queue with the same name to one that I already deleted?

2 questions @timgit :

  1. How can I rectify this behaviour?
  2. Is there a more graceful way to handle queue deletions?

@timgit
Copy link
Owner

timgit commented Oct 19, 2024

There is a test in the suite that does exactly this. It deletes and re-creates a queue. Was this perhaps a unique failure use case?

@OyugoObonyo
Copy link
Author

Update: Must've been an issue on my side because I tried creating queues concurrently:

  private async persistDefinedQueues(definedQueues: Queue[]): Promise<void> {
    try {
      const storedQueues = await this.pgBoss.getQueues();
      const storedQueuesNames = new Set(
        storedQueues.map((storedQueue) => storedQueue.name),
      );
      const createQueuePromises = definedQueues
        .filter((definedQueue) => !storedQueuesNames.has(definedQueue.name))
        .map((definedQueue) => {
          const { name, options } = definedQueue;
          console.log(`Creating queue with name: ${name}`);
          return this.pgBoss.createQueue(name, options as PgBoss.Queue);
        });
      console.log('CREATED QUEUE PROMISES:: ', createQueuePromises);
      await Promise.all(createQueuePromises);

A refactor to a more one-by-one queue creation seems to have resolve the issue:

  private async persistDefinedQueues(definedQueues: Queue[]): Promise<void> {
    try {
      const persistedQueues = await this.pgBoss.getQueues();
      const persistedQueuesNames = new Set(
        persistedQueues.map((persistedQueue) => persistedQueue.name),
      );
      const unpersistedQueues = definedQueues.filter(
        (definedQueue) => !persistedQueuesNames.has(definedQueue.name),
      );
      for (const queue of unpersistedQueues) {
        const { name, options } = queue;
        await this.pgBoss.createQueue(name, options as PgBoss.Queue);
      }

Anywhere in the docs I can find situations in which i might run into a deadlock error?

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

No branches or pull requests

2 participants