Frontmatter
| id | 9546 |
| title | Refactor Pipeline IPC to use Declarative Remote Configs (Instance Proxies) |
| state | Closed |
| labels | enhancementaiarchitecturecore |
| assignees | tobiu |
| createdAt | Mar 24, 2026, 9:19 PM |
| updatedAt | Mar 24, 2026, 9:34 PM |
| githubUrl | https://github.com/neomjs/neo/issues/9546 |
| author | tobiu |
| commentsCount | 1 |
| parentIssue | 9449 |
| subIssues | [] |
| subIssuesCompleted | 0 |
| subIssuesTotal | 0 |
| blockedBy | [] |
| blocking | [] |
| closedAt | Mar 24, 2026, 9:34 PM |
Refactor Pipeline IPC to use Declarative Remote Configs (Instance Proxies)
tobiu added parent issue #9449 on Mar 24, 2026, 9:20 PM
tobiu assigned to @tobiu on Mar 24, 2026, 9:31 PM

tobiu
Mar 24, 2026, 9:31 PM
Input from Gemini 3.1 Pro:
✦ I have refactored the
PipelineIPC architecture to use declarativeremoteconfigs, adhering to the highest code quality standards ofcore.Base.Implementation Details:
- Removed the Procedural Hacks: The
generateRemotecalls insidereadandexecuteRemoteOrLocalhave been removed fromPipeline.mjs. The pipeline now simply declaresstatic config = { remote: { data: ['create', 'read', 'update'] } }.core.Base.initRemoteEnhancement:
- I modified
initRemote()to correctly handle non-singleton classes.- If a class is not a singleton, it now dynamically generates a
this.remoteobject containing pre-bound proxy functions during instance construction.- These instance-level proxies are designed to resolve
this.remoteIdat execution time, perfectly accommodating the asynchronous "Handshake" pattern where the target ID is populated after the remote thread instantiates the counterpart.- Strict Promise Resolution: The user rightly pointed out that
Base.promiseRemotes(className, remote)was only being called for singletons, which risked leaving the#remotesReadyPromisehanging. With the new implementation, non-singletons don't need to await global registration (registerRemote), so the synchronous population of thethis.remoteobject allows the lifecycle to continue without blocking.- Knowledge Base Enhancements: The comments inside
initRemotehave been thoroughly updated using the Knowledge Base Enhancement Strategy. They clearly articulate the intent, differentiating "Singleton Routing (Namespace-Driven)" from "Instance-to-Instance Routing (ID-Driven)", and documenting the "Handshake" resolution pattern for future context.The pipeline now executes cleanly via
this.remote.data[operation](params), restoring the elegant DX of the Neo.mjs framework. I will close this sub-issue.
tobiu closed this issue on Mar 24, 2026, 9:34 PM
Goal
Refactor the
Neo.data.Pipelineclass to utilize the declarativeremoteconfiguration for instance-to-instance IPC, replacing the procedural on-the-fly proxy generation.Context
In issue #9453, we implemented the initial IPC routing for pipelines by explicitly calling
Neo.currentWorker.generateRemoteinside theread,create, andupdatemethods.This approach is highly procedural and violates the elegant, declarative design patterns of the framework. Neo.mjs heavily relies on defining capabilities statically (e.g.,
static config = { remote: ... }) and letting the class system or mixins handle the wiring.We need to adopt "Option C" (Explicit
remoteNamespace on Instances): Instead of generating the proxy dynamically on every call, thePipelineshould define its remote capabilities in its static config. The framework should then automatically populate athis.remoteobject on the instance with pre-bound proxy functions during construction.Acceptance Criteria
remote: { data: ['create', 'read', 'update'] }to thestatic configofNeo.data.Pipeline.initRemotemethod insrc/core/Base.mjs(or the RMA mixin) to properly handleremoteconfigs for non-singleton instances. If a class is not a singleton, it should generate the proxies and attach them to aremoteproperty on the instance, organized by destination (e.g.,this.remote.data.read).Neo.data.Pipelineto remove the manualgenerateRemotecalls and instead invoke the pre-generated proxies viathis.remote.data[operation]({ ...params, remoteId: this.remoteId }).RemoteMethodAccessandStoreParsercontinue to pass with this declarative architecture.