Skip to content

Add Hyperdrive bindings#1266

Merged
a-robinson merged 8 commits intocloudflare:mainfrom
tmthecoder:tejas/add-hyperdrive-bindings
Oct 12, 2023
Merged

Add Hyperdrive bindings#1266
a-robinson merged 8 commits intocloudflare:mainfrom
tmthecoder:tejas/add-hyperdrive-bindings

Conversation

@tmthecoder
Copy link
Copy Markdown
Contributor

Adda a new binding type Hyperdrive as well as a corresponding Service definition ExternalTcpService that allows TCP connections to the designated host address & port

@github-actions
Copy link
Copy Markdown

github-actions bot commented Oct 3, 2023

CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅

@tmthecoder tmthecoder force-pushed the tejas/add-hyperdrive-bindings branch from 392a5ff to bef20bd Compare October 3, 2023 15:08
@tmthecoder
Copy link
Copy Markdown
Contributor Author

I have read the CLA document and I hereby sign the CLA

Comment thread src/workerd/api/hyperdrive.h Outdated
Comment thread src/workerd/api/hyperdrive.h Outdated
Comment thread src/workerd/api/hyperdrive.c++ Outdated
Comment thread src/workerd/api/hyperdrive.c++ Outdated
Comment thread src/workerd/api/hyperdrive.c++
Comment thread src/workerd/api/hyperdrive.c++ Outdated
@kentonv kentonv requested a review from a-robinson October 3, 2023 15:36
@tmthecoder tmthecoder force-pushed the tejas/add-hyperdrive-bindings branch from 7e16396 to 2f2c004 Compare October 3, 2023 15:38
# If `certificateHost` is not provided, then the certificate is checked against `address`.
}

