private async Task OnRuntimeInitializeStart(CancellationToken cancellation) { // Find the currently known cluster members first, before interrogating Kubernetes await _clusterMembershipService.Refresh(); var snapshot = _clusterMembershipService.CurrentSnapshot.Members; // Find the pods which correspond to this cluster var pods = await _client.ListNamespacedPodAsync( namespaceParameter : _podNamespace, labelSelector : _podLabelSelector, cancellationToken : cancellation); var clusterPods = new HashSet <string>(); clusterPods.Add(_podName); foreach (var pod in pods.Items) { clusterPods.Add(pod.Metadata.Name); } HashSet <string> known = new HashSet <string>(); var knownMap = new Dictionary <string, ClusterMember>(); known.Add(_podName); foreach (var member in snapshot.Values) { if (member.Status == SiloStatus.Dead) { continue; } known.Add(member.Name); knownMap[member.Name] = member; } var unknown = new List <string>(clusterPods.Except(known)); unknown.Sort(); foreach (var pod in unknown) { _logger.LogWarning("Pod {PodName} does not correspond to any known silos", pod); // Delete the pod once it has been active long enough? } var unmatched = new List <string>(known.Except(clusterPods)); unmatched.Sort(); foreach (var pod in unmatched) { var siloAddress = knownMap[pod]; _logger.LogWarning("Silo {SiloAddress} does not correspond to any known pod. Marking it as dead.", siloAddress); await _clusterMembershipService.TryKill(siloAddress.SiloAddress); } // Start monitoring loop ThreadPool.UnsafeQueueUserWorkItem(_ => _runTask = Task.WhenAll(Task.Run(MonitorOrleansClustering), Task.Run(MonitorKubernetesPods)), null); }