protected override async Task OnOpenAsync() { bool openedOK = false; int retryCount = 0; Exception lastException = null; do { try { await OpenClientsAsync().ConfigureAwait(false); openedOK = true; } catch (Exception e) { lastException = e; ProcessorEventSource.Log.PartitionPumpWarning( this.Host.HostName, this.PartitionContext.PartitionId, "Failure creating client or receiver, retrying", e.ToString()); // Don't retry if we already lost the lease. if (e is ReceiverDisconnectedException) { break; } retryCount++; } }while (!openedOK && (retryCount < 5)); if (!openedOK) { // IEventProcessor.onOpen is called from the base PartitionPump and must have returned in order for execution to reach here, // so we can report this error to it instead of the general error handler. await this.Processor.ProcessErrorAsync(this.PartitionContext, lastException).ConfigureAwait(false); this.PumpStatus = PartitionPumpStatus.OpenFailed; } if (this.PumpStatus == PartitionPumpStatus.Opening) { this.partitionReceiveHandler = new PartitionReceiveHandler(this); // IEventProcessor.OnOpen is called from the base PartitionPump and must have returned in order for execution to reach here, // meaning it is safe to set the handler and start calling IEventProcessor.OnEvents. // Set the status to running before setting the client handler, so the IEventProcessor.OnEvents can never race and see status != running. this.PumpStatus = PartitionPumpStatus.Running; this.partitionReceiver.SetReceiveHandler( this.partitionReceiveHandler, this.Host.EventProcessorOptions.InvokeProcessorAfterReceiveTimeout); } if (this.PumpStatus == PartitionPumpStatus.OpenFailed) { this.PumpStatus = PartitionPumpStatus.Closing; await this.CleanUpClientsAsync().ConfigureAwait(false); this.PumpStatus = PartitionPumpStatus.Closed; } }
protected override async Task OnOpenAsync() { bool openedOK = false; int retryCount = 0; Exception lastException = null; do { try { await OpenClientsAsync().ConfigureAwait(false); openedOK = true; } catch (Exception e) { lastException = e; if (e is ReceiverDisconnectedException) { // TODO Assuming this is due to a receiver with a higher epoch. // Is there a way to be sure without checking the exception text? ProcessorEventSource.Log.PartitionPumpWarning( this.Host.Id, this.PartitionContext.PartitionId, "Receiver disconnected on create, bad epoch?", e.ToString()); // If it's a bad epoch, then retrying isn't going to help. break; } else { ProcessorEventSource.Log.PartitionPumpWarning( this.Host.Id, this.PartitionContext.PartitionId, "Failure creating client or receiver, retrying", e.ToString()); retryCount++; } } }while (!openedOK && (retryCount < 5)); if (!openedOK) { // IEventProcessor.onOpen is called from the base PartitionPump and must have returned in order for execution to reach here, // so we can report this error to it instead of the general error handler. await this.Processor.ProcessErrorAsync(this.PartitionContext, lastException).ConfigureAwait(false); this.PumpStatus = PartitionPumpStatus.OpenFailed; } if (this.PumpStatus == PartitionPumpStatus.Opening) { this.partitionReceiveHandler = new PartitionReceiveHandler(this); // IEventProcessor.OnOpen is called from the base PartitionPump and must have returned in order for execution to reach here, // meaning it is safe to set the handler and start calling IEventProcessor.OnEvents. // Set the status to running before setting the client handler, so the IEventProcessor.OnEvents can never race and see status != running. this.PumpStatus = PartitionPumpStatus.Running; this.partitionReceiver.SetReceiveHandler(this.partitionReceiveHandler); } if (this.PumpStatus == PartitionPumpStatus.OpenFailed) { this.PumpStatus = PartitionPumpStatus.Closing; await this.CleanUpClientsAsync(); this.PumpStatus = PartitionPumpStatus.Closed; } }