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);
        }