public LockModel Lock(string lockname) { LockModel @lock = new LockModel(); Etcdserverpb.RangeResponse oldlockers = null; //use local cache speed up. lock (_lockerList) { var locallst = _lockerList.Where(c => c.Name == lockname).ToList(); if (locallst.Count > 0) { @lock.Result = LockResult.LockExists; @lock.Id = locallst.FirstOrDefault().Id; return(@lock); } } //confirm lock not exists. try { oldlockers = _client.GetAsync($"/locks/{lockname}").Result; } catch (Exception ex) { @lock.Id = 0; @lock.Result = LockResult.Fail; lock (_client) { _client = bestClient(_clients); } return(@lock); } //return lockid to locker . if (oldlockers?.Kvs.Count > 0) { @lock.Id = long.Parse(oldlockers.Kvs.FirstOrDefault().Value.ToStringUtf8()); @lock.Result = LockResult.LockExists; } else { //creat lock id TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); @lock.Id = (long)ts.TotalMilliseconds; @lock.Result = LockResult.Success; try { Etcdserverpb.LeaseGrantRequest request = new Etcdserverpb.LeaseGrantRequest(); request.TTL = _locklease; var lease = _client.LeaseGrant(request); Etcdserverpb.PutRequest put = new Etcdserverpb.PutRequest(); put.Key = Google.Protobuf.ByteString.CopyFromUtf8(($"/locks/{lockname}")); put.Value = Google.Protobuf.ByteString.CopyFromUtf8(@lock.Id.ToString()); put.Lease = lease.ID; _client.Put(put); //add to cache and srv . _client.Put($"/locks/{lockname}", @lock.Id.ToString()); lock (_lockerList) { _lockerList.Add(new ZkLockerWatcher() { Event = null, Id = @lock.Id, Name = lockname }); } } catch (Exception ex) { lock (_client) { _client = bestClient(_clients); } @lock.Result = LockResult.Fail; } } return(@lock); }
public UnLockResult UnLock(string lockname, long Id) { ZkLockerWatcher watcher = null; bool localhas = false; bool srvhas = false; lock (_lockerList) { var locallst = _lockerList.Where(c => c.Name == lockname).ToList(); if (locallst.Count > 0) { if (locallst.FirstOrDefault().Id != Id) { return(UnLockResult.NotSameLockId); } else { watcher = locallst.FirstOrDefault(); localhas = true; } } } if (!localhas) { Etcdserverpb.RangeResponse oldlockers = null; try { oldlockers = _client.GetAsync($"/locks/{lockname}").Result; } catch (Exception ex) { lock (_client) { _client = bestClient(_clients); } return(UnLockResult.Fail); } if (oldlockers?.Kvs.Count > 0) { if (long.Parse(oldlockers.Kvs[0].Value.ToStringUtf8()) != Id) { return(UnLockResult.NotSameLockId); } else { srvhas = true; } } } if (localhas || srvhas) { long deled = 0; try { deled = _client.DeleteRangeAsync($"/locks/{lockname}").Result.Deleted; if (localhas) { lock (_lockerList) { _lockerList.RemoveWhere(c => c.Id == Id && c.Name == lockname); } } } catch (Exception ex) { lock (_client) { _client = bestClient(_clients); } return(UnLockResult.Fail); } if (deled > 0) { return(UnLockResult.Success); } else { return(UnLockResult.NotExists); } } else { return(UnLockResult.NotExists); } }