Skip to content

Unable to reach quorum #168

@paymog

Description

@paymog

I'm having some trouble using this library. I have an endpoint which gets called twice upon page load and I'm trying to use a lock to perform sensitive database operations safely.

I'm using this library and I keep getting the following error in unusual ways which I haven't been able to figure out (maybe I have the library misconfigured?). Here's the code I'm using to initialize redlock:

import { getRedisURI } from './settings/settings.js';
import Redis from 'ioredis';
import Redlock from 'redlock';

export const redis = new Redis(getRedisURI());
export const redlock = new Redlock([redis]);

here's the code which does the sensitive database work:

async function createNewScheduleCardsIfNecessary(tripId) {
  let lock;
  console.log('attempting to make new schedule card items for trip', tripId);

  try {
    lock = await redlock.acquire([`${tripId}`], 5000, {
      retryDelay: 1000,
      retryCount: 30,
      automaticExtensionThreshold: 100,
      retryJitter: 1000,
    });
    console.log('acquired lock', tripId);
    const expectedNumberOfCards = await getExpectedNumberOfScheduleCards(tripId);
    const currentCards = await ScheduleCards.find({
      tripId,
    }).toArray();

    await createMissingScheduleCards(currentCards, expectedNumberOfCards, tripId);
    console.log('finished making schedule cards', tripId);
  } finally {
    if (lock) {
      console.log('releasing lock', tripId);
      await lock.release();
    }
  }
  console.log('all redlock stuff finished for trip', tripId);
}

here's the full output I'm getting:

Server running at http://localhost:5001/graphql


