private <T> T withStage(CompletionId cid, Function<Stage, T> function) { Stage stage = stages.get(cid); if (stage == null) { throw new PlatformException("Stage not found in graph :" + cid); } return function.apply(stage); }
private <T> T withStages(List<CompletionId> cids, Function<List<Stage>, T> function) { List<Stage> stages = new ArrayList<>(); for (CompletionId cid : cids) { Stage stage = this.stages.get(cid); if (stage == null) { throw new PlatformException("Stage not found in graph :" + cid); } stages.add(stage); } return function.apply(stages); }
private <T> T withActiveGraph(FlowId t, Function<Flow, T> act) { Flow g = graphs.get(t); if (g == null) { throw new PlatformException("unknown graph " + t.getId()); } if (g.mainFinished.get()) { throw new PlatformException("graph already run"); } return act.apply(g); }
private static byte[] serializeClosure(Object data) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); try (ObjectOutputStream oos = new ObjectOutputStream(bos)) { oos.writeObject(data); oos.close(); return bos.toByteArray(); } catch (NotSerializableException nse) { throw new LambdaSerializationException("Closure not serializable", nse); } catch (IOException e) { throw new PlatformException("Failed to write closure", e); } }
private CompletionId addStage(APIModel.CompletionOperation operation, APIModel.Blob closure, List<CompletionId> deps, FlowId flowId, CodeLocation codeLocation) { try { APIModel.AddStageRequest addStageRequest = new APIModel.AddStageRequest(); addStageRequest.closure = closure; addStageRequest.operation = operation; addStageRequest.codeLocation = codeLocation.getLocation(); addStageRequest.callerId = FlowRuntimeGlobals.getCurrentCompletionId().map(CompletionId::getId).orElse(null); addStageRequest.deps = deps.stream().map(dep -> dep.getId()).collect(Collectors.toList()); return executeAddStageRequest(flowId, addStageRequest); } catch (IOException e) { throw new PlatformException("Failed to add stage", e); } }
private OutputEvent constructOutputEvent(APIModel.Datum obj, boolean success) { APIModel.CompletionResult result = new APIModel.CompletionResult(); result.result = obj; result.successful = success; APIModel.InvokeStageResponse resp = new APIModel.InvokeStageResponse(); resp.result = result; String json; try { json = FlowRuntimeGlobals.getObjectMapper().writeValueAsString(resp); } catch (JsonProcessingException e) { throw new PlatformException("Error writing JSON", e); } return new ContinuationOutputEvent(success, json.getBytes()); }
private OutputEvent invokeContinuation(BlobStoreClient blobStoreClient, FlowId flowId, Object instance, Method m, Object[] args) { Object result; try { m.setAccessible(true); result = m.invoke(instance, args); } catch (InvocationTargetException ite) { APIModel.Datum datum = APIModel.datumFromJava(flowId, ite.getCause(), blobStoreClient); throw new InternalFunctionInvocationException( "Error invoking flows lambda", ite.getCause(), constructOutputEvent(datum, false) ); } catch (Exception ex) { throw new PlatformException(ex); } APIModel.Datum resultDatum = APIModel.datumFromJava(flowId, result, blobStoreClient); return constructOutputEvent(resultDatum, true); }
@Override public Object waitForCompletion(FlowId flowId, CompletionId completionId, ClassLoader loader) { return withActiveGraph(flowId, (flow) -> flow.withStage(completionId, (stage) -> { try { return stage.outputFuture().toCompletableFuture().get().toJava(flowId, this, loader); } catch (ExecutionException e) { if (e.getCause() instanceof ResultException) { APIModel.CompletionResult r = ((ResultException) e.getCause()).toResult(); Object err = r.toJava(flowId, this, loader); if (err instanceof Throwable) { throw new FlowCompletionException((Throwable) err); } else if (err instanceof HttpResponse && !r.successful) { throw new FlowCompletionException(new FunctionInvocationException((HttpResponse) err)); } throw new PlatformException(e); } else { throw new PlatformException(e); } } catch (Exception e) { throw new PlatformException(e); } })); }
throw new FlowCompletionException(new FunctionInvocationException((HttpResponse) err)); throw new PlatformException(e); } else { throw new PlatformException(e); throw new PlatformException(e);
@Override public Object toJava(boolean successful, FlowId flowId, BlobStoreClient blobStore, ClassLoader classLoader) { return blobStore.readBlob(flowId.getId(), blob.blobId, (requestInputStream) -> { try (ObjectInputStream ois = new ObjectInputStream(requestInputStream) { @Override protected Class resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException { String cname = classDesc.getName(); try { return classLoader.loadClass(cname); } catch (ClassNotFoundException ex) { return super.resolveClass(classDesc); } } }) { return ois.readObject(); } catch (ClassNotFoundException | InvalidClassException | StreamCorruptedException | OptionalDataException e) { throw new FunctionInputHandlingException("Error reading continuation content", e); } catch (IOException e) { throw new PlatformException("Error reading blob data", e); } }, blob.contentType); }
@Override public Object toJava(boolean successful, FlowId flowId, BlobStoreClient blobStore, ClassLoader classLoader) { switch (type) { case StageTimeout: return new StageTimeoutException(message); case StageLost: return new StageLostException(message); case StageFailed: return new StageInvokeFailedException(message); case FunctionTimeout: return new FunctionTimeoutException(message); case FunctionInvokeFailed: return new FunctionInvokeFailedException(message); case InvalidStageResponse: return new InvalidStageResponseException(message); default: return new PlatformException(message); } }