public OperationFetcher(IStateReplicator stateReplicator, OperationProcessorInfo copyOperationProcessor, OperationProcessorInfo replicationOperationProcessor, bool drainQueuesInParallel)
        {
            Requires.Argument("partition", stateReplicator).NotNull();
            Requires.Argument("copyOperationProcessor", copyOperationProcessor).NotNull();
            Requires.Argument("replicationOperationProcessor", replicationOperationProcessor).NotNull();

            if (copyOperationProcessor.Callback == null)
            {
                throw new ArgumentException("copyOperationProcessor.Callback cannot be null");
            }

            if (replicationOperationProcessor.Callback == null)
            {
                throw new ArgumentException("replicationOperationProcessor.Callback cannot be null");
            }

            this.copyOperationQueue = new OperationQueue(() => stateReplicator.GetCopyStream(), copyOperationProcessor)
            {
                Name = "CopyQueue"
            };
            this.replicationOperationQueue = new OperationQueue(() => stateReplicator.GetReplicationStream(), replicationOperationProcessor)
            {
                Name = "ReplicationQueue"
            };
            this.drainQueuesInParallel = drainQueuesInParallel;
            this.role = ReplicaRole.None;
        }
 public void Open(
     RecoveredOrCopiedCheckpointLsn recoveredOrCopiedCheckpointLsn,
     RoleContextDrainState roleContextDrainState,
     OperationProcessor recordsProcessor,
     IStateReplicator fabricReplicator,
     IBackupManager backupManager,
     CheckpointManager checkpointManager,
     TransactionManager transactionManager,
     ReplicatedLogManager replicatedLogManager,
     IStateManager stateManager,
     TransactionalReplicatorSettings replicatorSettings,
     RecoveryManager recoveryManager,
     ITracer tracer)
 {
     this.recoveredOrCopiedCheckpointLsn = recoveredOrCopiedCheckpointLsn;
     this.recoveryManager       = recoveryManager;
     this.replicatorSettings    = replicatorSettings;
     this.stateManager          = stateManager;
     this.tracer                = tracer;
     this.roleContextDrainState = roleContextDrainState;
     this.recordsProcessor      = recordsProcessor;
     this.fabricReplicator      = fabricReplicator;
     this.backupManager         = backupManager;
     this.transactionManager    = transactionManager;
     this.checkpointManager     = checkpointManager;
     this.replicatedLogManager  = replicatedLogManager;
 }
        public OperationReplicator(IStateReplicator replicator, StateProvider stateProvider, Logger logger, Serializer serializer)
        {
            this.replicator    = replicator;
            this.stateProvider = stateProvider;
            this.logger        = logger;
            this.serializer    = serializer;
            var options = new ExecutionDataflowBlockOptions {
                MaxDegreeOfParallelism = 1, BoundedCapacity = 128
            };

            this.replicationWorker = new ActionBlock <ReplicationRequest>(this.InitiateOrderedReplication, options);
            this.completionWorker  = new ActionBlock <ReplicationRequest>(this.CompleteOrderedReplication, options);
        }
Exemple #4
0
 public void Open(
     ITracer tracer,
     Func <bool, BeginCheckpointLogRecord> appendCheckpointCallback,
     IndexingLogRecord currentHead,
     RoleContextDrainState roleContextDrainState,
     IStateReplicator fabricReplicator)
 {
     this.appendCheckpointCallback = appendCheckpointCallback;
     this.RoleContextDrainState    = roleContextDrainState;
     this.fabricReplicator         = fabricReplicator;
     this.tracer = tracer;
     this.CurrentLogHeadRecord = currentHead;
     this.replicationSerializationBinaryWritersPoolClearTimer.Change(Constants.ReplicationWriteMemoryStreamsBufferPoolCleanupMilliseconds, Timeout.Infinite);
 }