schedule cards called for trip vMEKsgzFy9EGdQKbp <------------ this indicates a request came in from the web 
attempting to make new schedule card items for trip vMEKsgzFy9EGdQKbp
acquired lock vMEKsgzFy9EGdQKbp
schedule cards called for trip vMEKsgzFy9EGdQKbp <--------------- here's the second request from the web
attempting to make new schedule card items for trip vMEKsgzFy9EGdQKbp
need to create schedule card for trip { part: 'morning', i: 0 }
need to create schedule card for trip { part: 'morning', i: 1 }
need to create schedule card for trip { part: 'morning', i: 2 }
need to create schedule card for trip { part: 'morning', i: 3 }
need to create schedule card for trip { part: 'morning', i: 4 }
need to create schedule card for trip { part: 'afternoon', i: 0 }
need to create schedule card for trip { part: 'afternoon', i: 1 }
need to create schedule card for trip { part: 'afternoon', i: 2 }
need to create schedule card for trip { part: 'afternoon', i: 3 }
need to create schedule card for trip { part: 'afternoon', i: 4 }
need to create schedule card for trip { part: 'evening', i: 0 }
need to create schedule card for trip { part: 'evening', i: 1 }
need to create schedule card for trip { part: 'evening', i: 2 }
need to create schedule card for trip { part: 'evening', i: 3 }
need to create schedule card for trip { part: 'evening', i: 4 }
need to create schedule card for trip { part: 'lodging', i: 0 }
need to create schedule card for trip { part: 'lodging', i: 1 }
need to create schedule card for trip { part: 'lodging', i: 2 }
need to create schedule card for trip { part: 'lodging', i: 3 }
need to create schedule card for trip { part: 'lodging', i: 4 }
finished making schedule cards vMEKsgzFy9EGdQKbp
releasing lock vMEKsgzFy9EGdQKbp
ExecutionError: The operation was unable to achieve a quorum during its retry window.
    at Redlock._execute (file:///Users/paymahn/code/tripvector/tripvector-mono/backend/node_modules/redlock/dist/esm/index.js:290:23)
    at async createNewScheduleCardsIfNecessary (file:///Users/paymahn/code/tripvector/tripvector-mono/backend/api/scheduleCards/graphql/queries.js:143:7)
    at async Object.scheduleCards (file:///Users/paymahn/code/tripvector/tripvector-mono/backend/api/scheduleCards/graphql/queries.js:153:5) {
  attempts: [
    Promise { [Object] },
    Promise { [Object] },
    Promise { [Object] },
    Promise { [Object] },
    Promise { [Object] },
    Promise { [Object] },
    Promise { [Object] },
    Promise { [Object] },
    Promise { [Object] },
    Promise { [Object] },
    Promise { [Object] }
  ]
}
ExecutionError: The operation was unable to achieve a quorum during its retry window.
    at Redlock._execute (file:///Users/paymahn/code/tripvector/tripvector-mono/backend/node_modules/redlock/dist/esm/index.js:290:23)
    at async Redlock.acquire (file:///Users/paymahn/code/tripvector/tripvector-mono/backend/node_modules/redlock/dist/esm/index.js:207:34)
    at async createNewScheduleCardsIfNecessary (file:///Users/paymahn/code/tripvector/tripvector-mono/backend/api/scheduleCards/graphql/queries.js:126:12)
    at async Object.scheduleCards (file:///Users/paymahn/code/tripvector/tripvector-mono/backend/api/scheduleCards/graphql/queries.js:153:5) {
  attempts: [
    Promise { [Object] }, Promise { [Object] },
    Promise { [Object] }, Promise { [Object] },
    Promise { [Object] }, Promise { [Object] },
    Promise { [Object] }, Promise { [Object] },
    Promise { [Object] }, Promise { [Object] },
    Promise { [Object] }, Promise { [Object] },
    Promise { [Object] }, Promise { [Object] },
    Promise { [Object] }, Promise { [Object] },
    Promise { [Object] }, Promise { [Object] },
    Promise { [Object] }, Promise { [Object] },
    Promise { [Object] }, Promise { [Object] },
    Promise { [Object] }, Promise { [Object] },
    Promise { [Object] }, Promise { [Object] },
    Promise { [Object] }, Promise { [Object] },
    Promise { [Object] }, Promise { [Object] },
    Promise { [Object] }
  ]
}

The time between the acquired lock and releasing lock log lines is around 1 second but for some reason, even with the generous retry policy I'm seeing redlock fail consistently.

The top stack trace includes line 143 which is the line where I release the lock. The bottom stack trace include line 126 which is where I acquire the lock.

I've tried using redlock.using as well but had the same results. I've downloaded a redis gui to inspect my local redis instance to see if there are any spurious keys but haven't been able to find any.

Here's my package.json:

    "@babel/runtime": "^7.16.3",
    "@graphql-tools/schema": "^8.3.1",
    "apollo-server-express": "^3.5.0",
    "axios": "^0.26.1",
    "bcryptjs": "^2.4.3",
    "body-parser": "^1.19.0",
    "chalk": "^4.1.2",
    "compression": "^1.7.4",
    "cookie-parser": "^1.4.6",
    "cors": "^2.8.5",
    "crypto-extra": "^1.0.1",
    "dayjs": "^1.10.7",
    "ejs": "^3.1.6",
    "express": "^4.17.1",
    "graphql": "^16.0.1",
    "graphql-redis-subscriptions": "^2.4.2",
    "graphql-subscriptions": "^2.0.0",
    "graphql-ws": "^5.7.0",
    "html-to-text": "^8.1.0",
    "immutability-helper": "^3.1.1",
    "ioredis": "^5.0.4",
    "jsonwebtoken": "^8.5.1",
    "juice": "^8.0.0",
    "lodash-es": "^4.17.21",
    "moment": "^2.29.3",
    "mongo-uri-tool": "^1.0.1",
    "mongodb": "^4.2.0",
    "nodemailer": "^6.7.2",
    "ps-node": "^0.1.6",
    "redlock": "^5.0.0-beta.2",
    "serve-favicon": "^2.5.0",
    "speakingurl": "^14.0.1",
    "ws": "^8.5.0"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions