/// <summary> /// Create a <seealso cref="ReplayMerge"/> to manage the merging of a replayed stream and switching to live stream as /// appropriate. /// </summary> /// <param name="subscription"> to use for the replay and live stream. Must be a multi-destination subscription. </param> /// <param name="archive"> to use for the replay. </param> /// <param name="replayChannel"> to use for the replay. </param> /// <param name="replayDestination"> to send the replay to and the destination added by the <seealso cref="Subscription"/>. </param> /// <param name="liveDestination"> for the live stream and the destination added by the <seealso cref="Subscription"/>. </param> /// <param name="recordingId"> for the replay. </param> /// <param name="startPosition"> for the replay. </param> public ReplayMerge(Subscription subscription, AeronArchive archive, string replayChannel, string replayDestination, string liveDestination, long recordingId, long startPosition) { var subscriptionChannelUri = ChannelUri.Parse(subscription.Channel); if (!Context.MDC_CONTROL_MODE_MANUAL.Equals(subscriptionChannelUri.Get(Context.MDC_CONTROL_MODE_PARAM_NAME)) ) { throw new ArgumentException("Subscription channel must be manual control mode: mode=" + subscriptionChannelUri.Get(Context.MDC_CONTROL_MODE_PARAM_NAME) ); } this.archive = archive; this.subscription = subscription; this.replayDestination = replayDestination; this.replayChannel = replayChannel; this.liveDestination = liveDestination; this.recordingId = recordingId; this.startPosition = startPosition; this.liveAddThreshold = LIVE_ADD_THRESHOLD; this.replayRemoveThreshold = REPLAY_REMOVE_THRESHOLD; subscription.AddDestination(replayDestination); }
private int AwaitUpdatedRecordingPosition() { int workCount = 0; if (NULL_VALUE == activeCorrelationId) { long correlationId = archive.Ctx().AeronClient().NextCorrelationId(); if (archive.Proxy().GetRecordingPosition(recordingId, correlationId, archive.ControlSessionId())) { activeCorrelationId = correlationId; workCount += 1; } } else if (PollForResponse(archive, activeCorrelationId)) { nextTargetPosition = PolledRelevantId(archive); if (AeronArchive.NULL_POSITION == nextTargetPosition) { long correlationId = archive.Ctx().AeronClient().NextCorrelationId(); if (archive.Proxy() .GetRecordingPosition(recordingId, correlationId, archive.ControlSessionId())) { activeCorrelationId = correlationId; } } else { State nextState = State.AWAIT_CATCH_UP; if (null != image) { long position = image.Position; if (ShouldAddLiveDestination(position)) { subscription.AddDestination(liveDestination); isLiveAdded = true; } else if (ShouldStopAndRemoveReplay(position)) { nextState = State.AWAIT_STOP_REPLAY; } } activeCorrelationId = NULL_VALUE; SetState(nextState); } workCount += 1; } return(workCount); }