Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/workerd/api/container.c++
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,9 @@ class Container::TcpPortOutgoingFactory final: public Fetcher::OutgoingFactory {

kj::Own<WorkerInterface> newSingleUseClient(kj::Maybe<kj::String> cfStr) override {
// At present we have no use for `cfStr`.
return kj::heap<TcpPortWorkerInterface>(byteStreamFactory, entropySource, headerTable, port);
return IoContext::current().getSubrequestNoChecks([&](auto& tracing, auto& channelFactory) {
return kj::heap<TcpPortWorkerInterface>(byteStreamFactory, entropySource, headerTable, port);
}, {.inHouse = false, .wrapMetrics = false});
}

private:
Expand Down
7 changes: 5 additions & 2 deletions src/workerd/api/http.c++
Original file line number Diff line number Diff line change
Expand Up @@ -2434,12 +2434,15 @@ Fetcher::ClientWithTracing Fetcher::getClientWithTracing(
return ClientWithTracing{kj::mv(client), kj::mv(traceContext)};
}
KJ_CASE_ONEOF(outgoingFactory, IoOwn<OutgoingFactory>) {
// For outgoing factories, no trace context needed
// Outgoing factories are responsible for routing through getSubrequestNoChecks() (or
// getSubrequest()) internally if they create HTTP connections, to ensure external memory
// adjustment and other subrequest accounting are applied.
auto client = outgoingFactory->newSingleUseClient(kj::mv(cfStr));
return ClientWithTracing{kj::mv(client), kj::none};
}
KJ_CASE_ONEOF(outgoingFactory, kj::Own<CrossContextOutgoingFactory>) {
// For cross-context outgoing factories, no trace context needed
// Same as OutgoingFactory above -- the factory is responsible for routing through
// getSubrequestNoChecks() internally.
auto client = outgoingFactory->newSingleUseClient(ioContext, kj::mv(cfStr));
return ClientWithTracing{kj::mv(client), kj::none};
}
Expand Down
7 changes: 7 additions & 0 deletions src/workerd/api/http.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,10 @@ class Fetcher: public JsRpcClientProvider {
// Used by Fetchers that use ad-hoc, single-use WorkerInterface instances, such as ones
// created for Actors.
//
// Implementations that create HTTP connections should route through
// IoContext::getSubrequestNoChecks() (or getSubrequest()) internally, to ensure external memory
// adjustment and other subrequest accounting are applied.
//
// TODO(cleanup): Consider removing this in favor of `IoChannelFactory::SubrequestChannel`, which
// is almost the same thing.
class OutgoingFactory {
Expand All @@ -297,6 +301,9 @@ class Fetcher: public JsRpcClientProvider {
// Used by Fetchers that obtain their HttpClient in a custom way, but which aren't tied
// to a specific I/O context. The factory object moves with the isolate across threads and
// contexts, and must work from any context.
//
// Same as OutgoingFactory: implementations that create HTTP connections should route through
// IoContext::getSubrequestNoChecks() internally.
class CrossContextOutgoingFactory {
public:
virtual kj::Own<WorkerInterface> newSingleUseClient(
Expand Down
8 changes: 6 additions & 2 deletions src/workerd/api/sockets.c++
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "streams/standard.h"
#include "system-streams.h"

#include <workerd/io/io-context.h>
#include <workerd/io/worker-interface.h>
#include <workerd/jsg/exception.h>
#include <workerd/jsg/url.h>
Expand Down Expand Up @@ -636,8 +637,11 @@ class StreamWorkerInterface final: public WorkerInterface {
kj::Own<WorkerInterface> StreamOutgoingFactory::newSingleUseClient(kj::Maybe<kj::String> cfStr) {
JSG_ASSERT(stream.get() != nullptr, Error,
"Fetcher created from internalNewHttpClient can only be used once");
// Create a WorkerInterface that wraps the stream
return kj::heap<StreamWorkerInterface>(kj::addRef(*this));
// Create a WorkerInterface that wraps the stream, routing through getSubrequestNoChecks to apply
// external memory adjustment for GC pressure.
return IoContext::current().getSubrequestNoChecks([&](auto& tracing, auto& channelFactory) {
return kj::heap<StreamWorkerInterface>(kj::addRef(*this));
}, {.inHouse = false, .wrapMetrics = false});
}

jsg::Promise<jsg::Ref<Fetcher>> SocketsModule::internalNewHttpClient(
Expand Down
9 changes: 9 additions & 0 deletions src/workerd/io/io-context.h
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,10 @@ class IoContext final: public kj::Refcounted, private kj::TaskSet::ErrorHandler
kj::Maybe<TraceContext&> existingTraceContext;
};

// Wraps a WorkerInterface factory with subrequest accounting: tracing, optional metrics wrapping,
// and an external memory adjustment to pressure V8's GC. All code paths that create HTTP
// connections (including those built from capnp capabilities via getHttpOverCapnpFactory())
// should route through this function or getSubrequest().
kj::Own<WorkerInterface> getSubrequestNoChecks(
kj::FunctionParam<kj::Own<WorkerInterface>(TraceContext&, IoChannelFactory&)> func,
SubrequestOptions options);
Expand Down Expand Up @@ -834,6 +838,11 @@ class IoContext final: public kj::Refcounted, private kj::TaskSet::ErrorHandler
// TODO(cleanup): Make it the caller's job to call asHttpClient() on the result of
// getSubrequest*().

// Get a raw Cap'n Proto capability for the given channel. This is appropriate for pure RPC use
// cases (e.g. actor operations, email dispatch) that don't create HTTP connections. If you're
// converting the capability to an HTTP service via getHttpOverCapnpFactory(), use
// getSubrequestNoChecks() instead and call channelFactory.getCapability() from the callback,
// so that the external memory adjustment and other subrequest accounting are applied.
capnp::Capability::Client getCapnpChannel(uint channel) {
return getIoChannelFactory().getCapability(channel);
}
Expand Down
Loading