/// <summary>Gets a detailed grain report from a specified silo</summary> /// <param name="grainFactory">The grain factory.</param> /// <param name="grainId">The grain id we are requesting information from</param> /// <param name="siloHandle">The target silo that should provide this information from it's cache</param> internal static Task <DetailedGrainReport> GetDetailedGrainReport(IInternalGrainFactory grainFactory, GrainId grainId, SiloHandle siloHandle) { var siloControl = grainFactory.GetSystemTarget <ISiloControl>(Constants.SiloControlId, siloHandle.ProxyAddress); return(siloControl.GetDetailedGrainReport(grainId)); }
private IClusterTypeManager GetTypeManager(SiloAddress destination, IInternalGrainFactory grainFactory) { return(grainFactory.GetSystemTarget <IClusterTypeManager>(Constants.TypeManagerId, destination)); }
private async Task <bool> UpdateManifest(ClusterMembershipSnapshot clusterMembership) { var existingManifest = _current; var builder = existingManifest.Silos.ToBuilder(); var modified = false; // First, remove defunct entries. foreach (var entry in existingManifest.Silos) { var address = entry.Key; var status = clusterMembership.GetSiloStatus(address); if (address.Equals(_localSiloAddress)) { // The local silo is always present in the manifest. continue; } if (status == SiloStatus.None || status == SiloStatus.Dead) { builder.Remove(address); modified = true; } } // Next, fill missing entries. var tasks = new List <Task <(SiloAddress Key, SiloManifest Value, Exception Exception)> >(); foreach (var entry in clusterMembership.Members) { var member = entry.Value; if (member.SiloAddress.Equals(_localSiloAddress)) { // The local silo is always present in the manifest. continue; } if (existingManifest.Silos.ContainsKey(member.SiloAddress)) { // Manifest has already been retrieved for the cluster member. continue; } if (member.Status != SiloStatus.Active) { // If the member is not yet active, it may not be ready to process requests. continue; } tasks.Add(GetManifest(member.SiloAddress)); async Task <(SiloAddress, SiloManifest, Exception)> GetManifest(SiloAddress siloAddress) { try { // Get the manifest from the remote silo. var remoteManifestProvider = _grainFactory.GetSystemTarget <ISiloManifestSystemTarget>(Constants.ManifestProviderType, member.SiloAddress); var manifest = await remoteManifestProvider.GetSiloManifest(); return(siloAddress, manifest, null); } catch (Exception exception) { return(siloAddress, null, exception); } } } var fetchSuccess = true; await Task.WhenAll(tasks); foreach (var task in tasks) { var result = await task; if (result.Exception is Exception exception) { fetchSuccess = false; _logger.LogWarning(exception, "Error retrieving silo manifest for silo {SiloAddress}", result.Key); } else { modified = true; builder[result.Key] = result.Value; } } // Regardless of success or failure, update the manifest if it has been modified. var version = new MajorMinorVersion(clusterMembership.Version.Value, existingManifest.Version.Minor + 1); if (modified) { return(_updates.TryPublish(new ClusterManifest(version, builder.ToImmutable())) && fetchSuccess); } return(fetchSuccess); }