Exemple #5
0
        /// <inheritdoc/>
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            // Find a better log directory
            this.operationLoggerPrimary = new OperationLogger(this.Context.CodePackageActivationContext.LogDirectory);

            FabricReplicator replicator = null;

            while ((replicator = this.serviceContext.Replicator) == null)
            {
                await Task.Delay(125).ConfigureAwait(false);
            }

            this.stateReplicator         = replicator.StateReplicator;
            this.cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

            var unusedTask = Task.Run(this.ProcessIncomingRequests);

            ServiceEventSource.Current.ServiceMessage(this.Context, "Replicator is ready");

            try
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    ServiceEventSource.Current.ServiceMessage(
                        this.Context,
                        "RunAsync alive: {0} - pending operations {1} LSN {2}",
                        DateTime.UtcNow,
                        this.pendingOperations.Count,
                        this.lastSequenceNumber);
                    await Task.Delay(1000 * 30, cancellationToken).ConfigureAwait(false);
                }
            }
            catch (TaskCanceledException)
            {
            }
        }
        /// <summary>
        /// Opens the replica.
        /// </summary>
        /// <param name="openMode">Replica open mode (new or existent).</param>
        /// <param name="partition">Stateful partition object.</param>
        /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param>
        /// <returns></returns>
        public virtual async Task <IReplicator> OpenAsync(ReplicaOpenMode openMode, IStatefulServicePartition partition, CancellationToken cancellationToken)
        {
            //
            // Check arguments.
            //
            if (null == partition)
            {
                AppTrace.TraceSource.WriteError("StatefulServiceReplica.Open", "{0}", this.ToString());
                throw new ArgumentNullException("partition");
            }

            //
            // Perform local open functionality.
            //
            AppTrace.TraceSource.WriteNoise("StatefulServiceReplica.Open", "{0}", this.ToString());

            //
            // Set partition related members.
            //
            this.servicePartition      = partition;
            this.serviceGroupPartition = partition as IServiceGroupPartition;
            this.servicePartitionEx    = partition as IStatefulServicePartitionEx;

            //
            // Create an implementation of the state provider broker.
            //
            this.stateProviderBroker = this.CreateStateProviderBroker();
            if (null == this.stateProviderBroker)
            {
                AppTrace.TraceSource.WriteError("StatefulServiceReplica.Open", "{0} invalid state provider broker", this.ToString());
                throw new InvalidOperationException();
            }

            //
            // Extract state providers.
            //
            this.stateProvider              = this.stateProviderBroker as IStateProvider;
            this.atomicGroupStateProvider   = this.stateProviderBroker as IAtomicGroupStateProvider;
            this.atomicGroupStateProviderEx = this.stateProviderBroker as IAtomicGroupStateProviderEx;
            if (null == this.stateProvider && null == this.atomicGroupStateProvider && null == this.atomicGroupStateProviderEx)
            {
                AppTrace.TraceSource.WriteError("StatefulServiceReplica.Open", "{0} invalid state providers", this.ToString());
                throw new InvalidOperationException();
            }

            //
            // Create replicator settings (replication and log).
            // For service groups, these settings are specified in the service manifest.
            //
            ReplicatorSettings replicatorSettings = null;

            if (null != this.serviceGroupPartition)
            {
                replicatorSettings = this.ReplicatorSettings;
            }

            ReplicatorLogSettings replicatorLogSettings = null;

            if (null != this.atomicGroupStateProviderEx && null != this.serviceGroupPartition)
            {
                replicatorLogSettings = this.ReplicatorLogSettings;
            }

            //
            // Create replicator.
            //
            FabricReplicator   replicator   = null;
            FabricReplicatorEx replicatorEx = null;

            if (null == this.atomicGroupStateProviderEx)
            {
                AppTrace.TraceSource.WriteInfo("StatefulServiceReplica.Open", "{0} creating replicator", this.ToString());
                //
                // v1 replicator.
                //
                replicator                      = this.servicePartition.CreateReplicator(this.stateProvider, replicatorSettings);
                this.stateReplicator            = replicator.StateReplicator;
                this.atomicGroupStateReplicator = this.stateReplicator as IAtomicGroupStateReplicator;
            }
            else
            {
                AppTrace.TraceSource.WriteInfo("StatefulServiceReplica.Open", "{0} creating atomic group replicator", this.ToString());
                //
                // v2 replicator.
                //
                replicatorEx = this.servicePartitionEx.CreateReplicatorEx(this.atomicGroupStateProviderEx, replicatorSettings, replicatorLogSettings);
                this.atomicGroupStateReplicatorEx = replicatorEx.StateReplicator;
            }

            //
            // Perform local open functionality. Initialize and open state provider broker.
            //
            this.stateProviderBroker.Initialize(this.initializationParameters);
            await this.stateProviderBroker.OpenAsync(
                openMode,
                this.servicePartitionEx,
                this.atomicGroupStateReplicatorEx,
                cancellationToken);

            //
            // Perform custom open functionality.
            //
            await this.OnOpenAsync(openMode, cancellationToken);

            //
            // Change current replica state.
            //
            this.replicaState = ReplicaState.Opened;
            AppTrace.TraceSource.WriteNoise("StatefulServiceReplica.State", "{0} is {1}", this.ToString(), this.replicaState);

            //
            // Done.
            //
            return((null != replicator) ? replicator as IReplicator : replicatorEx as IReplicator);
        }
 public OperationReceiver(IOperationApplier applier, IStateReplicator replicator, Logger logger)
 {
     this.applier    = applier;
     this.replicator = replicator;
     this.logger     = logger;
 }
        /// <summary>
        /// OpenAsync is called when the replica is going to be actually used
        /// </summary>
        /// <param name="openMode">Open mode.</param>
        /// <param name="partitionObject">Service partition</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        /// <returns>Task that represents the asynchronous operation.</returns>
        async Task <IReplicator> IStatefulServiceReplica.OpenAsync(
            ReplicaOpenMode openMode,
            IStatefulServicePartition partitionObject,
            CancellationToken cancellationToken)
        {
            FabricEvents.Events.Lifecycle(
                this.tracer.Type,
                "OpenAsync" + " openMode: " + openMode + " replica: " + this.initializationParameters.ReplicaId);

            TaskScheduler.UnobservedTaskException += this.ProcessUnobservedTaskException;

            // Store the partitionObject
            this.partition = partitionObject;

            var statefulServiceContext = new StatefulServiceContext(
                FabricRuntime.GetNodeContext(),
                this.initializationParameters.CodePackageActivationContext,
                this.initializationParameters.ServiceTypeName,
                this.initializationParameters.ServiceName,
                this.initializationParameters.InitializationData,
                this.initializationParameters.PartitionId,
                this.initializationParameters.ReplicaId);

            this.transactionalReplicator.Initialize(statefulServiceContext, partitionObject);

            FabricEvents.Events.Lifecycle(this.tracer.Type, "OpenAsync: StateManager initialized");

            // create the replicator
            // The Windows Fabric Replicator is used to actually replicate the data
            // The ReplicatorSettings are used for configuring the replicator - here we ask for them from the derived class
            // When using service groups Replicator Settings are described in the Settings.xml inside the configuration package.
            // So when the service is part of a service group it should use null as its Replicator Setting.
            FabricReplicator replicator;
            ReliableStateManagerReplicatorSettings replicatorSettings = null;
            var onOpenInvoked = false;

            try
            {
                if (this.Partition is IServiceGroupPartition)
                {
                    replicatorSettings = new ReliableStateManagerReplicatorSettings();
                    ReliableStateManagerReplicatorSettingsUtil.LoadDefaultsIfNotSet(ref replicatorSettings);
                    replicator = this.partition.CreateReplicator(
                        this.transactionalReplicator,
                        ReliableStateManagerReplicatorSettingsUtil.ToReplicatorSettings(replicatorSettings));
                }
                else
                {
                    replicatorSettings = await this.OnOpenAsync(cancellationToken).ConfigureAwait(false);

                    onOpenInvoked = true;

                    if (replicatorSettings == null)
                    {
                        replicatorSettings = new ReliableStateManagerReplicatorSettings();
                    }

                    ReliableStateManagerReplicatorSettingsUtil.LoadDefaultsIfNotSet(ref replicatorSettings);
                    replicator = this.partition.CreateReplicator(
                        this.transactionalReplicator,
                        ReliableStateManagerReplicatorSettingsUtil.ToReplicatorSettings(replicatorSettings));
                }

                ServiceReplicaUtils.SetupLoggerPath(ref replicatorSettings, ref this.initializationParameters);
                var transactionalReplicatorSettings = new TransactionalReplicatorSettings
                {
                    PublicSettings = replicatorSettings
                };

                ReliableStateManagerReplicatorSettingsUtil.LoadInternalSettingsDefault(ref transactionalReplicatorSettings);

                this.stateReplicator = replicator.StateReplicator;
                this.transactionalReplicator.LoggingReplicator.FabricReplicator = this.stateReplicator;
                this.transactionalReplicator.LoggingReplicator.Tracer           = this.tracer;

                // Starting local recovery
                await this.transactionalReplicator.OpenAsync(openMode, transactionalReplicatorSettings).ConfigureAwait(false);

                // Change state
                this.replicaState = ReplicaState.Opened;

                FabricEvents.Events.Lifecycle(
                    this.tracer.Type,
                    "OpenAsync: Finished opening replica " + this.initializationParameters.ReplicaId + " ReplicatorAddress: " + replicatorSettings.ReplicatorAddress
                    + " ReplicatorListenAddress: " + replicatorSettings.ReplicatorListenAddress
                    + " ReplicatorPublishAddress: " + replicatorSettings.ReplicatorPublishAddress);

                return(replicator);
            }
            catch (Exception e)
            {
                int innerHResult       = 0;
                var flattenedException = Utility.FlattenException(e, out innerHResult);

                FabricEvents.Events.Exception_TStatefulServiceReplica(
                    this.tracer.Type,
                    "OpenAsync",
                    flattenedException.GetType().ToString(),
                    flattenedException.Message,
                    flattenedException.HResult != 0 ? flattenedException.HResult : innerHResult,
                    flattenedException.StackTrace);

                if (onOpenInvoked)
                {
                    this.OnAbort();
                }

                TaskScheduler.UnobservedTaskException -= this.ProcessUnobservedTaskException;
                throw;
            }
        }
 public OperationReceiver(IOperationApplier applier, IStateReplicator replicator, Logger logger)
 {
     this.applier = applier;
     this.replicator = replicator;
     this.logger = logger;
 }