Esempio n. 1
0
 def _create(self, args: Tuple[Any], kwargs: Dict[str, Any]):
     workflow_storage = WorkflowStorage(self._actor_id, self._storage)
     workflow_storage.save_actor_class_body(self._metadata.cls)
     ref = self._actor_method_call("__init__", args, kwargs)
     workflow_manager = get_or_create_management_actor()
     # keep the ref in a list to prevent dereference
     ray.get(workflow_manager.init_actor.remote(self._actor_id, [ref]))
Esempio n. 2
0
            def step(method_name, method, *args, **kwargs):
                readonly = getattr(method, "__virtual_actor_readonly__", False)
                flattened_args = self.flatten_args(method_name, args, kwargs)
                actor_id = workflow_context.get_current_workflow_id()
                if not readonly:
                    if method_name == "__init__":
                        state_ref = None
                    else:
                        ws = WorkflowStorage(actor_id, get_global_storage())
                        state_ref = WorkflowRef(ws.get_entrypoint_step_id())
                    # This is a hack to insert a positional argument.
                    flattened_args = [signature.DUMMY_TYPE, state_ref
                                      ] + flattened_args
                workflow_inputs = serialization_context.make_workflow_inputs(
                    flattened_args)

                if readonly:
                    _actor_method = _wrap_readonly_actor_method(
                        actor_id, self.cls, method_name)
                    step_type = StepType.READONLY_ACTOR_METHOD
                else:
                    _actor_method = _wrap_actor_method(self.cls, method_name)
                    step_type = StepType.ACTOR_METHOD
                # TODO(suquark): Support actor options.
                workflow_data = WorkflowData(
                    func_body=_actor_method,
                    step_type=step_type,
                    inputs=workflow_inputs,
                    max_retries=1,
                    catch_exceptions=False,
                    ray_options={},
                    name=None,
                )
                wf = Workflow(workflow_data)
                return wf
Esempio n. 3
0
 def _create(self, args: Tuple[Any], kwargs: Dict[str, Any]):
     workflow_storage = WorkflowStorage(self._actor_id, self._storage)
     workflow_storage.save_actor_class_body(self._metadata.cls)
     # TODO(suquark): This is just a temporary solution.
     # A virtual actor writer should take place of this solution later.
     arg_list = self._metadata.flatten_args("__init__", args, kwargs)
     init_step = _virtual_actor_init.step(self._metadata.cls, arg_list)
     init_step._step_id = self._metadata.cls.__init__.__name__
     ref = init_step.run_async(workflow_id=self._actor_id)
     workflow_manager = get_or_create_management_actor()
     # keep the ref in a list to prevent dereference
     ray.get(workflow_manager.init_actor.remote(self._actor_id, [ref]))
Esempio n. 4
0
def get_actor(actor_id: str, storage: Storage) -> VirtualActor:
    """Get an virtual actor.

    Args:
        actor_id: The ID of the actor.
        storage: The storage of the actor.

    Returns:
        A virtual actor.
    """
    ws = WorkflowStorage(actor_id, storage)
    cls = ws.load_actor_class_body()
    v_cls = VirtualActorClass._from_class(cls)
    return v_cls._construct(actor_id, storage)
Esempio n. 5
0
def commit_step(store: workflow_storage.WorkflowStorage,
                step_id: "StepID",
                ret: Union[Workflow, Any],
                outer_most_step_id: Optional[str] = None):
    """Checkpoint the step output.
    Args:
        store: The storage the current workflow is using.
        step_id: The ID of the step.
        ret: The returned object of the workflow step.
        outer_most_step_id: The ID of the outer most workflow. None if it
            does not exists. See "step_executor.execute_workflow" for detailed
            explanation.
    """
    if isinstance(ret, Workflow):
        store.save_subworkflow(ret)
    store.save_step_output(step_id, ret, outer_most_step_id)
Esempio n. 6
0
    def _actor_method_call(self, method_name: str, args,
                           kwargs) -> "ObjectRef":
        cls = self._metadata.cls
        method = getattr(cls, method_name, None)
        if method is None:
            raise AttributeError(f"Method '{method_name}' does not exist.")
        readonly = getattr(method, "__virtual_actor_readonly__", False)

        flattened_args = self._metadata.flatten_args(method_name, args, kwargs)
        if not readonly:
            if method_name == "__init__":
                state_ref = None
            else:
                ws = WorkflowStorage(self._actor_id, self._storage)
                state_ref = WorkflowRef(ws.get_entrypoint_step_id())
            # This is a hack to insert a positional argument.
            flattened_args = [signature.DUMMY_TYPE, state_ref] + flattened_args
        workflow_inputs = serialization_context.make_workflow_inputs(
            flattened_args)

        if readonly:
            _actor_method = _wrap_readonly_actor_method(
                self._actor_id, cls, method_name)
            step_type = StepType.READONLY_ACTOR_METHOD
        else:
            _actor_method = _wrap_actor_method(cls, method_name)
            step_type = StepType.ACTOR_METHOD
        # TODO(suquark): Support actor options.
        workflow_data = WorkflowData(
            func_body=_actor_method,
            step_type=step_type,
            inputs=workflow_inputs,
            max_retries=1,
            catch_exceptions=False,
            ray_options={},
        )
        wf = Workflow(workflow_data)
        with workflow_context.workflow_step_context(self._actor_id,
                                                    self._storage.storage_url):
            if readonly:
                return execute_workflow(wf).volatile_output
            else:
                return wf.run_async(self._actor_id)
Esempio n. 7
0
def _construct_resume_workflow_from_step(
        reader: workflow_storage.WorkflowStorage,
        step_id: StepID) -> Union[Workflow, StepID]:
    """Try to construct a workflow (step) that recovers the workflow step.
    If the workflow step already has an output checkpointing file, we return
    the workflow step id instead.

    Args:
        reader: The storage reader for inspecting the step.
        step_id: The ID of the step we want to recover.

    Returns:
        A workflow that recovers the step, or a ID of a step
        that contains the output checkpoint file.
    """
    result: workflow_storage.StepInspectResult = reader.inspect_step(step_id)
    if result.output_object_valid:
        # we already have the output
        return step_id
    if isinstance(result.output_step_id, str):
        return _construct_resume_workflow_from_step(reader,
                                                    result.output_step_id)
    # output does not exists or not valid. try to reconstruct it.
    if not result.is_recoverable():
        raise WorkflowStepNotRecoverableError(step_id)
    input_workflows = []
    instant_workflow_outputs: Dict[int, str] = {}
    for i, _step_id in enumerate(result.workflows):
        r = _construct_resume_workflow_from_step(reader, _step_id)
        if isinstance(r, Workflow):
            input_workflows.append(r)
        else:
            input_workflows.append(None)
            instant_workflow_outputs[i] = r
    workflow_refs = list(map(WorkflowRef, result.workflow_refs))
    recovery_workflow: Workflow = _recover_workflow_step.options(
        max_retries=result.max_retries,
        catch_exceptions=result.catch_exceptions,
        **result.ray_options).step(result.object_refs, input_workflows,
                                   workflow_refs, instant_workflow_outputs)
    recovery_workflow._step_id = step_id
    recovery_workflow.data.step_type = result.step_type
    return recovery_workflow