Example #1
0
class InvocationBuilder(object):
    """builder for the ToFunction message"""
    def __init__(self):
        self.to_function = ToFunction()

    def with_target(self, ns, type, id):
        InvocationBuilder.set_address(ns, type, id,
                                      self.to_function.invocation.target)
        return self

    def with_state(self, name, value=None):
        state = self.to_function.invocation.state.add()
        state.state_name = name
        if value:
            any = Any()
            any.Pack(value)
            state.state_value = any.SerializeToString()
        return self

    def with_invocation(self, arg, caller=None):
        invocation = self.to_function.invocation.invocations.add()
        if caller:
            (ns, type, id) = caller
            InvocationBuilder.set_address(ns, type, id, invocation.caller)
        invocation.argument.Pack(arg)
        return self

    def SerializeToString(self):
        return self.to_function.SerializeToString()

    @staticmethod
    def set_address(namespace, type, id, address):
        address.namespace = namespace
        address.type = type
        address.id = id
Example #2
0
    def _run_flink_loop(self,
                        message_arg: Union[TaskRequest, TaskResult,
                                           TaskException, TaskActionRequest],
                        target: Address,
                        caller=None):
        to_function = ToFunction()
        update_address(to_function.invocation.target, target.namespace,
                       target.type, target.id)
        invocation = to_function.invocation.invocations.add()
        if caller:
            update_address(invocation.caller, caller.namespace, caller.type,
                           caller.id)
        invocation.argument.Pack(message_arg)

        self._copy_state_to_invocation(target.namespace, target.type,
                                       target.id, to_function)
        result_bytes = asyncio.get_event_loop().run_until_complete(
            async_handler(to_function.SerializeToString()))

        result = self._process_result(to_function, result_bytes)
        if result.egress_message is not None:
            return result.egress_message
        else:
            outgoing_messages = result.outgoing_messages
            for outgoing_message in outgoing_messages:
                message_arg = unpack_any(
                    outgoing_message.argument,
                    [TaskRequest, TaskResult, TaskException])
                egress_value = self._run_flink_loop(
                    message_arg=message_arg,
                    target=outgoing_message.target,
                    caller=target)
                if egress_value:
                    return egress_value
Example #3
0
class InvocationBuilder(object):
    """builder for the ToFunction message"""

    def __init__(self):
        self.to_function = ToFunction()

    def with_target(self, ns, type, id):
        InvocationBuilder.set_address(ns, type, id, self.to_function.invocation.target)
        return self

    def with_state(self, name, value=None):
        state = self.to_function.invocation.state.add()
        state.state_name = name
        if value:
            state.state_value.CopyFrom(self.to_typed_value_any_state(value))
        return self

    def with_invocation(self, arg, caller=None):
        invocation = self.to_function.invocation.invocations.add()
        if caller:
            (ns, type, id) = caller
            InvocationBuilder.set_address(ns, type, id, invocation.caller)
        invocation.argument.CopyFrom(self.to_typed_value(arg))
        return self

    def SerializeToString(self):
        return self.to_function.SerializeToString()

    @staticmethod
    def to_typed_value(proto_msg):
        any = Any()
        any.Pack(proto_msg)
        typed_value = TypedValue()
        typed_value.typename = any.type_url
        typed_value.value = any.value
        return typed_value

    @staticmethod
    def to_typed_value_any_state(proto_msg):
        any = Any()
        any.Pack(proto_msg)
        typed_value = TypedValue()
        typed_value.typename = "type.googleapis.com/google.protobuf.Any"
        typed_value.value = any.SerializeToString()
        return typed_value

    @staticmethod
    def set_address(namespace, type, id, address):
        address.namespace = namespace
        address.type = type
        address.id = id
    def _run_flink_loop(self,
                        message_arg,
                        target: Address,
                        caller=None,
                        egress_result=None):
        to_function = ToFunction()
        update_address(to_function.invocation.target, target.namespace,
                       target.type, target.id)
        invocation = to_function.invocation.invocations.add()
        if caller:
            update_address(invocation.caller, caller.namespace, caller.type,
                           caller.id)

        if isinstance(message_arg, TypedValue):  # function calling function
            invocation.argument.CopyFrom(message_arg)
        else:
            flink_type = flink_value_type_for(
                message_arg
            )  # ingress protobuf needs to to be wrapped into a TypedValue
            invocation.argument.CopyFrom(
                TypedValue(typename=flink_type.typename,
                           has_value=True,
                           value=message_arg.SerializeToString()))

        self._copy_state_to_invocation(target.namespace, target.type,
                                       target.id, to_function)
        result_bytes = asyncio.get_event_loop().run_until_complete(
            handler.handle_async(to_function.SerializeToString()))
        result = self._process_result(to_function, result_bytes)

        # remember first egress result
        if result.egress_message is not None and egress_result is None:
            egress_result = result.egress_message

        # recurse while we have outgoing messages
        outgoing_messages = result.outgoing_messages
        for outgoing_message in outgoing_messages:
            egress_value = self._run_flink_loop(
                message_arg=outgoing_message.argument,
                target=outgoing_message.target,
                caller=target,
                egress_result=egress_result)
            if egress_value:
                return egress_value

        return egress_result