Compare commits

...

11 Commits

Author SHA1 Message Date
7946c61468 remove comment block 2025-04-04 09:15:35 +02:00
0b77de8b4c fix ttl sometimes -1 2025-04-04 09:14:04 +02:00
6ae5b3ddd2 fix formatting, bump version 2025-01-10 18:30:13 +01:00
66261365d7 change package name 2025-01-10 18:25:59 +01:00
8ec81cf547 add publish script 2025-01-10 16:03:08 +01:00
c26e8f227a add .npmrc to gitignore 2025-01-10 15:59:09 +01:00
33050a6f4a bump version, add .npmignore 2025-01-10 15:55:50 +01:00
cfd430e31c remove mutex options 2025-01-10 01:20:21 +01:00
20496cc24b make MutexOptions optional 2025-01-10 01:20:11 +01:00
33a49cba4a make MutexOptions optional 2025-01-10 01:19:55 +01:00
f65ab42231 make redis host and port optional 2025-01-10 01:19:06 +01:00
6 changed files with 30 additions and 25 deletions

1
.gitignore vendored
View File

@@ -70,6 +70,7 @@ web_modules/
# Optional npm cache directory # Optional npm cache directory
.npm .npm
.npmrc
# Optional eslint cache # Optional eslint cache

6
.npmignore Normal file
View File

@@ -0,0 +1,6 @@
test/
node_modules/
README.md
.gitignore
biome.json
bun.lockb

View File

@@ -1,9 +1,11 @@
{ {
"name": "mutex-lock-redis", "name": "@osudirect/mutex-lock-redis",
"version": "1.1.0",
"module": "index.ts", "module": "index.ts",
"type": "module", "type": "module",
"scripts": { "scripts": {
"lint": "bunx biome check --write" "lint": "bunx biome check --write",
"publish": "npm publish --scope=ezppfarm"
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "1.9.4", "@biomejs/biome": "1.9.4",

View File

@@ -9,17 +9,17 @@ type RedisClient = redis.RedisClientType<
export class MutexLock { export class MutexLock {
redisClient: RedisClient; redisClient: RedisClient;
mutexOptions: MutexOptions; mutexOptions: MutexOptions | undefined;
constructor(redisClient: RedisClient, options: MutexOptions) { constructor(redisClient: RedisClient, options?: MutexOptions) {
this.mutexOptions = options; this.mutexOptions = options;
this.redisClient = redisClient; this.redisClient = redisClient;
} }
static async create(options: MutexOptions) { static async create(options?: MutexOptions) {
const redisClient = await redis const redisClient = await redis
.createClient({ .createClient({
url: `redis://${options.redis.host}:${options.redis.port}`, url: `redis://${options?.redis?.host ?? "127.0.0.1"}:${options?.redis?.port ?? 6379}`,
}) })
.connect(); .connect();
@@ -31,21 +31,22 @@ export class MutexLock {
const releaseFunc = async () => { const releaseFunc = async () => {
await this.redisClient.del(lockIdentifier); await this.redisClient.del(lockIdentifier);
}; };
let ttl = this.mutexOptions?.mutex?.ttl || 60;
if (ttl <= 0) ttl = 60;
while (true) { while (true) {
const acquired = await this.redisClient.set(lockIdentifier, "1", { const acquired = await this.redisClient.set(lockIdentifier, "1", {
NX: true NX: true,
EX: ttl,
}); });
if (acquired) { if (acquired) {
await this.redisClient.expire(
lockIdentifier,
this.mutexOptions.mutex?.ttl || 60
);
return releaseFunc; return releaseFunc;
} }
await new Promise(resolve => await new Promise((resolve) =>
setTimeout(resolve, this.mutexOptions.mutex?.checkInterval || 100) setTimeout(resolve, this.mutexOptions?.mutex?.checkInterval || 100),
); );
} }
}} }
}

View File

@@ -1,7 +1,7 @@
export type MutexOptions = { export type MutexOptions = {
redis: { redis?: {
host: string; host?: string;
port: number; port?: number;
}; };
mutex?: { mutex?: {
checkInterval?: number; checkInterval?: number;

View File

@@ -4,12 +4,7 @@ import { MutexLock } from "../src/MutexLock";
test( test(
"redis mutex", "redis mutex",
async () => { async () => {
const mutexLock = await MutexLock.create({ const mutexLock = await MutexLock.create();
redis: {
host: "127.0.0.1",
port: 6379,
},
});
const testLock = async () => { const testLock = async () => {
const release = await mutexLock.obtainLock("test"); const release = await mutexLock.obtainLock("test");