def _resume_workflow_step_executor( workflow_id: str, step_id: "StepID", store_url: str, current_output: [ray.ObjectRef ]) -> Tuple[ray.ObjectRef, ray.ObjectRef]: # TODO (yic): We need better dependency management for virtual actor # The current output will always be empty for normal workflow # For virtual actor, if it's not empty, it means the previous job is # running. This is a really bad one. for ref in current_output: try: while isinstance(ref, ray.ObjectRef): ref = ray.get(ref) except Exception: pass try: store = storage.create_storage(store_url) wf_store = workflow_storage.WorkflowStorage(workflow_id, store) r = _construct_resume_workflow_from_step(wf_store, step_id, {}) except Exception as e: raise WorkflowNotResumableError(workflow_id) from e if isinstance(r, Workflow): with workflow_context.workflow_step_context( workflow_id, store.storage_url, last_step_of_workflow=True): from ray.workflow.step_executor import execute_workflow result = execute_workflow(r) return result.persisted_output, result.volatile_output assert isinstance(r, StepID) return wf_store.load_step_output(r), None
def _actor_method_call(self, method_helper: _VirtualActorMethodHelper, args, kwargs) -> "ObjectRef": with workflow_context.workflow_step_context(self._actor_id, self._storage.storage_url): wf = method_helper.step(*args, **kwargs) if method_helper.readonly: return execute_workflow(wf).volatile_output else: return wf.run_async(self._actor_id)
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.") with workflow_context.workflow_step_context(self._actor_id, self._storage.storage_url): wf = method.step(*args, **kwargs) readonly = getattr(method, "__virtual_actor_readonly__", False) if readonly: return execute_workflow(wf).volatile_output else: return wf.run_async(self._actor_id)