doc: Fix and expand design.md #278

pull ViniciusCestarii wants to merge 1 commits into bitcoin-core:master from ViniciusCestarii:doc-design-md-corrections changing 1 files +3 −1
  1. ViniciusCestarii commented at 2:19 PM on May 24, 2026: contributor

    Improve two points on design.md:

    • Clarify that only ProxyClient is directly exposed to users and meant to be used directly and inherits from the C++ interface class so it can be used as a pointer to it.
    • Document the special destroy capnp method, which handles synchronous server-side object destruction.
  2. DrahtBot commented at 2:20 PM on May 24, 2026: none

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK ryanofsky

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #287 (Split repository into master (library source) and support (CI, docs, examples) branches. by ryanofsky)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  3. in doc/design.md:18 in 6314aa19b9
      14 | @@ -15,7 +15,7 @@ Libmultiprocess acts as a pure wrapper or layer over the underlying protocol. Cl
      15 |  
      16 |  ## Core Architecture
      17 |  
      18 | -The `ProxyClient` and `ProxyServer` generated classes are not directly exposed to the user, as described in [usage.md](usage.md). Instead, they wrap C++ interfaces and appear to the user as pointers to an interface. They are first instantiated when calling `ConnectStream` and `ServeStream` respectively for creating the `InitInterface`. These methods establish connections through sockets, internally creating `Connection` objects wrapping a `capnp::RpcSystem` configured for client and server mode respectively.
      19 | +The `ProxyServer` generated class is not directly exposed to the user. The `ProxyClient` generated class is exposed and made to be used directly, as described in [usage.md](usage.md), and inherits from the C++ interface class so it can be used as a pointer to it. They are first instantiated when calling `ConnectStream` and `ServeStream` respectively for creating the `InitInterface`. These methods establish connections through sockets, internally creating `Connection` objects wrapping a `capnp::RpcSystem` configured for client and server mode respectively.
    


    ryanofsky commented at 7:51 PM on June 2, 2026:

    In commit "doc: Fix and expand design.md" (6314aa19b996aa9f8c2e9dcc1aa208bf9dd2b9ae)

    Nice catch. Current text is inaccurate in claiming the ProxyClient type is not exposed at all, because the pointer returned to the initial remote object returned by ConnectStream is a ProxyClient<InitInterface> object. But this object isn't really meant to do anything other than inherit from InitInterface and implement its methods. So I think potentially ConnectStream could be changed to return an InitInterface pointer instead of a ProxyClient<InitInterface> and it wouldn't affect anything.

    All other remote objects obtained by calling InitInterface methods will be ProxyClient<Foo> objects, but only exposed to user code as Foo pointers, so that aligns with current documentation. Current documentation should be mostly accurate except for the ConnectStream exception, and it is misleading to change it to say ProxyClient generated class meant to be is exposed and used more directly.

    LLM suggests following which I think would be more accurate:

    The ProxyServer generated class is not directly exposed to the user. The ProxyClient generated class inherits from the C++ interface class, so user code interacts with it through the abstract interface type — the ProxyClient type itself is generally not visible or accessible without a cast. ConnectStream returns a unique_ptr<ProxyClient<InitInterface>> as an exception for the root Init interface, but even there users typically treat it as a pointer to the abstract InitInterface. For all interfaces returned by Init methods (e.g., Printer, Calculator), the return type is the abstract class pointer, hiding the underlying ProxyClient entirely.


    ViniciusCestarii commented at 1:06 PM on June 3, 2026:

    I agree, I wanted to make it not misleading but added another misleading

    Fixed on (used your suggestion with a tweak: replaced the em dash with ", and"): 18db0ab9570786c5efc75b3447027d5a4e104caa

  4. in doc/design.md:113 in 6314aa19b9
     109 | @@ -110,6 +110,8 @@ Each `ServerField` invokes `PassField`, which:
     110 |  
     111 |  `ServerCall` uses the generated `ProxyMethod<MethodParams>::impl` pointer-to-member to invoke the actual C++ method on the wrapped implementation object.
     112 |  
     113 | +A capnp interface can also declare a special `destroy` method, handled by `ServerDestroy` instead of `ServerCall`. Rather than dispatching to a C++ interface method, `ServerDestroy` calls `invokeDestroy()` on the `ProxyServer`, which resets `m_impl` and runs any registered cleanup functions, giving the client a way to synchronously destroy the wrapped object on the server side.
    


    ryanofsky commented at 7:56 PM on June 2, 2026:

    In commit "doc: Fix and expand design.md" (6314aa19b996aa9f8c2e9dcc1aa208bf9dd2b9ae)

    This is worth mentioning, but placement is awkward since it is interrupting the description of the flow for server method calls by describing a special case before the general case is described and shown in the diagram.

    Would suggest moving the new paragraph after the mermaid diagram and tweaking text to connect it to previously described flow. LLM suggests following which I think is an improvement:

    Destroy methods are a special case: a capnp interface can declare a destroy method that is handled by ServerDestroy instead of ServerCall. Rather than dispatching through the ServerField/ServerRet/ServerCall chain to a C++ interface method, ServerDestroy calls invokeDestroy() on the ProxyServer, which resets m_impl and runs any registered cleanup functions, giving the client a way to synchronously destroy the wrapped object on the server side.


    ViniciusCestarii commented at 1:07 PM on June 3, 2026:

    I agree

    Fixed on: 18db0ab9570786c5efc75b3447027d5a4e104caa

  5. ryanofsky commented at 8:01 PM on June 2, 2026: collaborator

    Code review 6314aa19b996aa9f8c2e9dcc1aa208bf9dd2b9ae. Nice catches calling out two special cases that don't match the more general descriptions in the design doc.

    I think the changes should be edited a little more for clarify, though, so left some suggestions below to consider

  6. doc: Fix and expand design.md 18db0ab957
  7. ViniciusCestarii force-pushed on Jun 3, 2026
  8. ViniciusCestarii commented at 1:22 PM on June 3, 2026: contributor

    Forced-push 18db0ab9570786c5efc75b3447027d5a4e104caa to add suggested changes

  9. in doc/design.md:18 in 18db0ab957
      14 | @@ -15,7 +15,7 @@ Libmultiprocess acts as a pure wrapper or layer over the underlying protocol. Cl
      15 |  
      16 |  ## Core Architecture
      17 |  
      18 | -The `ProxyClient` and `ProxyServer` generated classes are not directly exposed to the user, as described in [usage.md](usage.md). Instead, they wrap C++ interfaces and appear to the user as pointers to an interface. They are first instantiated when calling `ConnectStream` and `ServeStream` respectively for creating the `InitInterface`. These methods establish connections through sockets, internally creating `Connection` objects wrapping a `capnp::RpcSystem` configured for client and server mode respectively.
      19 | +The `ProxyServer` generated class is not directly exposed to the user. The `ProxyClient` generated class inherits from the C++ interface class, so user code interacts with it through the abstract interface type, and the `ProxyClient` type itself is generally not visible or accessible without a cast. `ConnectStream` returns a `unique_ptr<ProxyClient<InitInterface>>` as an exception for the root Init interface, but even there users typically treat it as a pointer to the abstract `InitInterface`. For all interfaces returned by Init methods (e.g., `Printer`, `Calculator`), the return type is the abstract class pointer, hiding the underlying `ProxyClient` entirely. They are first instantiated when calling `ConnectStream` and `ServeStream` respectively for creating the `InitInterface`. These methods establish connections through sockets, internally creating `Connection` objects wrapping a `capnp::RpcSystem` configured for client and server mode respectively.
    


    ryanofsky commented at 7:49 PM on June 9, 2026:

    In commit "doc: Fix and expand design.md" (18db0ab9570786c5efc75b3447027d5a4e104caa)

    This all looks accurate now. But I feel like it is also more confusing. The point this is trying to make is that library users don't really interact with the ProxyClient and ProxyClient classes directly. Library users define virtual interfaces and call interface methods that ProxyClient classes implement. And they provide interface pointers that ProxyServer classes wrap. They can create a ProxyClient object accessing an interface by calling ConnectStream, and they can create a ProxyServer object wrapping an interface by calling ConnectStream. The interface type is passed to ConnectStream and ServeStream as a template parameter, and Connect/Serve functions are typically only called once with an initial interface or InitInterface type. From there, InitInterface methods can return pointers new interfaces, causing new ProxyClient and ProxyServer objects to be created when they are called, and those interface and create and pass around pointers to other interface.

    I think maybe it might make sense to structure the paragraph more like that description but I don't have a clear suggestion.

    This change is probably better than the status quo since it is more technically accurate though, and it seems fine to follow up on improving this later.


    ViniciusCestarii commented at 12:28 PM on June 10, 2026:

    I agree. This revised version is more accurate, but it may also be harder to follow. Thanks for the feedback

  10. ryanofsky approved
  11. ryanofsky commented at 7:52 PM on June 9, 2026: collaborator

    Code review ACK 18db0ab9570786c5efc75b3447027d5a4e104caa. Thanks for the fixes and for taking suggestions!

  12. ryanofsky merged this on Jun 9, 2026
  13. ryanofsky closed this on Jun 9, 2026


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin-core/libmultiprocess. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-06-24 04:30 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me