use of org.apache.beam.model.jobmanagement.v1.JobApi.RunJobRequest in project beam by apache.
the class PortableRunner method run.
@Override
public PipelineResult run(Pipeline pipeline) {
Runnable cleanup;
if (Environments.ENVIRONMENT_LOOPBACK.equals(options.as(PortablePipelineOptions.class).getDefaultEnvironmentType())) {
GrpcFnServer<ExternalWorkerService> workerService;
try {
workerService = new ExternalWorkerService(options).start();
} catch (Exception exn) {
throw new RuntimeException("Failed to start GrpcFnServer for ExternalWorkerService", exn);
}
LOG.info("Starting worker service at {}", workerService.getApiServiceDescriptor().getUrl());
options.as(PortablePipelineOptions.class).setDefaultEnvironmentConfig(workerService.getApiServiceDescriptor().getUrl());
cleanup = () -> {
try {
LOG.warn("closing worker service {}", workerService);
workerService.close();
} catch (Exception exn) {
throw new RuntimeException(exn);
}
};
} else {
cleanup = null;
}
ImmutableList.Builder<String> filesToStageBuilder = ImmutableList.builder();
List<String> stagingFiles = options.as(PortablePipelineOptions.class).getFilesToStage();
if (stagingFiles == null) {
List<String> classpathResources = detectClassPathResourcesToStage(Environments.class.getClassLoader(), options);
if (classpathResources.isEmpty()) {
throw new IllegalArgumentException("No classpath elements found.");
}
LOG.debug("PortablePipelineOptions.filesToStage was not specified. " + "Defaulting to files from the classpath: {}", classpathResources.size());
filesToStageBuilder.addAll(classpathResources);
} else {
filesToStageBuilder.addAll(stagingFiles);
}
// TODO(heejong): remove jar_packages experimental flag when cross-language dependency
// management is implemented for all runners.
List<String> experiments = options.as(ExperimentalOptions.class).getExperiments();
if (experiments != null) {
Optional<String> jarPackages = experiments.stream().filter((String flag) -> flag.startsWith("jar_packages=")).findFirst();
jarPackages.ifPresent(s -> filesToStageBuilder.addAll(Arrays.asList(s.replaceFirst("jar_packages=", "").split(","))));
}
options.as(PortablePipelineOptions.class).setFilesToStage(filesToStageBuilder.build());
RunnerApi.Pipeline pipelineProto = PipelineTranslation.toProto(pipeline, SdkComponents.create(options));
pipelineProto = DefaultArtifactResolver.INSTANCE.resolveArtifacts(pipelineProto);
PrepareJobRequest prepareJobRequest = PrepareJobRequest.newBuilder().setJobName(options.getJobName()).setPipeline(pipelineProto).setPipelineOptions(PipelineOptionsTranslation.toProto(options)).build();
LOG.info("Using job server endpoint: {}", endpoint);
ManagedChannel jobServiceChannel = channelFactory.forDescriptor(ApiServiceDescriptor.newBuilder().setUrl(endpoint).build());
JobServiceBlockingStub jobService = JobServiceGrpc.newBlockingStub(jobServiceChannel);
try (CloseableResource<JobServiceBlockingStub> wrappedJobService = CloseableResource.of(jobService, unused -> jobServiceChannel.shutdown())) {
final int jobServerTimeout = options.as(PortablePipelineOptions.class).getJobServerTimeout();
PrepareJobResponse prepareJobResponse = jobService.withDeadlineAfter(jobServerTimeout, TimeUnit.SECONDS).withWaitForReady().prepare(prepareJobRequest);
LOG.info("PrepareJobResponse: {}", prepareJobResponse);
ApiServiceDescriptor artifactStagingEndpoint = prepareJobResponse.getArtifactStagingEndpoint();
String stagingSessionToken = prepareJobResponse.getStagingSessionToken();
try (CloseableResource<ManagedChannel> artifactChannel = CloseableResource.of(channelFactory.forDescriptor(artifactStagingEndpoint), ManagedChannel::shutdown)) {
ArtifactStagingService.offer(new ArtifactRetrievalService(), ArtifactStagingServiceGrpc.newStub(artifactChannel.get()), stagingSessionToken);
} catch (CloseableResource.CloseException e) {
LOG.warn("Error closing artifact staging channel", e);
// CloseExceptions should only be thrown while closing the channel.
} catch (Exception e) {
throw new RuntimeException("Error staging files.", e);
}
RunJobRequest runJobRequest = RunJobRequest.newBuilder().setPreparationId(prepareJobResponse.getPreparationId()).build();
// Run the job and wait for a result, we don't set a timeout here because
// it may take a long time for a job to complete and streaming
// jobs never return a response.
RunJobResponse runJobResponse = jobService.run(runJobRequest);
LOG.info("RunJobResponse: {}", runJobResponse);
ByteString jobId = runJobResponse.getJobIdBytes();
return new JobServicePipelineResult(jobId, jobServerTimeout, wrappedJobService.transfer(), cleanup);
} catch (CloseException e) {
throw new RuntimeException(e);
}
}
use of org.apache.beam.model.jobmanagement.v1.JobApi.RunJobRequest in project beam by apache.
the class InMemoryJobService method run.
@Override
public void run(RunJobRequest request, StreamObserver<RunJobResponse> responseObserver) {
LOG.trace("{} {}", RunJobRequest.class.getSimpleName(), request);
String preparationId = request.getPreparationId();
try {
// retrieve job preparation
JobPreparation preparation = preparations.get(preparationId);
if (preparation == null) {
String errMessage = String.format("Unknown Preparation Id \"%s\".", preparationId);
StatusException exception = Status.NOT_FOUND.withDescription(errMessage).asException();
responseObserver.onError(exception);
return;
}
try {
PipelineValidator.validate(preparation.pipeline());
} catch (Exception e) {
LOG.warn("Encountered Unexpected Exception during validation", e);
responseObserver.onError(new StatusRuntimeException(Status.INVALID_ARGUMENT.withCause(e)));
return;
}
// create new invocation
JobInvocation invocation = invoker.invoke(resolveDependencies(preparation.pipeline(), stagingSessionTokens.get(preparationId)), preparation.options(), request.getRetrievalToken());
String invocationId = invocation.getId();
invocation.addStateListener(event -> {
if (!JobInvocation.isTerminated(event.getState())) {
return;
}
String stagingSessionToken = stagingSessionTokens.get(preparationId);
stagingSessionTokens.remove(preparationId);
try {
if (cleanupJobFn != null) {
cleanupJobFn.accept(stagingSessionToken);
}
} catch (Exception e) {
LOG.warn("Failed to remove job staging directory for token {}.", stagingSessionToken, e);
} finally {
onFinishedInvocationCleanup(invocationId);
}
});
invocation.start();
invocations.put(invocationId, invocation);
// Cleanup this preparation because we are running it now.
// If we fail, we need to prepare again.
preparations.remove(preparationId);
RunJobResponse response = RunJobResponse.newBuilder().setJobId(invocationId).build();
responseObserver.onNext(response);
responseObserver.onCompleted();
} catch (StatusRuntimeException e) {
LOG.warn("Encountered Status Exception", e);
responseObserver.onError(e);
} catch (Exception e) {
String errMessage = String.format("Encountered Unexpected Exception for Preparation %s", preparationId);
LOG.error(errMessage, e);
responseObserver.onError(Status.INTERNAL.withCause(e).asException());
}
}
Aggregations