public override async Task acceptBuildJob(IAsyncStreamReader <BuildStatusUpdate> requestStream, IServerStreamWriter <RunBuildCommand> responseStream, ServerCallContext context) { var agent = Authenticate(context); if (agent == null) { return; } async Task <bool> CheckPlatform(PlatformInfo platformInfo, CancellationToken cancellationToken) { await responseStream.WriteAsync(new RunBuildCommand { SupportsPlatformRequest = new SupportsPlatformRequest { Platform = JsonConvert.SerializeObject(platformInfo, typeof(PlatformInfo), new JsonSerializerSettings()), }, }); while (await requestStream.MoveNext(cancellationToken)) { var update = requestStream.Current; switch (update.PayloadCase) { case BuildStatusUpdate.PayloadOneofCase.PlatformSupport: return(update.PlatformSupport.IsSupported); default: throw new Exception("Unexpected update type (expected PlatformSupport): " + update.PayloadCase); } } throw new Exception("Unexpected end of stream (expected PlatformSupport)"); } IRunnableJob?runnableJob = null; try { runnableJob = await jobQueue.AcceptJob(CheckPlatform, context.CancellationToken); var cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(context.CancellationToken, runnableJob.JobStatus.BuildCancelToken).Token; runnableJob.JobStatus.Started(agent.Config); var task = JsonConvert.SerializeObject(runnableJob.BuildTask, typeof(BuildTaskBase), new JsonSerializerSettings()); await responseStream.WriteAsync(new RunBuildCommand { BuildTask = task, }); await SendWorkspace(responseStream, runnableJob, cancellationToken); var result = await ProcessBuildOutput(requestStream, cancellationToken, runnableJob); if (result.ExitCode != 0) { await runnableJob.JobStatus.FailedWith(result.ExitCode); return; } if (runnableJob.BuildTask.ReplayMode != ReplayMode.Discard) { await ReadReplay(requestStream, responseStream, runnableJob.JobStatus, cancellationToken); } foreach (var artifact in result.Artifacts) { await ReadArtifact(requestStream, responseStream, runnableJob.JobStatus, artifact, cancellationToken); } await runnableJob.JobStatus.Completed(); } catch (OperationCanceledException) { throw; } catch (Exception ex) { if (runnableJob != null) { await runnableJob.JobStatus.Error(ex); } else { throw; } } }