Skip to content

What still overlaps with core-cpp after the migration #807

Description

@christianparpart

The core-cpp migration (#805, #806) moved TimeoutScheduler, base64, the wakeup pipe and the per-model strands onto core-cpp, and added coroutines on core::async. This issue lists where morph and core-cpp still overlap, and what moving each would take against the code as it is now. Each item is a candidate for its own change, and none of them is required by the migration.

morph core-cpp What moving would take
morph::exec leaf executors: IExecutor, ThreadPoolExecutor, MainThreadExecutor, InlineExecutor, and qt::QtExecutor core::async::IExecutor, ThreadPoolExecutor, ResumeOn; core::net::EventLoop as an executor Blocked on contour-terminal/core-cpp#56. The per-model strands have already moved (exec::detail::ModelStrands over core::async::KeyedStrands; morph keeps the adapters CoreExecutorOver, TaskResumer, ExecutorResumer). What remains is the leaf executors, which post std::function<void()> (28 post() sites in include/morph, plus every Completion callback). core::async::IExecutor accepts only submit(coroutine_handle<>) and submit(ParkedWork) and has no way to run a closure. Replacing them therefore needs either a closure submit in core-cpp, or every closure wrapped in a coroutine frame (one allocation per post). MainThreadExecutor::runFor/drain and QtExecutor have no core-cpp counterpart. It is a public API change and needs docs/spec/core/executor.md first.
morph::log core::log Proposed: keep. morph::log::logError is the sink for orphaned errors and for exceptions posted tasks throw, and tests silence it through --log-level. The two filter differently: morph gates on one ordered threshold (debug < info < warn < error < off); core::log enables or disables named Category objects individually and has no severity order. Moving needs a decision on how the threshold maps onto categories. morph does not link core::log today, and core-cpp's async, net and platform modules don't log through it. So no core-cpp output currently bypasses morph's sink, and moving would only gain a shared sink for applications that already use core::log.
morph::core::FileIoOps (the injectable file-I/O seam for the journal and both offline queues) core::platform::FileSystem Blocked on contour-terminal/core-cpp#57. FileIoOps injects fopen, fwrite, fflush, fsync(FILE*), resizeFile and directory syncPath, and the torn-tail repair works on a FILE* (ftell, seek to end, truncate). FileSystem (v0.5.0) is path- and stream-based and has none of these: no file or directory sync, no truncate, no handle to sync. Moving needs a file-handle abstraction with write/flush/sync/truncate/tell and directory sync landed in core-cpp first, and a morph adapter until then. core::platform is also not linked under WebAssembly.
Four independent wall-clock sources (below) core::platform::IWallClock, injected (header already reachable: timeout_scheduler.hpp includes core/platform/Clock.hpp on every platform) Actionable now; the two raw sites are in #842. Reconciling them into one injected IWallClock:
• DateTime::now() / Timestamp::now() with a process-global override. No caller in include/morph or src; used by examples/ledger and tests.
• session::Clock (std::function<int64_t()>, default systemClockMs) for token issue/verify. Already injected, per call.
• Model::recordIfAttached stamps action-log entries (LogEntry::timestampMs) from system_clock::now() directly. Not injectable.
• SqliteOfflineQueue::nowMillis() stamps enqueue and update times from system_clock::now() directly. Not injectable.
The last two are the ones a test cannot pin today, and they are the smallest step: give Model and SqliteOfflineQueue an IWallClock defaulting to SystemWallClock.
morph::net (POSIX sockets only; MORPH_BUILD_NET warns and builds nothing on Windows) core::net sockets, listeners and TLS on every platform, IOCP on Windows Valid, not scheduled. SocketServer runs one accept thread and one thread per client; SocketBackend uses raw POSIX sockets (~1550 lines together). Porting onto core::net (IListener, TcpClient, EventLoop) would give the raw-socket transport Windows support, at the cost of rewriting thread-per-connection as event-loop flows. TLS would also need CORE_CPP_WITH_TLS, which morph builds OFF.

Constraints any of these must keep

  • morph's public surface stays header-only. core-cpp's static modules are built alongside it, as they are now, but nothing may require a consumer to link a morph library of its own.
  • Single-threaded WebAssembly (Qt wasm_singlethread, emsdk 3.1.56, no -pthread) must keep building and working. No thread, no blocking wait, and nothing newer than libc++ 17 without a feature-test macro. Of core-cpp, only its WebAssembly subset is available there.
  • The wire protocol and the remote backends stay unchanged.

Verification status. Read from source, not built, measured or prototyped: morph at master 2cfbdd4 (core-cpp pinned at v0.5.0), and a checkout of core-cpp's v0.5.0 tag (async/IExecutor.hpp, async/ThreadPoolExecutor.hpp, platform/FileSystem.hpp, platform/Clock.hpp, platform/CMakeLists.txt, log/, net/). The clock sites come from grepping include/morph and src for system_clock::now, DateTime::now and Timestamp::now; a clock read through another spelling would be missed. That Clock.hpp compiles under WebAssembly is inferred from its unconditional include, not from a wasm build.

What would close this: each row either moved (with its own issue), or recorded here as deliberately kept, with the reason.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: coreSubsystem: coretriage: rescopeReal problem, wrong framing; rewrite before building

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions