Skip to content
File

Blob: src/workerd/server/workerd-debug-port-client.h

cpp117 lines
1// Copyright (c) 2017-2022 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4 
5#pragma once
6 
7#include <workerd/io/io-channels.h>
8#include <workerd/io/io-own.h>
9#include <workerd/io/worker-interface.capnp.h>
10#include <workerd/jsg/jsg.h>
11 
12#include <capnp/rpc-twoparty.h>
13 
14namespace workerd::api {
15class Fetcher;
16} // namespace workerd::api
17 
18namespace workerd::server {
19 
20// Holds the I/O state for a debug port connection: the TCP stream, capnp RPC client,
21// and debug port capability. Refcounted to support deferred proxying - response bodies
22// and WebSockets are proxied through the capnp connection, so it must stay alive until
23// they're fully consumed. See WorkerdBootstrapSubrequestChannel::startRequest().
24class DebugPortConnectionState: public kj::Refcounted {
25 public:
26 DebugPortConnectionState(kj::Own<kj::AsyncIoStream> connection,
27 kj::Own<capnp::TwoPartyClient> rpcClient,
28 rpc::WorkerdDebugPort::Client debugPort)
29 : connection(kj::mv(connection)),
30 rpcClient(kj::mv(rpcClient)),
31 debugPort(kj::mv(debugPort)) {}
32 
33 kj::Own<DebugPortConnectionState> addRef() {
34 return kj::addRef(*this);
35 }
36 
37 kj::Own<kj::AsyncIoStream> connection;
38 kj::Own<capnp::TwoPartyClient> rpcClient;
39 rpc::WorkerdDebugPort::Client debugPort;
40};
41 
42// JS interface for a connected workerd debug port.
43// This class is returned from WorkerdDebugPortConnector::connect() and provides
44// access to a remote workerd instance's WorkerdDebugPort RPC interface.
45class WorkerdDebugPortClient: public jsg::Object {
46 public:
47 // Create a WorkerdDebugPortClient with an established connection.
48 // Takes an IoOwn reference to the connection state.
49 explicit WorkerdDebugPortClient(IoOwn<DebugPortConnectionState> state): state(kj::mv(state)) {}
50 
51 // Get access to a stateless entrypoint on the remote workerd instance.
52 // Uses Cap'n Proto pipelining to return a Fetcher synchronously — the actual
53 // RPC resolution is deferred until the Fetcher is first used (e.g. fetch()).
54 //
55 // @param service - The service name in the remote workerd process
56 // @param entrypoint - The entrypoint name to access (if omitted, uses the default handler)
57 // @param props - Optional props to pass to the entrypoint
58 // @returns A Fetcher that lazily resolves on first use
59 jsg::Ref<api::Fetcher> getEntrypoint(jsg::Lock& js,
60 kj::String service,
61 jsg::Optional<kj::String> entrypoint,
62 jsg::Optional<jsg::JsRef<jsg::JsObject>> props);
63 
64 // Get access to an actor (Durable Object) stub on the remote workerd instance.
65 // Uses Cap'n Proto pipelining to return a Fetcher synchronously — the actual
66 // RPC resolution is deferred until the Fetcher is first used (e.g. fetch()).
67 //
68 // @param service - The service name in the remote workerd process
69 // @param entrypoint - The entrypoint/class name to access
70 // @param actorId - The actor ID (hex string for DOs, plain string for ephemeral)
71 // @returns A Fetcher that lazily resolves on first use
72 jsg::Ref<api::Fetcher> getActor(
73 jsg::Lock& js, kj::String service, kj::String entrypoint, kj::String actorId);
74 
75 JSG_RESOURCE_TYPE(WorkerdDebugPortClient) {
76 JSG_METHOD(getEntrypoint);
77 JSG_METHOD(getActor);
78 
79 JSG_TS_ROOT();
80 JSG_TS_OVERRIDE({
81 getEntrypoint<T extends Rpc.WorkerEntrypointBranded | undefined>(
82 service: string, entrypoint?: string, props?: Record<string, unknown>): Fetcher<T>;
83 getActor<T extends Rpc.DurableObjectBranded | undefined>(
84 service: string, entrypoint: string, actorId: string): Fetcher<T>;
85 });
86 }
87 
88 private:
89 IoOwn<DebugPortConnectionState> state;
90};
91 
92// JS interface for the workerdDebugPort binding.
93// This binding provides a connect() method to dynamically connect to any workerd
94// instance's debug port.
95class WorkerdDebugPortConnector: public jsg::Object {
96 public:
97 WorkerdDebugPortConnector() = default;
98 
99 // Connect to a remote workerd debug port at the given address.
100 // Returns synchronously using kj::newPromisedStream() to defer the TCP connection.
101 // Cap'n Proto pipelining ensures that all subsequent RPC calls (getEntrypoint, getActor)
102 // are queued until the connection is established.
103 //
104 // @param address - The address of the remote workerd debug port (e.g., "localhost:1234")
105 // @returns A WorkerdDebugPortClient that lazily connects on first use
106 jsg::Ref<WorkerdDebugPortClient> connect(jsg::Lock& js, kj::String address);
107 
108 JSG_RESOURCE_TYPE(WorkerdDebugPortConnector) {
109 JSG_METHOD(connect);
110 }
111};
112 
113#define EW_WORKERD_DEBUG_PORT_CLIENT_ISOLATE_TYPES \
114 workerd::server::WorkerdDebugPortClient, workerd::server::WorkerdDebugPortConnector
115 
116} // namespace workerd::server