private WriteResult ExecuteCommand(DxStoreCommand command, WriteOptions options, TimeSpan timeout) { WriteResult writeResult = null; command.Initialize(this.instance.GroupConfig.Self, options); if (options != null && (options.IsPerformTestUpdate || options.IsWaitRequired())) { if (options.IsPerformTestUpdate) { this.EnsureTestUpdateIsSuccessful(command, options, timeout); } writeResult = this.ExecuteCommandWithAck(command, options, true, timeout); if (!writeResult.IsConstraintPassed) { this.instance.EventLogger.Log(DxEventSeverity.Warning, 0, "{0}: Failed to satisfy constraint in the second attempt. Updates will eventually catch up", new object[] { this.instance.GroupConfig.Identity }); } } else { this.instance.StateMachine.ReplicateCommand(command, new TimeSpan?(timeout)); } return(writeResult); }
private void InitializeCommand(DxStoreCommand command, WriteOptions options) { command.TimeInitiated = DateTimeOffset.Now; command.Initiator = this.instance.GroupConfig.Self; if (options != null) { command.IsNotifyInitiator = options.IsWaitRequired(); } }
private WriteResult EnsureTestUpdateIsSuccessful(DxStoreCommand command, WriteOptions options, TimeSpan timeout) { DxStoreCommand.DummyCommand dummyCommand = new DxStoreCommand.DummyCommand { OriginalDbCommandId = command.CommandId }; dummyCommand.Initialize(this.instance.GroupConfig.Self, options); WriteResult writeResult = this.ExecuteCommandWithAck(dummyCommand, options, true, timeout); if (!writeResult.IsConstraintPassed) { throw new DxStoreCommandConstraintFailedException("TestUpdate"); } return(writeResult); }
public void AddCommand(DxStoreCommand command, WriteOptions options) { lock (this.locker) { int count = this.instance.StateMachine.Paxos.ConfigurationHint.Acceptors.Count; LocalCommitAcknowledger.Container container = new LocalCommitAcknowledger.Container(command.CommandId, command.TimeInitiated, count, options); LocalCommitAcknowledger.Tracer.TraceDebug((long)this.instance.IdentityHash, "{0}: Adding command {1} - Id# {2} (Initiator: {3}, TotalNodes: {4}, MinimumRequired: {5})", new object[] { this.instance.Identity, command.GetTypeId(), command.CommandId, command.Initiator, container.TotalNodesCount, container.MinimumNodesRequired }); LinkedListNode <LocalCommitAcknowledger.Container> value = this.containerList.AddFirst(container); this.containerMap[command.CommandId] = value; this.UpdateOldestItemTime(); } }
private WriteResult ExecuteCommandWithAck(DxStoreCommand command, WriteOptions options, bool isThrowOnException, TimeSpan timeout) { LocalCommitAcknowledger commitAcknowledger = this.instance.CommitAcknowledger; WriteResult writeResult = new WriteResult(); Guid commandId = command.CommandId; try { commitAcknowledger.AddCommand(command, options); this.instance.StateMachine.ReplicateCommand(command, new TimeSpan?(timeout)); if (commitAcknowledger.WaitForExecution(commandId, timeout)) { writeResult.IsConstraintPassed = true; } } finally { writeResult.Responses = commitAcknowledger.RemoveCommand(commandId); } return(writeResult); }