def round_trip(typename, fn, to: InvocationBuilder) -> dict: functions = StatefulFunctions() functions.register(typename, fn) handler = RequestReplyHandler(functions) f = FromFunction() f.ParseFromString(handler(to.SerializeToString())) return MessageToDict(f, preserving_proto_field_name=True)
def round_trip(functions: StatefulFunctions, to: InvocationBuilder) -> dict: handler = RequestReplyHandler(functions) in_bytes = to.SerializeToString() out_bytes = handler.handle_sync(in_bytes) f = FromFunction() f.ParseFromString(out_bytes) return MessageToDict(f, preserving_proto_field_name=True)
def invoke(self, typename): fn = self.examples[typename] builder = InvocationBuilder() type, name = typename.split("/") builder.with_target(type, name, "some id") fn(builder) result = post(builder.SerializeToString()) from_fn = FromFunction() from_fn.ParseFromString(result.content) pprint.pprint(MessageToDict(from_fn, preserving_proto_field_name=True, including_default_value_fields=True))
def async_round_trip(functions: StatefulFunctions, to: InvocationBuilder) -> dict: handler = AsyncRequestReplyHandler(functions) in_bytes = to.SerializeToString() future = handler(in_bytes) out_bytes = asyncio.get_event_loop().run_until_complete(future) f = FromFunction() f.ParseFromString(out_bytes) return MessageToDict(f, preserving_proto_field_name=True)
def complete(self): from_function = FromFunction() invocation_result = from_function.invocation_result context = self.context self.add_mutations(context, invocation_result) self.add_outgoing_messages(context, invocation_result) self.add_delayed_messages(context, invocation_result) self.add_egress(context, invocation_result) # reset the state for the next invocation self.batch = None self.context = None self.target_function = None # return the result return from_function.SerializeToString()
def complete(self): from_function = FromFunction() invocation_result = from_function.sagas_function_invocation_result context = self.context self.add_invocation_pairs(context, invocation_result) self.add_response(context.success_response, invocation_result.success_response) self.add_response(context.failure_response, invocation_result.failure_response) # reset the state for the next invocation self.batch = None self.context = None self.target_function = None # return the result return from_function.SerializeToString()
def collect_success(ctx: UserFacingContext) -> FromFunction: pb_from_function = FromFunction() pb_invocation_result = pb_from_function.invocation_result collect_messages(ctx._outgoing_messages, pb_invocation_result) collect_delayed(ctx._outgoing_delayed_messages, pb_invocation_result) collect_egress(ctx._outgoing_egress_messages, pb_invocation_result) collect_mutations(ctx._storage._cells, pb_invocation_result) return pb_from_function
def collect_failure(missing_state_specs: typing.List[ValueSpec]) -> FromFunction: pb_from_function = FromFunction() incomplete_context = pb_from_function.incomplete_invocation_context missing_values = incomplete_context.missing_values for state_spec in missing_state_specs: missing_value = missing_values.add() missing_value.state_name = state_spec.name missing_value.type_typename = state_spec.type.typename protocol_expiration_spec = FromFunction.ExpirationSpec() if not state_spec.after_write and not state_spec.after_call: protocol_expiration_spec.mode = FromFunction.ExpirationSpec.ExpireMode.NONE else: protocol_expiration_spec.expire_after_millis = state_spec.duration if state_spec.after_call: protocol_expiration_spec.mode = FromFunction.ExpirationSpec.ExpireMode.AFTER_INVOKE elif state_spec.after_write: protocol_expiration_spec.mode = FromFunction.ExpirationSpec.ExpireMode.AFTER_WRITE else: raise ValueError("Unexpected state expiration mode.") missing_value.expiration_spec.CopyFrom(protocol_expiration_spec) return pb_from_function
def add_missing_state_specs(missing_state_specs, incomplete_context_response): missing_values = incomplete_context_response.missing_values for state_spec in missing_state_specs: missing_value = missing_values.add() missing_value.state_name = state_spec.name protocol_expiration_spec = FromFunction.ExpirationSpec() sdk_expiration_spec = state_spec.expiration if not sdk_expiration_spec: protocol_expiration_spec.mode = FromFunction.ExpirationSpec.ExpireMode.NONE else: protocol_expiration_spec.expire_after_millis = sdk_expiration_spec.expire_after_millis if sdk_expiration_spec.expire_mode is Expiration.Mode.AFTER_INVOKE: protocol_expiration_spec.mode = FromFunction.ExpirationSpec.ExpireMode.AFTER_INVOKE elif sdk_expiration_spec.expire_mode is Expiration.Mode.AFTER_WRITE: protocol_expiration_spec.mode = FromFunction.ExpirationSpec.ExpireMode.AFTER_WRITE else: raise ValueError("Unexpected state expiration mode.") missing_value.expiration_spec.CopyFrom(protocol_expiration_spec)
def handle_invocation(self, to_function): # # setup # context = BatchContext(to_function.invocation.target, to_function.invocation.state) target_function = self.functions.for_type(context.address.namespace, context.address.type) if target_function is None: raise ValueError("Unable to find a function of type ", target_function) # # process the batch # batch = to_function.invocation.invocations self.invoke_batch(batch, context, target_function) # # prepare an invocation result that represents the batch # from_function = FromFunction() invocation_result = from_function.invocation_result self.add_mutations(context, invocation_result) self.add_outgoing_messages(context, invocation_result) self.add_delayed_messages(context, invocation_result) self.add_egress(context, invocation_result) return from_function
def add_missing_state_specs(missing_state_specs, incomplete_context_response): missing_values = incomplete_context_response.missing_values for state_spec in missing_state_specs: missing_value = missing_values.add() missing_value.state_name = state_spec.name # TODO see the comment in typed_value_utils.from_proto_any_state on # TODO the reason to use this specific typename missing_value.type_typename = "type.googleapis.com/google.protobuf.Any" protocol_expiration_spec = FromFunction.ExpirationSpec() sdk_expiration_spec = state_spec.expiration if not sdk_expiration_spec: protocol_expiration_spec.mode = FromFunction.ExpirationSpec.ExpireMode.NONE else: protocol_expiration_spec.expire_after_millis = sdk_expiration_spec.expire_after_millis if sdk_expiration_spec.expire_mode is Expiration.Mode.AFTER_INVOKE: protocol_expiration_spec.mode = FromFunction.ExpirationSpec.ExpireMode.AFTER_INVOKE elif sdk_expiration_spec.expire_mode is Expiration.Mode.AFTER_WRITE: protocol_expiration_spec.mode = FromFunction.ExpirationSpec.ExpireMode.AFTER_WRITE else: raise ValueError("Unexpected state expiration mode.") missing_value.expiration_spec.CopyFrom(protocol_expiration_spec)
def _parse_result_bytes(result_bytes): f = FromFunction() f.ParseFromString(result_bytes) return f