public void SetWatch(long watchId, Watch watch) => _watches.TryAdd(watchId, watch);
public Watch CreateWatch( bool ads, DiscoveryRequest request, ISet <string>?knownResourceNames, Action <Response> responseCallback) { var group = _hash(request.Node); // even though we're modifying, we take a readLock to allow multiple watches to be created in parallel since it // doesn't conflict _rwLock.EnterReadLock(); try { var status = _statuses.GetOrAdd(group, g => new CacheStatusInfo <T>(group)); status.SetLastWatchRequestTime(DateTimeOffset.UtcNow.Ticks); _snapshots.TryGetValue(group, out Snapshot? snapshot); var version = snapshot == null ? string.Empty : snapshot.GetVersion(request.TypeUrl, request.ResourceNames); var watch = new Watch(ads, request, responseCallback); if (snapshot != null) { var requestedResources = ImmutableHashSet.CreateRange(request.ResourceNames); var newResourceHints = requestedResources.Except(knownResourceNames); // If the request is asking for resources we haven't sent to the proxy yet, see if we have additional resources. if (newResourceHints.Any()) { // If any of the newly requested resources are in the snapshot respond immediately. If not we'll fall back to // version comparisons. if (snapshot.GetResources(request.TypeUrl).Keys.Any(newResourceHints.Contains)) { this.Respond(watch, snapshot, group); return(watch); } } } // If the requested version is up-to-date or missing a response, leave an open watch. if (snapshot == null || request.VersionInfo.Equals(version)) { long watchId = Interlocked.Increment(ref _watchCount); Logger.LogDebug("open watch {0} for {1}[{2}] from node {3} for version {4}", watchId, request.TypeUrl, string.Join(", ", request.ResourceNames), group, request.VersionInfo); status.SetWatch(watchId, watch); watch.SetStop(() => status.RemoveWatch(watchId)); return(watch); } // Otherwise, the watch may be responded immediately var responded = this.Respond(watch, snapshot, group); if (!responded) { long watchId = Interlocked.Increment(ref _watchCount); Logger.LogDebug("did not respond immediately, leaving open watch {0} for {1}[{2}] from node {3} for version {4}", watchId, request.TypeUrl, string.Join(", ", request.ResourceNames), group, request.VersionInfo); status.SetWatch(watchId, watch); watch.SetStop(() => status.RemoveWatch(watchId)); } return(watch); } finally { _rwLock.ExitReadLock(); } }