import { localrun } from "pinus/lib/master/starter"; import { setLock, releaseLock, getLock } from './redlockCacheService'; var Redlock = require('redlock'); var _redlockCache; export function initRedlock (redisClient) { _redlockCache = new RedlockService(redisClient); } export class RedlockService { _redisClient: any; ttl: number; redlock: any; constructor(redisClient) { this._redisClient = redisClient; this._redisClient.on("error", function (err) { console.error("Redis:Error:" + err); }); this.ttl = 1000; this.redlock = new Redlock( [this._redisClient], { // the expected clock drift; for more details // see http://redis.io/topics/distlock driftFactor: 0.01, // time in ms // the max number of times Redlock will attempt // to lock a resource before erroring retryCount: 10, // the time in ms between attempts retryDelay: 200, // time in ms // the max time in ms randomly added to retries // to improve performance under high contention // see https://www.awsarchitectureblog.com/2015/03/backoff.html retryJitter: 200 // time in ms } ); this.redlock.on('clientError', function(err) { console.error('A redis error has occurred:', err); }); } } export async function lockData(serverId: number, dataName: string, id: string ) { let key = 'serverId_'+serverId+'_'+dataName+'_'+id; let lockKey = 'locks:' + key; console.log(' lockKey = '+ lockKey); return await lock(lockKey); } function lock(lockKey: string) { return _redlockCache.redlock.lock(lockKey, _redlockCache.ttl).then(function(lock) { setLock(lockKey, lock); return {err: null, releaseCallback: releaseCallback.bind(null, lockKey)}; }).catch(function(err) { console.error(err); return { err }; }); } export async function releaseCallback(lockKey: string) { releaseLock(lockKey); } export async function isLocked(serverId: number, dataName: string, id: string) { let key = 'serverId_'+serverId+'_'+dataName+'_'+id; let lockKey = 'locks:' + key; return getLock(lockKey); }