public GlobalSingleInstanceResponseOutcome(OutcomeState state, AddressAndTag remoteOwnerAddress, string remoteOwnerCluster) { this.State = state; this.RemoteOwnerAddress = remoteOwnerAddress; this.RemoteOwnerCluster = remoteOwnerCluster; }
/// <summary> /// Adds a new activation to the directory partition /// </summary> /// <param name="grain"></param> /// <param name="activation"></param> /// <param name="silo"></param> /// <param name="registrationStatus"></param> /// <returns>The registered ActivationAddress and version associated with this directory mapping</returns> internal virtual AddressAndTag AddSingleActivation(GrainId grain, ActivationId activation, SiloAddress silo, GrainDirectoryEntryStatus registrationStatus) { if (log.IsVerbose3) log.Verbose3("Adding single activation for grain {0}{1}{2}", silo, grain, activation); AddressAndTag result = new AddressAndTag(); if (!IsValidSilo(silo)) return result; lock (lockable) { if (!partitionData.ContainsKey(grain)) { partitionData[grain] = new GrainInfo(); } var grainInfo = partitionData[grain]; result.Address = grainInfo.AddSingleActivation(grain, activation, silo, registrationStatus); result.VersionTag = grainInfo.VersionTag; } return result; }
private static GlobalSingleInstanceResponseOutcome? GetOutcome(ICollection<RemoteClusterActivationResponse> responses, GrainId grainId, Logger logger, bool hasPendingResponses) { if (!hasPendingResponses && responses.All(res => res.ResponseStatus == ActivationResponseStatus.Pass)) { // All passed, or no other clusters exist return GlobalSingleInstanceResponseOutcome.Succeed; } var ownerResponses = responses .Where(res => res.ResponseStatus == ActivationResponseStatus.Failed && res.Owned == true).ToList(); if (ownerResponses.Count > 0) { if (ownerResponses.Count > 1) logger.Warn((int)ErrorCode.GlobalSingleInstance_MultipleOwners, "GSIP:Req {0} Unexpected error occured. Multiple Owner Replies.", grainId); return new GlobalSingleInstanceResponseOutcome(OutcomeState.RemoteOwner, ownerResponses[0].ExistingActivationAddress, ownerResponses[0].ClusterId); } // are all responses here or have failed? if (!hasPendingResponses) { // determine best candidate var candidates = responses .Where(res => res.ResponseStatus == ActivationResponseStatus.Failed && res.ExistingActivationAddress.Address != null) .ToList(); AddressAndTag remoteOwner = new AddressAndTag(); string remoteOwnerCluster = null; foreach (var res in candidates) { if (remoteOwner.Address == null || MultiClusterUtils.ActivationPrecedenceFunc(grainId, res.ClusterId, remoteOwnerCluster)) { remoteOwner = res.ExistingActivationAddress; remoteOwnerCluster = res.ClusterId; } } var outcome = remoteOwner.Address != null ? OutcomeState.RemoteOwnerLikely : OutcomeState.Inconclusive; return new GlobalSingleInstanceResponseOutcome(outcome, remoteOwner, remoteOwnerCluster); } return null; }