/// <summary> /// Connects to the master and enables this node to receive build requests /// </summary> /// <param name="schedule">the engine schedule</param> /// <returns>true if the operation was successful</returns> internal async Task <bool> ConnectToMasterAsync(EngineSchedule schedule) { Contract.Requires(schedule != null); Contract.Requires(schedule.Scheduler != null); Contract.Requires(schedule.SchedulingQueue != null); Contract.Assert(AttachCompletion.IsCompleted && AttachCompletion.GetAwaiter().GetResult(), "ProcessBuildRequests called before finishing attach on worker"); m_workerPipStateManager = new WorkerServicePipStateManager(this); m_pipTable = schedule.PipTable; m_pipQueue = schedule.SchedulingQueue; m_scheduler = schedule.Scheduler; m_operationTracker = m_scheduler.OperationTracker; m_environment = m_scheduler; m_environment.ContentFingerprinter.FingerprintSalt = BuildStartData.FingerprintSalt; m_environment.State.PipEnvironment.MasterEnvironmentVariables = BuildStartData.EnvironmentVariables; m_resultSerializer = new ExecutionResultSerializer(maxSerializableAbsolutePathIndex: schedule.MaxSerializedAbsolutePath, executionContext: m_scheduler.Context); m_forwardingEventListener = new ForwardingEventListener(this); bool success = await SendAttachCompletedAfterProcessBuildRequestStartedAsync(); // Wait until the build finishes or we discovered that the master is dead success &= await ExitCompletion; success &= !m_hasFailures; if (m_masterFailureMessage != null) { Logger.Log.DistributionWorkerExitFailure(m_appLoggingContext, m_masterFailureMessage); } m_pipQueue.SetAsFinalized(); return(success); }
internal void Start(EngineSchedule schedule) { Contract.Requires(schedule != null); Contract.Requires(schedule.Scheduler != null); Contract.Requires(schedule.SchedulingQueue != null); Contract.Assert(AttachCompletion.IsCompleted && AttachCompletion.GetAwaiter().GetResult(), "ProcessBuildRequests called before finishing attach on worker"); m_workerPipStateManager = new WorkerServicePipStateManager(this); m_pipTable = schedule.PipTable; m_pipQueue = schedule.SchedulingQueue; m_scheduler = schedule.Scheduler; m_operationTracker = m_scheduler.OperationTracker; m_environment = m_scheduler; m_environment.ContentFingerprinter.FingerprintSalt = BuildStartData.FingerprintSalt; m_environment.State.PipEnvironment.MasterEnvironmentVariables = BuildStartData.EnvironmentVariables; m_resultSerializer = new ExecutionResultSerializer(maxSerializableAbsolutePathIndex: schedule.MaxSerializedAbsolutePath, executionContext: m_scheduler.Context); m_forwardingEventListener = new ForwardingEventListener(this); }
/// <summary> /// Connects to the master and enables this node to receive build requests /// </summary> internal async Task <bool> WhenDoneAsync() { Contract.Assert(AttachCompletion.IsCompleted && AttachCompletion.GetAwaiter().GetResult(), "ProcessBuildRequests called before finishing attach on worker"); bool success = await SendAttachCompletedAfterProcessBuildRequestStartedAsync(); // Wait until the build finishes or we discovered that the master is dead success &= await ExitCompletion; success &= !m_hasFailures; if (m_masterFailureMessage != null) { Logger.Log.DistributionWorkerExitFailure(m_appLoggingContext, m_masterFailureMessage); } m_pipQueue.SetAsFinalized(); return(success); }
/// <summary> /// Waits for the master to attach synchronously /// </summary> internal bool WaitForMasterAttach() { Logger.Log.DistributionWaitingForMasterAttached(m_appLoggingContext); while (!AttachCompletion.Wait(EngineEnvironmentSettings.WorkerAttachTimeout)) { if ((TimestampUtilities.Timestamp - m_lastHeartbeatTimestamp) > EngineEnvironmentSettings.WorkerAttachTimeout) { Exit(failure: "Timed out waiting for attach request from master", isUnexpected: true); return(false); } } if (!AttachCompletion.Result) { Logger.Log.DistributionInactiveMaster(m_appLoggingContext, (int)EngineEnvironmentSettings.WorkerAttachTimeout.Value.TotalMinutes); return(false); } return(true); }