refactor(engine)!: simplify execution architecture - #249
Draft
laipz8200 wants to merge 1 commit into
Draft
Conversation
Consolidate frame scheduling, event processing, commands, layers, filters, workers, and runtime execution state behind direct module boundaries and canonical public imports. BREAKING CHANGE: Rename the engine, runtime, event, layer, filter, command, and container APIs; remove legacy import paths and compatibility aliases; unify nested event ownership under container_id.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Important
!Related Issue
Closes #248
Summary
This refactor reduces the engine's public vocabulary and collapses overlapping execution responsibilities. It intentionally removes compatibility aliases: downstream integrations must upgrade imports, constructor calls, extension hooks, and event field access together.
Architecture changes
GraphEngineand thegraph_enginepackage withEngineandgraphon.engine.RuntimeState; child frames receive only their container-scoped graph and can read variables inherited from their parent state without exposing child variables upward.Scheduler, and keep frame creation/restoration inFrameRegistry.GraphEngineConfigare removed.event, command channels/processing intocommand, and use singularcontainer_handler,filter,layer, andworkermodules.Downstream migration
Imports and public names
graphon.graph_enginegraphon.enginegraphon.graph_eventsgraphon.engine_eventsgraphon.filters/ old engine filter pathsgraphon.engine.filterlayers,command_channels,command_processing,container_handlers, andworker_managementpathsgraphon.engineGraphEngineEngineGraphEngineEventEngineEventGraphNodeEventBaseNodeEventNodeEventBaseNodeEventPayloadGraphRuntimeStateRuntimeStateGraphInitParamsInitParamsGraphEngineLayerLayerGraphEventFilterEngineEventFilterGraphEventFilterContextEngineEventFilterContextfilter_graph_events(...)filter_engine_events(...)TaskEventNodeEventTaskConcrete
GraphRun*Event,GraphEdge*Event, andNodeRun*Eventnames remain unchanged. There are no aliases for the old imports or type names.Engine construction and identity
GraphEngineConfig; pass the fixed worker count asworkers=when loading or constructing an engine.workflow_idtoEngine. Set it on the rootRuntimeState; restored and child states share itsGraphExecutionidentity.InMemoryChannel.engine.layer(layer)withengine.add_layer(layer). The method mutates the engine and returnsNone.Events and containers
in_loop_idandin_iteration_idwith onecontainer_idfield on engine events.container_ididentifies the event's direct owning container. Top-level events usecontainer_id == ""; nested events do not expose ancestor container IDs.NodeEventPayload;Node.run()adds execution context and emitsNodeEvent, which is part of theEngineEventstream.Layers and filters
DebugLoggingLayerandGraphEngineLayerNotInitializedError; invalid layer use now raises the standard runtime error.ResumableEngineEventFilterandfilter_id; filters operate directly on the engine event stream.ResponseStreamFilterandExecutionLimitsLayeruse their canonical singular-module imports. NonessentialExecutionLimitsLayerhelpers andLimitTypeare no longer public API.Commands and remote control
GraphEngineManager. Downstream applications now own task IDs, Redis key naming, and command routing policy.GraphEngineCommand/CommandTypebranching with the concrete discriminated command types such asAbortCommand,PauseCommand, andUpdateVariablesCommand.VariableUpdatewrapper;UpdateVariablesCommand.updatesreceives variables directly.{ "value": variable }update shape for the bounded Redis TTL migration window.Extension APIs
ContainerHandlerhooks change as follows:start_await(...)handle_request(...)complete_frame(...)complete_frame_if_ready(...)should_collect(...)should_emit(...)FrameRegistrychanges as follows:materialize_frame(...)create(...)materialize_child_frame(...)create_child(...)materialize_child_frame_from_state(...)restore_child(...)registry.get(frame_id)registry[frame_id]Execution frame fields change as follows:
frame.graph_runtime_stateframe.stateframe.state_manager/frame.edge_processorframe.schedulerframe.error_handlerframe.failure_handlerCustom node factories must continue binding nodes through
with_runtime_state(...). Custom ready queues must consumeReadyTaskvalues and implement serialization through the new ready-queue module;ReadyQueueStateis no longer public.Removed internal boundaries
GraphStateManager,EdgeProcessor,graph_traversal,event_management,orchestration,error_handler, and dynamic worker-management modules.GraphExecutionandNodeExecutiontographon.runtime.execution.WorkflowExecutiontemporarily for downstream compatibility, with a TODO marking its future removal. The existing event-streamRWLockis unchanged and will be handled separately.Persistence compatibility
InitParams.model_dump()data is unchanged, although its generated schema title changes with the class name.isinstancechecks, schema-title assertions, and pickles that refer to removed class/module names are not compatible.container_id.Dify adaptation scope
Dify should upgrade Graphon and migrate in one change. The main affected areas are workflow engine construction, runtime-state creation and restoration, layer registration, command/stop routing, event filters, persistence and response conversion, custom container handlers, and type annotations. In particular, all
in_loop_id/in_iteration_idaccess in runners, persistence layers, and response converters must use direct-ownercontainer_idsemantics rather than mechanically preserving both ancestor fields.Checklist
!