예제 #1
0
        /// <summary>
        /// Check if the partition primary has changed, we do this by comparing the Era.
        /// </summary>
        /// <param name="normalizedKey">PartitionKey</param>
        /// <param name="timeout">timeout for this operation to complete</param>
        /// <returns>false if same, true otherwise</returns>
        internal async Task <bool> HasPartitionEraChanged(PartitionKey normalizedKey, TimeSpan timeout)
        {
            PartitionInfo existingEndpoint = null;

            lock (this.resolvedEndpointsLock)
            {
                var endpointFound = this.resolvedEndpoints.TryGetValue(normalizedKey, out existingEndpoint);
                Diagnostics.Assert(
                    endpointFound,
                    "{0} resolvedEndpoints found no existing endpoint in SessionConnectionManager.HasEnpointChanged, for Key: {1}",
                    this.streamManager.TraceType,
                    normalizedKey);
            }

            var currentEndPoint = await this.GetEndpointAsync(normalizedKey, timeout);

            return(currentEndPoint.Era != existingEndpoint.Era);
        }
예제 #2
0
        /// <summary>
        /// Get the partition end point info for the given partition key
        /// Exceptions this may throw TimeoutException, FabricObjectClosedException, more to be discovered
        /// </summary>
        /// <param name="key">Get end point for this given partition key</param>
        /// <param name="timeout">Timeout for the operation to complete</param>
        /// <returns>Partition Body</returns>
        private async Task <PartitionInfo> GetEndpointAsync(PartitionKey key, TimeSpan timeout)
        {
            PartitionInfo endpoint = null;

            var parentName       = key.ServiceInstanceName;
            var propertyName     = key.PublishedPropertyName("TransportEndpoint");
            var getEndpointDelay = 0;
            var getCompleted     = false;

            // TODO: revisit the timeout behavior of GetPropertyAsync to clarify and adjust accordingly
            var remainingTimeout = timeout;

            FabricEvents.Events.GetEndpointProperty("Start@" + this.streamManager.TraceType, key.ToString(), "");

            while (!getCompleted)
            {
                var beforeGetPropertyAsync = DateTime.UtcNow;
                try
                {
                    var property = await this.client.PropertyManager.GetPropertyAsync(parentName, propertyName);

                    endpoint     = property.GetValue <byte[]>().Deserialize <PartitionInfo>();
                    getCompleted = true;
                }
                catch (FabricElementNotFoundException)
                {
                    FabricEvents.Events.GetEndpointProperty("NotFound.Retrying@" + this.streamManager.TraceType, key.ToString(), "");
                }
                catch (FabricTransientException)
                {
                    FabricEvents.Events.GetEndpointProperty("TransientError.Retrying@" + this.streamManager.TraceType, key.ToString(), "");
                }
                catch (TimeoutException)
                {
                    FabricEvents.Events.GetEndpointProperty("Timeout.Retrying@" + this.streamManager.TraceType, key.ToString(), "");
                }
                catch (OperationCanceledException)
                {
                    FabricEvents.Events.GetEndpointProperty("Canceled.Retrying@" + this.streamManager.TraceType, key.ToString(), "");
                }
                catch (FabricException fabricException)
                {
                    if (fabricException.ErrorCode == FabricErrorCode.CommunicationError)
                    {
                        FabricEvents.Events.GetEndpointProperty("CommunicationError.Retrying@" + this.streamManager.TraceType, key.ToString(), "");
                    }
                    else
                    {
                        Tracing.WriteExceptionAsError("RegisterEndpointAsync.GetPropertyAsync.UnrecoverableError", fabricException, "{0}", this.tracer);
                        throw;
                    }
                }
                catch (Exception otherException)
                {
                    Tracing.WriteExceptionAsError("RegisterEndpointAsync.GetPropertyAsync.UnrecoverableError", otherException, "{0}", this.tracer);
                    throw;
                }

                if (endpoint == null)
                {
                    var afterGetPropertyAsync = DateTime.UtcNow;

                    remainingTimeout = TimeoutHandler.UpdateTimeout(remainingTimeout, beforeGetPropertyAsync, afterGetPropertyAsync);

                    getEndpointDelay = getEndpointDelay >= StreamConstants.MaxDelayForValidSessionEndpoint
                        ? StreamConstants.MaxDelayForValidSessionEndpoint
                        : getEndpointDelay + StreamConstants.BaseDelayForValidSessionEndpoint;
                    await Task.Delay(getEndpointDelay);
                }
            }

            bool replaced;

            // Update resolved end points cache
            lock (this.resolvedEndpointsLock)
            {
                replaced = this.resolvedEndpoints.Remove(key);
                this.resolvedEndpoints.Add(key, endpoint);
            }

            if (replaced)
            {
                FabricEvents.Events.GetEndpointProperty("FinishReplaced@" + this.streamManager.TraceType, key.ToString(), endpoint.ToString());
            }
            else
            {
                FabricEvents.Events.GetEndpointProperty("FinishNew@" + this.streamManager.TraceType, key.ToString(), endpoint.ToString());
            }

            return(endpoint);
        }
예제 #3
0
        /// <summary>
        /// Register my(this instance of) service endpoint info (endpoint and era)
        /// This method is called only once at startup when the service becomes primary
        /// </summary>
        /// <param name="key">Partition to register</param>
        /// <param name="endpoint">Endpoint of the partition</param>
        /// <param name="era">Era of the partition</param>
        /// <returns></returns>
        internal async Task RegisterPartitionAsync(PartitionKey key, string endpoint, Guid era)
        {
            var parentName   = key.ServiceInstanceName;
            var propertyName = key.PublishedPropertyName("TransportEndpoint");
            var endPointInfo = new PartitionInfo(endpoint, era);

            FabricEvents.Events.RegisterEndpointProperty("Start@" + this.streamManager.TraceType, key.ToString(), endPointInfo.ToString());


            await this.RevokeEnpointAsync(key);

            var putSuccess = false;

            while (!putSuccess)
            {
                try
                {
                    await this.client.PropertyManager.PutPropertyAsync(parentName, propertyName, endPointInfo.Serialize());

                    putSuccess = true;
                }
                catch (FabricTransientException)
                {
                    FabricEvents.Events.RegisterEndpointProperty(
                        "TransientException.Retrying@" + this.streamManager.TraceType,
                        key.ToString(),
                        endPointInfo.ToString());
                }
                catch (TimeoutException)
                {
                    FabricEvents.Events.RegisterEndpointProperty(
                        "Timeout.Retrying@" + this.streamManager.TraceType,
                        key.ToString(),
                        endPointInfo.ToString());
                }
                catch (OperationCanceledException)
                {
                    FabricEvents.Events.RegisterEndpointProperty(
                        "Canceled.Retrying@" + this.streamManager.TraceType,
                        key.ToString(),
                        endPointInfo.ToString());
                }
                catch (FabricException fabricException)
                {
                    if (fabricException.ErrorCode == FabricErrorCode.CommunicationError)
                    {
                        FabricEvents.Events.RegisterEndpointProperty(
                            "CommunicationError.Retrying@" + this.streamManager.TraceType,
                            key.ToString(),
                            endPointInfo.ToString());
                    }
                    else
                    {
                        Tracing.WriteExceptionAsError("RegisterEndpointAsync.PutPropertyAsync.UnrecoverableError", fabricException, "{0}", this.tracer);
                        throw;
                    }
                }
                catch (Exception otherException)
                {
                    Tracing.WriteExceptionAsError("RegisterEndpointAsync.PutPropertyAsync.UnrecoverableError", otherException, "{0}", this.tracer);
                    throw;
                }
            }

            FabricEvents.Events.RegisterEndpointProperty("Finish@" + this.streamManager.TraceType, key.ToString(), endPointInfo.ToString());
        }