public virtual RefreshResponseInfo Refresh(RefreshInfo refreshInfo) { if (refreshInfo == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("refreshInfo", System.ServiceModel.SR.GetString("PeerNullRefreshInfo")); } this.ThrowIfClosed("Refresh"); if ((!refreshInfo.HasBody() || string.IsNullOrEmpty(refreshInfo.MeshId)) || (refreshInfo.RegistrationId == Guid.Empty)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("refreshInfo", System.ServiceModel.SR.GetString("PeerInvalidMessageBody", new object[] { refreshInfo })); } RefreshResult registrationNotFound = RefreshResult.RegistrationNotFound; RegistrationEntry entry = null; MeshEntry meshEntry = this.GetMeshEntry(refreshInfo.MeshId, false); LiteLock liteLock = null; if (meshEntry != null) { try { LiteLock.Acquire(out liteLock, meshEntry.Gate); if (!meshEntry.EntryTable.TryGetValue(refreshInfo.RegistrationId, out entry)) { return(new RefreshResponseInfo(this.RefreshInterval, registrationNotFound)); } lock (entry) { if (entry.State == RegistrationState.OK) { entry.Expires = DateTime.UtcNow + this.RefreshInterval; registrationNotFound = RefreshResult.Success; } } } finally { LiteLock.Release(liteLock); } } return(new RefreshResponseInfo(this.RefreshInterval, registrationNotFound)); }
public virtual RegisterResponseInfo Register(Guid clientId, string meshId, PeerNodeAddress address) { Guid registrationId = Guid.NewGuid(); DateTime expiry = DateTime.UtcNow + RefreshInterval; RegistrationEntry entry = null; MeshEntry meshEntry = null; lock (ThisLock) { entry = new RegistrationEntry(clientId, registrationId, meshId, expiry, address); meshEntry = GetMeshEntry(meshId); if (meshEntry.Service2EntryTable.ContainsKey(address.ServicePath)) { PeerExceptionHelper.ThrowInvalidOperation_DuplicatePeerRegistration(address.ServicePath); } LiteLock ll = null; try { // meshEntry.gate can be held by this thread for write if this is coming from update // else MUST not be held at all. if (!meshEntry.Gate.IsWriterLockHeld) { LiteLock.Acquire(out ll, meshEntry.Gate, true); } meshEntry.EntryTable.Add(registrationId, entry); meshEntry.EntryList.Add(entry); meshEntry.Service2EntryTable.Add(address.ServicePath, entry); } finally { if (ll != null) { LiteLock.Release(ll); } } } return(new RegisterResponseInfo(registrationId, RefreshInterval)); }
public virtual RegisterResponseInfo Update(UpdateInfo updateInfo) { if (updateInfo == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("updateInfo", System.ServiceModel.SR.GetString("PeerNullRegistrationInfo")); } this.ThrowIfClosed("Update"); if ((!updateInfo.HasBody() || string.IsNullOrEmpty(updateInfo.MeshId)) || (updateInfo.NodeAddress == null)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("updateInfo", System.ServiceModel.SR.GetString("PeerInvalidMessageBody", new object[] { updateInfo })); } Guid registrationId = updateInfo.RegistrationId; MeshEntry meshEntry = this.GetMeshEntry(updateInfo.MeshId); LiteLock liteLock = null; if ((updateInfo.RegistrationId == Guid.Empty) || (meshEntry == null)) { return(this.Register(updateInfo.ClientId, updateInfo.MeshId, updateInfo.NodeAddress)); } try { RegistrationEntry entry; LiteLock.Acquire(out liteLock, meshEntry.Gate); if (!meshEntry.EntryTable.TryGetValue(updateInfo.RegistrationId, out entry)) { return(this.Register(updateInfo.ClientId, updateInfo.MeshId, updateInfo.NodeAddress)); } lock (entry) { entry.Address = updateInfo.NodeAddress; entry.Expires = DateTime.UtcNow + this.RefreshInterval; } } finally { LiteLock.Release(liteLock); } return(new RegisterResponseInfo(registrationId, this.RefreshInterval)); }
public virtual void Unregister(UnregisterInfo unregisterInfo) { if (unregisterInfo == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("unregisterinfo", SR.GetString(SR.PeerNullRegistrationInfo)); } ThrowIfClosed("Unregister"); if (!unregisterInfo.HasBody() || String.IsNullOrEmpty(unregisterInfo.MeshId) || unregisterInfo.RegistrationId == Guid.Empty) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("unregisterInfo", SR.GetString(SR.PeerInvalidMessageBody, unregisterInfo)); } RegistrationEntry registration = null; MeshEntry meshEntry = GetMeshEntry(unregisterInfo.MeshId, false); //there could be a ---- that two different threads could be working on the same entry //we wont optimize for that case. LiteLock ll = null; try { LiteLock.Acquire(out ll, meshEntry.Gate, true); if (!meshEntry.EntryTable.TryGetValue(unregisterInfo.RegistrationId, out registration)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("unregisterInfo", SR.GetString(SR.PeerInvalidMessageBody, unregisterInfo)); } meshEntry.EntryTable.Remove(unregisterInfo.RegistrationId); meshEntry.EntryList.Remove(registration); meshEntry.Service2EntryTable.Remove(registration.Address.ServicePath); registration.State = RegistrationState.Deleted; } finally { LiteLock.Release(ll); } }
public static void Acquire(out LiteLock liteLock, ReaderWriterLock locker, bool forWrite) { LiteLock theLock = new LiteLock(locker, forWrite); try { } finally { if (forWrite) { locker.AcquireWriterLock(theLock.timeout); } else { locker.AcquireReaderLock(theLock.timeout); } liteLock = theLock; } }
public static void Acquire(out LiteLock liteLock, ReaderWriterLock locker) { Acquire(out liteLock, locker, false); }
public static void Release(LiteLock liteLock) { if (liteLock == null) { return; } if (liteLock.forWrite) { liteLock.locker.ReleaseWriterLock(); } else { Fx.Assert(!liteLock.upgraded, "Can't release while upgraded!"); liteLock.locker.ReleaseReaderLock(); } }
public static void Acquire(out LiteLock liteLock, ReaderWriterLock locker) { Acquire(out liteLock, locker, false); }
public virtual ResolveResponseInfo Resolve(ResolveInfo resolveInfo) { if (resolveInfo == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("resolveInfo", SR.GetString(SR.PeerNullResolveInfo)); } ThrowIfClosed("Resolve"); if (!resolveInfo.HasBody()) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("resolveInfo", SR.GetString(SR.PeerInvalidMessageBody, resolveInfo)); } int currentCount = 0; int index = 0; int maxEntries = resolveInfo.MaxAddresses; ResolveResponseInfo response = new ResolveResponseInfo(); List <PeerNodeAddress> results = new List <PeerNodeAddress>(); List <RegistrationEntry> entries = null; PeerNodeAddress address; RegistrationEntry entry; MeshEntry meshEntry = GetMeshEntry(resolveInfo.MeshId, false); if (meshEntry != null) { LiteLock ll = null; try { LiteLock.Acquire(out ll, meshEntry.Gate); entries = meshEntry.EntryList; if (entries.Count <= maxEntries) { foreach (RegistrationEntry e in entries) { results.Add(e.Address); } } else { Random random = new Random(); while (currentCount < maxEntries) { index = random.Next(entries.Count); entry = entries[index]; Fx.Assert(entry.State == RegistrationState.OK, "A deleted registration is still around!"); address = entry.Address; if (!results.Contains(address)) { results.Add(address); } currentCount++; } } } finally { LiteLock.Release(ll); } } response.Addresses = results.ToArray(); return(response); }