tcp :group {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add doc comments.

I assume this is something like:

Connect to the server over raw TCP. Bindings to this service will only support the connect() method; fetch() will throw an exception.

Comment thread src/workerd/server/server.c++ Outdated
kj::HttpHeaderTable& headerTable,
kj::Timer& timer, kj::EntropySource& entropySource)
: addr(kj::mv(addrParam)),
inner(kj::newHttpClient(timer, headerTable, *addr, {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the point of this class that it should form raw TCP connections, not HTTP? I'd expect request() throws an exception, and connect() calls addr->connect() without using an HttpClient.

Comment thread src/workerd/api/hyperdrive.c++ Outdated
kj::String user, kj::String password)
: clientIndex(clientIndex), database(kj::mv(database)),
user(kj::mv(user)), password(kj::mv(password)) {
randomHost = randomUUID(kj::none);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this actually need to be random? Could it instead just be a static fake string value?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't that cause issues if there were 2+ Hyperdrive bindings?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry, I missed that this is being used with setConnectOverride(). In that case, can we please generate the hostname the same way we do in the internal codebase? Matching behavior as much as possible is helpful for testing purposes.

randomHost = kj::str(kj::encodeHex(randomBytes), ".hyperdrive.local");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't see a random byte generation function so I went with the UUID, should I port one over or use the UUID with the .hyperdrive.local appended?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should match the formatting. UUIDs have a specific format which is not the same as a hex string.

Take a look at how randomUUID() itself generates random bytes -- it calls OpenSSL's RAND_bytes(). You can do the same here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah alright. Should be good now

@tmthecoder tmthecoder force-pushed the tejas/add-hyperdrive-bindings branch from 7b8c0f5 to 085c92e Compare October 3, 2023 16:23
Comment thread src/workerd/api/hyperdrive.c++ Outdated
@jasnell
Copy link
Copy Markdown
Collaborator

jasnell commented Oct 3, 2023

Marking this with needs-internal-pr to ensure there is an internal CI run done. Feel free to remove that label once this has gone through at least one successful internal CI run.

@tmthecoder tmthecoder force-pushed the tejas/add-hyperdrive-bindings branch from ed3f25a to 51a610d Compare October 4, 2023 15:33
Comment thread src/workerd/api/hyperdrive.c++ Outdated
Comment thread src/workerd/server/server.c++ Outdated
@tmthecoder tmthecoder force-pushed the tejas/add-hyperdrive-bindings branch 3 times, most recently from e6184a0 to 9173986 Compare October 5, 2023 14:54
@tmthecoder
Copy link
Copy Markdown
Contributor Author

Marking this with needs-internal-pr to ensure there is an internal CI run done. Feel free to remove that label once this has gone through at least one successful internal CI run.

It passed internally, so I think the tag's set to be removed (I can't remove it though)

jasnell
jasnell previously approved these changes Oct 5, 2023
@tmthecoder tmthecoder force-pushed the tejas/add-hyperdrive-bindings branch from 9173986 to c7c8da4 Compare October 11, 2023 15:34
@tmthecoder tmthecoder force-pushed the tejas/add-hyperdrive-bindings branch 2 times, most recently from 2ecdb57 to 83e2a95 Compare October 11, 2023 17:57
@tmthecoder tmthecoder force-pushed the tejas/add-hyperdrive-bindings branch 3 times, most recently from 60d23cd to d1e4b68 Compare October 12, 2023 16:24
Copy link
Copy Markdown
Member

@a-robinson a-robinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just a couple minor things left. Thanks for confirming that it is actually able to successfully establish connections. Did you test what happens when trying to connect to an address that isn't listening?

@@ -0,0 +1,106 @@
#include "hyperdrive.h"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we still need to add a copyright header here

Comment thread src/workerd/api/hyperdrive.c++ Outdated
try {
auto errorBody = co_await e->readAllText();
kj::throwFatalException(KJ_EXCEPTION(
FAILED, kj::str("unexpected error connecting to SQC from process sandbox: ", errorBody)));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not quite -- we aren't connecting from a "process sandbox" here. I'd just remove the "from process sandbox" part of these log messages

Comment thread src/workerd/api/hyperdrive.h Outdated
JSG_LAZY_READONLY_INSTANCE_PROPERTY(database, getDatabase);
JSG_LAZY_READONLY_INSTANCE_PROPERTY(user, getUser);
JSG_LAZY_READONLY_INSTANCE_PROPERTY(password, getPassword);
JSG_LAZY_READONLY_INSTANCE_PROPERTY(scheme, getScheme);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want to be in the business of supporting more public fields/methods in workerd than in the production workers runtime. We should avoid exposing this for now.

Comment thread src/workerd/api/hyperdrive.c++ Outdated
f.fulfill(kj::none);
return kj::mv(stream);
}, [&f = *paf.fulfiller](kj::Exception e) {
KJ_LOG(WARNING, "failed to connect to local hyperdrive process", e);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was it intentional that this was left as is?

kj::String password;
kj::String scheme;
bool registeredConnectOverride = false;
kj::Promise<kj::Own<kj::AsyncIoStream>> connectToDb();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style nit, but it'd be nice to put an empty line in between the class's member variables and any private functions just to more cleanly visually separate them. When scanning over this I initially was trying to figure out why we needed a connectToDb variable before I stopped to take a closer look.

Comment thread src/workerd/api/hyperdrive.c++ Outdated
auto connectReq = kj::newHttpClient(*service)->connect(
kj::str(getHost(), ":", getPort()), headers, kj::HttpConnectSettings{});

// auto conectionRequest =
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgot to delete this

@tmthecoder tmthecoder force-pushed the tejas/add-hyperdrive-bindings branch from fb15483 to 1d1206f Compare October 12, 2023 19:09
Copy link
Copy Markdown
Member

@a-robinson a-robinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @tmthecoder !

@tmthecoder tmthecoder force-pushed the tejas/add-hyperdrive-bindings branch from 1d1206f to 50c27e6 Compare October 12, 2023 20:55
@a-robinson
Copy link
Copy Markdown
Member

Just to be clear, I'll merge this as soon as the tests are green, but given that your branch is on your fork rather than the main repo, the builds are likely to take a few hours.

@tmthecoder
Copy link
Copy Markdown
Contributor Author

@a-robinson alright, sounds good. Thanks!

@a-robinson a-robinson merged commit 262307f into cloudflare:main Oct 12, 2023
@a-robinson
Copy link
Copy Markdown
Member

Aaaand I forgot to squash the commits down :( I'm sorry for making the history messier, anyone who's reading this.

a-robinson added a commit to a-robinson/wrangler2 that referenced this pull request Oct 13, 2023
Support is already in progress (see
cloudflare/workerd#1266) and should be coming in
the next few weeks, but we've already had at least one user get very
confused by this and cause us to spend time on debugging before
realizing the problem was that they were talking about problems in
wrangler dev rather than at the edge. This is an easy way to attempt to
mitigate that for now.
rozenmd pushed a commit to cloudflare/workers-sdk that referenced this pull request Oct 13, 2023
Support is already in progress (see
cloudflare/workerd#1266) and should be coming in
the next few weeks, but we've already had at least one user get very
confused by this and cause us to spend time on debugging before
realizing the problem was that they were talking about problems in
wrangler dev rather than at the edge. This is an easy way to attempt to
mitigate that for now.
thomasgauvin added a commit to thomasgauvin/workers-sdk that referenced this pull request May 13, 2024
…g does not work

Description Hyperdrive is supported locally (see cloudflare/workerd#1266) and this warning is not longer accurate. It was added while the support was in progress to avoid confusion (cloudflare@54800f6), but now that local support for Hyperdrive bindings has been added, this log is incorrect and should be removed
petebacondarwin pushed a commit to cloudflare/workers-sdk that referenced this pull request May 20, 2024
…g does not work (#5812)

* Remove Hyperdrive warning log indicating that Hyperdrive local binding does not work

Description Hyperdrive is supported locally (see cloudflare/workerd#1266) and this warning is not longer accurate. It was added while the support was in progress to avoid confusion (54800f6), but now that local support for Hyperdrive bindings has been added, this log is incorrect and should be removed

* Add changeset

* Update .changeset/thirty-kings-serve.md

Co-authored-by: Matt <granjef3@gmail.com>

* Nit changeset fix

---------

Co-authored-by: Matt <granjef3@gmail.com>
Comment on lines +77 to +80
kj::String Hyperdrive::getConnectionString() {
return kj::str(getScheme(), "://", getUser(), ":", getPassword(), "@", getHost(), ":", getPort(),
"/", getDatabase(), "?sslmode=disable");
}
Copy link
Copy Markdown
Collaborator

@thomasgauvin thomasgauvin Aug 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tmthecoder @a-robinson this hardcodes sslmode=disable. This prevents connection to remote databases such as Azure, Neon, etc. when developing locally. Can we have a way to connect to these databases which needs sslmode=require, while retaining the ability to connect to local Postgres with does need sslmode=disable?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have a way to connect to these databases which needs sslmode=require, while retaining the ability to connect to local Postgres with does need sslmode=disable?

If you want to support remote databases that require SSL but also local DBs that don't support it, it sounds like what we want for local mode is sslmode=prefer, which allows SSL but doesn't require it.

It should be possible to vary the default sslmode in workerd compared to on the edge, but I'd suggest bringing it up internally either in chat or as a ticket so we don't lose track of it.

And I wouldn't expect Tejas to respond given that his internship ended last year :)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants