public static bool Set(RedisConnection redisConnection, string key, string value, RedisOfficeStateStorageSettings settings) { string[] keyArgs = new string[] { key }; object[] valueArgs = new object[] { value }; string stringGetScript = @" local keyName = KEYS[1] local value = ARGV[1] local status = redis.call('SET', keyName, value) setExpired(keyName) local retValues = {} retValues[1] = status return retValues "; var expireScript = ExpireHelper.GetExpireScript(settings); var script = expireScript + stringGetScript; var results = (RedisResult[])(RedisResult)redisConnection.ScriptEvaluate(script, keyArgs, valueArgs); string setStatus = (string)results[0]; return(setStatus == "OK"); }
public static bool CheckIn(RedisConnection redisConnection, string lockerId, string workSessionId, string documentId, string state, RedisOfficeStateStorageSettings settings) { var keyBunch = new KeyNameHelper(workSessionId, documentId); string[] keyArgs = new string[] { keyBunch.LockerKeyName, keyBunch.StateKeyName, keyBunch.DocumentIdToWorkSessionIdKeyName, keyBunch.WorkSessionIdToDocumentIdKeyName }; object[] valueArgs = new object[] { lockerId, state, workSessionId, documentId }; string checkInScript = @" local lockerKeyName = KEYS[1] local stateKeyName = KEYS[2] local documentIdToWorkSessionIdKeyName = KEYS[3] local workSessionIdToDocumentIdKeyName= KEYS[4] local lockerId = ARGV[1] local state = ARGV[2] local workSessionId = ARGV[3] local documentId = ARGV[4] local stateUpdateStatus = 'failed' local docIdToStateIdUpdateStatus = 'failed' local stateIdToDocIdUpdateStatus = 'failed' local locker_DeletedKeysCount = 0 updateATime(stateKeyName) local wasLockedBy = redis.call('GET', lockerKeyName) local lockerWasNotFound = type(wasLockedBy) == 'boolean' and not wasLockedBy local wasLocked = not lockerWasNotFound local wasLockedByMe = wasLockedBy == lockerId local wasLockedByAnother = wasLocked and not wasLockedByMe if not wasLockedByAnother then stateUpdateStatus = redis.call('SET', stateKeyName, state) setExpired(stateKeyName) if not (documentId == nil or documentId == '') then docIdToStateIdUpdateStatus = redis.call('SET', documentIdToWorkSessionIdKeyName, workSessionId) stateIdToDocIdUpdateStatus = redis.call('SET', workSessionIdToDocumentIdKeyName, documentId) setExpired(documentIdToWorkSessionIdKeyName) setExpired(workSessionIdToDocumentIdKeyName) end end if wasLockedByMe then locker_DeletedKeysCount = redis.call('DEL', KEYS[1]) end local retValues = {} retValues[1] = stateUpdateStatus retValues[2] = locker_DeletedKeysCount retValues[3] = wasLockedByMe retValues[4] = wasLocked --[[ docIdToStateIdUpdateStatus stateIdToDocIdUpdateStatus --]] return retValues "; var expireScript = ExpireHelper.GetExpireScript(settings); var atimeUpdateScript = GetAccessTimeUpdateScript(settings); var script = expireScript + atimeUpdateScript + checkInScript; var results = (RedisResult[])(RedisResult)redisConnection.ScriptEvaluate(script, keyArgs, valueArgs); string stateUpdateStatus = (string)results[0]; #if DebugTest int locker_DeletedKeysCount = (int)results[1]; bool wasLockedByMe = (bool)results[2]; bool wasLocked = (bool)results[3]; DiagnosticEvents.OnCheckIn(workSessionId, documentId, lockerId, stateUpdateStatus, locker_DeletedKeysCount, wasLockedByMe, wasLocked); #endif bool success = stateUpdateStatus == "OK"; return(success); }
internal static bool AddCheckedOut(RedisConnection redisConnection, string lockerId, string workSessionId, string documentId, RedisOfficeStateStorageSettings settings) { var keyBunch = new KeyNameHelper(workSessionId, documentId); string[] keyArgs = new string[] { keyBunch.LockerKeyName, keyBunch.StateKeyName, keyBunch.DocumentIdToWorkSessionIdKeyName, keyBunch.WorkSessionIdToDocumentIdKeyName }; object[] valueArgs = new object[] { lockerId, workSessionId, documentId, settings.LockerTTL }; string addCheckedOutScript = @" local lockerKeyName = KEYS[1] local stateKeyName = KEYS[2] local documentIdToWorkSessionIdKeyName = KEYS[3] local workSessionIdToDocumentIdKeyName = KEYS[4] local lockerId = ARGV[1] local workSessionId = ARGV[2] local documentId = ARGV[3] local lockerTTL = ARGV[4] local stateUpdateStatus = 'failed' local docIdToStateIdUpdateStatus = 'failed' local stateIdToDocIdUpdateStatus = 'failed' local wasLockedByAnother = false updateATime(stateKeyName) local documentIdSearch = getWorkSessionIdFromDocumentId(documentIdToWorkSessionIdKeyName) local sessionForThisDocumentIdFound = documentIdSearch[1]; if not sessionForThisDocumentIdFound then wasLockedByAnother = tryToLock(lockerKeyName, lockerId, lockerTTL) local state = '' if not wasLockedByAnother then stateUpdateStatus = redis.call('SET', stateKeyName, state) setExpired(stateKeyName) if not (documentId == nil or documentId == '') then docIdToStateIdUpdateStatus = redis.call('SET', documentIdToWorkSessionIdKeyName, workSessionId) stateIdToDocIdUpdateStatus = redis.call('SET', workSessionIdToDocumentIdKeyName, documentId) setExpired(documentIdToWorkSessionIdKeyName) setExpired(workSessionIdToDocumentIdKeyName) end end end local retValues = {} retValues[1] = sessionForThisDocumentIdFound retValues[2] = wasLockedByAnother retValues[3] = stateUpdateStatus retValues[4] = docIdToStateIdUpdateStatus retValues[5] = stateIdToDocIdUpdateStatus return retValues "; var expireScript = ExpireHelper.GetExpireScript(settings); var atimeUpdateScript = GetAccessTimeUpdateScript(settings); var script = expireScript + atimeUpdateScript + getWorkSessionIdFromDocumentId + tryToLock + addCheckedOutScript; var results = (RedisResult[])(RedisResult)redisConnection.ScriptEvaluate(script, keyArgs, valueArgs); var sessionForThisDocumentIdFound = (bool)results[0]; var wasLockedByAnother = (bool)results[1]; string stateUpdateStatus = (string)results[2]; #if DebugTest var docIdToStateIdUpdateStatus = (string)results[3]; var stateIdToDocIdUpdateStatus = (string)results[4]; DiagnosticEvents.OnAddCheckOut(workSessionId, documentId, lockerId, stateUpdateStatus, sessionForThisDocumentIdFound, wasLockedByAnother, docIdToStateIdUpdateStatus, stateIdToDocIdUpdateStatus); #endif bool success = stateUpdateStatus == "OK"; if (sessionForThisDocumentIdFound) { throw new CannotAddWorkSessionThatAlreadyExistsException(); } return(success); }