void ConnectTwoPoint(LockItem pre, LockItem now) { if (pre == now) { return; } Vector3 pos = (pre.transform.position + now.transform.position) / 2; Vector3 engel = Vector3.zero; float dis = Loc.Distance(pre.loc, now.loc); if (dis != 1) { if (pre.loc.y < now.loc.y && pre.loc.x < now.loc.x || pre.loc.y > now.loc.y && pre.loc.x > now.loc.x) { engel = new Vector3(0, 0, -45); } else { engel = new Vector3(0, 0, 45); } } else { if (pre.loc.y != now.loc.y) { engel = new Vector3(0, 0, 90); } } Image mag = GameObject.Instantiate <GameObject>(line).GetComponent <Image>(); mag.transform.SetParent(lineTrans); mag.transform.localScale = Vector3.one; mag.transform.position = pos; mag.transform.localEulerAngles = engel; }
void DrawSelection(LockItem trans) { ConnectTwoPoint(prePoint, trans); recordList.Add(trans.transform); trans.GetComponent <Image>().sprite = selectSprite; prePoint = trans; }
/// <summary> /// 释放指定名称的锁 /// </summary> /// <param name="itemname"></param> public void Free(string itemname) { LockItem lockitem = null; lock (lockobj) { Dictionary <string, LockItem> dicitems = null; if (_dicobj.ContainsKey(CurrentWorkArea)) { dicitems = _dicobj[CurrentWorkArea]; } else { dicitems = new Dictionary <string, LockItem>(); _dicobj.Add(CurrentWorkArea, dicitems); } if (dicitems.ContainsKey(itemname)) { lockitem = dicitems[itemname]; } else { lockitem = new LockItem(itemname); dicitems.Add(lockitem.Name, lockitem); } } if (System.Threading.Monitor.IsEntered(lockitem)) { System.Threading.Monitor.Exit(lockitem); lockitem.State = LockState.Free; } }
/// <summary> /// ToLockMsg /// </summary> /// <param name="lockItem">thisLockItem</param> /// <returns>string</returns> public static string ToLockMsg(this LockItem lockItem) { if (null == lockItem) { GlobalDefinition.LoggerWrapper.LogDevError("[ToLockMsg][lockItem == null]"); return(string.Empty); } GlobalDefinition.LoggerWrapper.LogDevWarning("[ToLockMsg][Comment:" + lockItem.Comment + "]"); var lockTip = GlobalDefinition.ToLocalLanguge("UID_PA_Item_LockedInfo"); if (string.IsNullOrEmpty(lockTip)) { GlobalDefinition.LoggerWrapper.LogDevWarning("[ToLockMsg][lockTip is empty]"); return(string.Empty); } if (string.IsNullOrEmpty(lockItem.Comment)) { GlobalDefinition.LoggerWrapper.LogDevWarning("[ToLockMsg][lockItem.Comment is empty]"); return(lockTip); } var c = GlobalDefinition.ToLocalLanguge(lockItem.Comment); if (string.IsNullOrEmpty(c)) { GlobalDefinition.LoggerWrapper.LogDevWarning("[ToLockMsg][not find resource:" + lockItem.Comment + "]"); return(lockTip); } return(string.Format("{0} ({1}...)", lockTip, c)); }
public WaitResult(MultiLock <TKey> multiLock, LockItem lockItem, TKey key, bool acquired) { MultiLock = multiLock; LockItem = lockItem; Key = key; LockAcquired = acquired; }
void OnItemPressed(LockItem trans) { if (!isBegin) { isBegin = true; prePoint = trans; DrawSelection(trans); Debug.Log("begin draw"); } }
public override bool Equals(Object obj) { LockItem <T> p = obj as LockItem <T>; if ((object)p == null) { return(false); } return(this == p); }
private LockItem CreateLockFromDbAttribute(Dictionary <string, AttributeValue> item, DateTime lookUpTime) { if (!item.ContainsKey(OwnerName) || !item.ContainsKey(LeaseDuration) || !item.ContainsKey(_partitionKeyName) || !item.ContainsKey(RecordVersionNumber)) { throw new InvalidOperationException("cannot create LockItem from dbItem"); } string ownerName = null; long leaseDuration = 0; string recordVersionNumber = null; string partitionKey = null; bool isReleased; //bool deleteOnRelease = true; if (item.TryGetValue(OwnerName, out var ownerNameAttributeValue)) { ownerName = ownerNameAttributeValue.S; } if (item.TryGetValue(_partitionKeyName, out var partitionKeyAttributeValue)) { partitionKey = partitionKeyAttributeValue.S; } if (item.TryGetValue(LeaseDuration, out var leaseDurationAttributeValue)) { var leaseDurationValue = leaseDurationAttributeValue.S; leaseDuration = long.Parse(leaseDurationValue); } if (item.TryGetValue(RecordVersionNumber, out var recordVersionAttributeValue)) { recordVersionNumber = recordVersionAttributeValue.S; } if (item.TryGetValue(DeleteOnRelease, out var deleteOnReleaseAttributeValue)) { // deleteOnRelease = deleteOnReleaseAttributeValue.BOOL; } isReleased = item.ContainsKey(IsReleased); var lockItem = new LockItem(partitionKey, ownerName, recordVersionNumber, lookUpTime, leaseDuration, isReleased); return(lockItem); }
public void Init() { RepositoryMock = new Mock <IResourceLockRepository>(); Lock = LockItem.CreateRead("xxx", null); //add both read and write locks as secondary ones SecondaryLocks = new List <LockItem>(); for (int i = 0; i < 10; i++) { var item = i % 2 == 0 ? LockItem.CreateRead(i.ToString(), null) : LockItem.CreateWrite(i.ToString(), null); SecondaryLocks.Add(item); } }
public LockItem TryAcquireLockItem(string partitionKey, long?millisecondsToWait, long?refreshPeriodInMilliseconds, bool retryOnFirstFail = true) { LockItem lockItem = null; var acquireAction = new Func <LockItem>(() => { try { LockItem item = null; Task.Run(async() => { item = await AcquireLockItemAsync(partitionKey, millisecondsToWait, refreshPeriodInMilliseconds); }).Wait(); return(item); } catch (AggregateException ae) { foreach (var e in ae.Flatten().InnerExceptions) { ExceptionDispatchInfo.Capture(e).Throw(); } } return(null); }); try { lockItem = acquireAction(); } catch (Exception e) { if (retryOnFirstFail) { retryOnFirstFail = false; lockItem = acquireAction(); } else { ExceptionDispatchInfo.Capture(e).Throw(); } } return(lockItem); }
void OnItemEnter(LockItem trans) { if (!isBegin || _isEnd) { return; } if (recordList.Contains(trans.transform)) { return; } if (Loc.Distance(prePoint.loc, trans.loc) >= 2) { return; } DrawSelection(trans); prePoint = trans; }
public static bool GetLock(string id) { if (string.IsNullOrEmpty(id)) { return(false); } id = id.ToLower().Trim(); int wait = 0; int threadId = Thread.CurrentThread.ManagedThreadId; Next: lock (LockObj) { if (Locks.ContainsKey(id)) { if (Locks[id].ThreadId == threadId) { Locks[id].ReLock(); return(true); } if (Locks[id].IsOverdue()) {//已经过期 Locks[id] = new LockItem(threadId); return(true); } } else { Locks.Add(id, new LockItem(threadId)); return(true); } } if (wait < TRYCOUNT) { wait++; Thread.Sleep(TRYINTERVAL); goto Next; } return(false); }
private LockItem AddLockItemToDynamo(string partitionKey, string recordVersionNumber, PutItemRequest putItemRequest) { long lastUpdatedTime = LockClientUtils.TimeStamp(); PutItemResponse response = _client.PutItemAsync(putItemRequest).Result; if (response.HttpStatusCode == HttpStatusCode.OK) { //todo: do something with this } LockItem lockItem = new LockItem(partitionKey, _ownerName, recordVersionNumber, DateTime.Now, null); _locks.TryAdd(lockItem.UniqueIdentifier, lockItem); return(lockItem); }
private void ReleaseLockItem(LockItem lockItem, TKey key) { lock (Locker) { lockItem.UsedCount -= 1; if (lockItem.UsedCount == 0) { if (Dictionary.TryGetValue(key, out var stored)) { if (stored == lockItem) // Sanity check { Dictionary.Remove(key); if (Pool.Count < PoolSize) { Pool.Enqueue(lockItem); } } } } } }
public LockItem AddAndWatchNewOrReleasedLock(string partitionKey, string recordVersionNumber, Dictionary <string, AttributeValue> item) { Dictionary <string, string> expressionAttributeNames = new Dictionary <string, string> { { PkPathExpressionVariable, _partitionKeyName }, { IsReleasedPathExpressionVariable, IsReleased } }; Dictionary <string, AttributeValue> expressionAttributeValues = new Dictionary <string, AttributeValue> { { IsReleasedValueExpressionVariable, IsReleasedAttributeValue } }; PutItemRequest putItemRequest = new PutItemRequest(_tableName, item) { ConditionExpression = AcquireLockThatDoesntExistOrIsReleasedCondition, ExpressionAttributeNames = expressionAttributeNames, ExpressionAttributeValues = expressionAttributeValues }; long lastUpdatedTime = LockClientUtils.TimeStamp(); PutItemResponse response = _client.PutItemAsync(putItemRequest).Result; if (response.HttpStatusCode != HttpStatusCode.OK) { //todo: do something with this } LockItem lockItem = new LockItem(partitionKey, _ownerName, recordVersionNumber, DateTime.Now, null); _locks.TryAdd(lockItem.UniqueIdentifier, lockItem); return(lockItem); }
private LockItem GetLockItem(TKey key) { LockItem lockItem; lock (Locker) { if (!Dictionary.TryGetValue(key, out lockItem)) { if (Pool.Count > 0) { lockItem = Pool.Dequeue(); } else { lockItem = new LockItem(); } Dictionary.Add(key, lockItem); } lockItem.UsedCount += 1; } return(lockItem); }
/// <summary> /// Waits for and acquires a lock on the specified key. Dispose the returned value to release the lock. /// </summary> /// <param name="key"></param> public Task <IDisposable> GetLock(T key) { // ReSharper disable once InconsistentlySynchronizedField - by design var nextLi = new LockItem(locks, key); try { var continueImmediately = false; lock (locks) { if (!locks.TryGetValue(key, out var li)) { locks.Add(key, nextLi); continueImmediately = true; } else { while (li.Next != null) { li = li.Next; } li.Next = nextLi; } } if (continueImmediately) { nextLi.Continue(); } } catch (Exception e) { nextLi.Error(e); } return(nextLi.GetTask()); }
public Task <IDisposable> GetLock(T key) { LockItem nextLi = new LockItem(locks, key); try { bool continueImmediately = false; lock (locks) { LockItem li; if (!locks.TryGetValue(key, out li)) { locks.Add(key, nextLi); continueImmediately = true; } else { while (li.Next != null) { li = li.Next; } li.Next = nextLi; } } if (continueImmediately) { nextLi.Continue(); } } catch (Exception e) { nextLi.Error(e); } return(nextLi.GetTask()); }
void OnItemUp(LockItem trans) { if (!isBegin) { return; } if (recordList.Count <= maxPoint && recordList.Count >= minPoint) //点个数有效 { isEnd = true; } if (!_isEnd) { OnDrawIllegal(recordList.Count); DisDrawSelection(); } else { List <int> vl = new List <int>(); recordList.ForEach((x) => { vl.Add(x.GetComponent <LockItem>().getValue()); }); OnDrawEnd(vl.ToArray()); } }
public void Init() { Lock = LockItem.CreateDenied("xxx"); RepositoryMock = new Mock <IResourceLockRepository>(); Guard = new ResourceLockGuard(Lock, Repository); }
public void Init() { Lock = LockItem.CreateWrite("xxx", null); RepositoryMock = new Mock <IResourceLockRepository>(); Guard = new ResourceLockGuard(Lock, Repository); }
public bool Equals(LockItem <T> p) { return(this == p); }
private async Task <LockItem> AcquireLockItemAsync(string partitionKey, long?millisecondsToWait, long?refreshPeriodInMilliseconds) { long timeToWait = millisecondsToWait ?? DefaultBufferMs; long refreshPeriod = refreshPeriodInMilliseconds ?? DefaultBufferMs; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); LockItem lockTryingToBeAcquired = null; bool alreadySleptOnceForOneLeasePeriod = false; while (true) { try { try { var existingLockItem = GetExistingLock(partitionKey); if (existingLockItem == null || existingLockItem.IsReleased) { var recordVersionNumber = GenerateRecordVersionNumber(); var item = BuildLockItem(partitionKey, recordVersionNumber); var lockItem = AddAndWatchNewOrReleasedLock(partitionKey, recordVersionNumber, item); var lockAcquiredTime = stopWatch.ElapsedMilliseconds; Console.WriteLine($"lock acquired in {lockAcquiredTime / 1000}"); return(lockItem); } if (lockTryingToBeAcquired == null) { //this branch of logic only happens once, in the first iteration of the while loop //lockTryingToBeAcquired only ever gets set to non-null values after this point. //so it is impossible to get in this /* * Someone else has the lock, and they have the lock for LEASE_DURATION time. At this point, we need * to wait at least LEASE_DURATION milliseconds before we can try to acquire the lock. */ lockTryingToBeAcquired = existingLockItem; if (!alreadySleptOnceForOneLeasePeriod) { alreadySleptOnceForOneLeasePeriod = true; timeToWait += existingLockItem.LeaseDuration; Console.WriteLine($"will wait {timeToWait / 1000} seconds for lock"); } } else { if (lockTryingToBeAcquired.RecordVersionNumber.Equals(existingLockItem.RecordVersionNumber)) { /* If the version numbers match, then we can acquire the lock, assuming it has already expired */ if (lockTryingToBeAcquired.IsExpired) { var lockItem = UpsertExpiredLock(partitionKey, lockTryingToBeAcquired.RecordVersionNumber); var lockAcquiredTime = stopWatch.ElapsedMilliseconds; Console.WriteLine($"lock acquired in {lockAcquiredTime / 1000}"); return(lockItem); } } else { /* * If the version number changed since we last queried the lock, then we need to update * lockTryingToBeAcquired as the lock has been refreshed since we last checked */ lockTryingToBeAcquired = existingLockItem; } } } catch (ConditionalCheckFailedException conditionalCheckFailedException) { /* Someone else acquired the lock while we tried to do so, so we throw an exception */ // logger.debug("Someone else acquired the lock", conditionalCheckFailedException); throw new LockNotGrantedException("Could not acquire lock because someone else acquired it: ", conditionalCheckFailedException); } catch (AmazonClientException amazonClientException) { /* This indicates that we were unable to successfully connect and make a service call to DDB. Often * indicative of a network failure, such as a socket timeout. We retry if still within the time we * can wait to acquire the lock. */ // logger.warn("Could not acquire lock because of a client side failure in talking to DDB", amazonClientException); } } catch (LockNotGrantedException lockNotGrantedException) { if (stopWatch.ElapsedMilliseconds > timeToWait) { //logger.debug("This client waited more than millisecondsToWait=" + millisecondsToWait // + " ms since the beginning of this acquire call.", x); //throw x; throw; } } double timeElapsed = Math.Round((double)stopWatch.ElapsedMilliseconds, MidpointRounding.ToEven); Console.WriteLine($"Time elapsed {timeElapsed * 0.001} seconds"); if (timeElapsed > timeToWait) { Console.WriteLine($"item timesince last lookup {lockTryingToBeAcquired.TimeSinceLastLookUp}"); Console.WriteLine($"lock not granted after {timeElapsed / 1000} seconds of waiting. "); throw new LockNotGrantedException( "Didn't acquire lock after sleeping for " + (timeElapsed) + " milliseconds", null); } //logger.trace("Sleeping for a refresh period of " + refreshPeriodInMilliseconds + " ms"); Console.WriteLine("Sleeping for a refresh period of " + refreshPeriod + " ms"); //Thread.Sleep((int)refreshPeriod); var sleepStartTime = stopWatch.ElapsedMilliseconds; await Task.Delay((int)refreshPeriod); var sleepEndTime = stopWatch.ElapsedMilliseconds; var sleepTime = sleepEndTime - sleepStartTime; Console.WriteLine($"slept {sleepTime / 1000} seconds"); } }
public bool ReleaseLock(LockItem item) { if (!item.Owner.Equals(_ownerName)) { return(false); } lock (_threadLock) { try { _locks.TryRemove(item.UniqueIdentifier, out var removedLockItem); Dictionary <string, AttributeValue> expressionAttributeValues = new Dictionary <string, AttributeValue> { { RvnValueExpressionVariable, new AttributeValue { S = item.RecordVersionNumber } }, { OwnerNameValueExpressionVariable, new AttributeValue { S = item.Owner } } }; Dictionary <string, string> expressionAttributeNames = new Dictionary <string, string> { { PkPathExpressionVariable, _partitionKeyName }, { OwnerNamePathExpressionVariable, OwnerName }, { RvnPathExpressionVariable, RecordVersionNumber } }; var conditionalExpression = PkExistsAndOwnerNameSameAndRvnSameCondition; Dictionary <string, AttributeValue> key = new Dictionary <string, AttributeValue> { { _partitionKeyName, new AttributeValue { S = item.UniqueIdentifier } } }; string updateExpression = null; expressionAttributeNames.Add(IsReleasedPathExpressionVariable, IsReleased); expressionAttributeValues.Add(IsReleasedValueExpressionVariable, IsReleasedAttributeValue); updateExpression = UpdateIsReleased; UpdateItemRequest updateItemRequest = new UpdateItemRequest(_tableName, key, null) { ConditionExpression = conditionalExpression, UpdateExpression = updateExpression, ExpressionAttributeNames = expressionAttributeNames, ExpressionAttributeValues = expressionAttributeValues }; UpdateItemResponse response = _client.UpdateItemAsync(updateItemRequest, CancellationToken.None).Result; } catch (ConditionalCheckFailedException conditionalCheckFailedException) { // logger.debug("Someone else acquired the lock before you asked to release it", conditionalCheckFailedException); return(false); } catch (AmazonClientException amazonClientException) { throw; } } return(true); }
public void SendHeartbeat(LockItem item) { long leaseDurationToEnsureInMilliseconds = _leaseDuration; if (item.IsExpired || !item.Owner.Equals(this._ownerName) || item.IsReleased) { _locks.TryRemove(item.UniqueIdentifier, out var removedLockItem); throw new LockNotGrantedException("Cannot send heartbeat because lock is not granted", null); } lock (_threadLock) { string recordVersionNumber = GenerateRecordVersionNumber(); string conditionalExpression = null; string updateExpression = null; Dictionary <string, AttributeValue> expressionAttributeValues = new Dictionary <string, AttributeValue> { { RvnValueExpressionVariable, new AttributeValue { S = item.RecordVersionNumber } }, { OwnerNameValueExpressionVariable, new AttributeValue { S = item.Owner } } }; Dictionary <string, string> expressionAttributeNames = new Dictionary <string, string> { { PkPathExpressionVariable, _partitionKeyName }, { LeaseDurationPathValueExpressionVariable, LeaseDuration }, { RvnPathExpressionVariable, RecordVersionNumber }, { OwnerNamePathExpressionVariable, OwnerName } }; expressionAttributeValues.Add(NewRvnValueExpressionVariable, new AttributeValue { S = recordVersionNumber }); expressionAttributeValues.Add(LeaseDurationValueExpressionVariable, new AttributeValue { S = _leaseDuration.ToString() }); conditionalExpression = PkExistsAndOwnerNameSameAndRvnSameCondition; updateExpression = UpdateLeaseDurationAndRvn; var key = new Dictionary <string, AttributeValue> { { _partitionKeyName, new AttributeValue { S = item.UniqueIdentifier } } }; UpdateItemRequest updateItemRequest = new UpdateItemRequest(_tableName, key, null) { ConditionExpression = conditionalExpression, UpdateExpression = updateExpression, ExpressionAttributeValues = expressionAttributeValues, ExpressionAttributeNames = expressionAttributeNames }; try { UpdateItemResponse response = _client.UpdateItemAsync(updateItemRequest).Result; if (response.HttpStatusCode != HttpStatusCode.OK) { throw new LockNotGrantedException("failed to updated database", null); } item.UpdatedRecordVersionNumber(recordVersionNumber, DateTime.Now, leaseDurationToEnsureInMilliseconds); Console.WriteLine($"updated lock item : {item.UniqueIdentifier} with new RVN: {recordVersionNumber} and lease {_leaseDuration / 1000} seconds"); } catch (ConditionalCheckFailedException conditionalCheckFailedException) { // logger.debug("Someone else acquired the lock, so we will stop heartbeating it", conditionalCheckFailedException); _locks.TryRemove(item.UniqueIdentifier, out var lockToRemove); throw new LockNotGrantedException("Someone else acquired the lock, so we will stop heartbeating it", conditionalCheckFailedException); } } }