WIP: builder interface for constructing servers, rework server startup code paths #1120
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Particularly after #1115, the arguments for the
HttpServerStarter::new*
family of functions is getting unwieldy. I wanted to take a stab at a builder-based constructor.But it seemed excessive to create a Builder that creates a Starter that creates the Server. So I wanted to see if I could obviate the Starter altogether. I looked into why it exists and I found #81, which I think made sense at the time. But at this point,
HttpServerStarter
has only one thing you can do with it, which is to callstart()
, and that consumesself
. By the time you have yourStarter
, it has already bound to the listening socket and there are no new ways that it can fail to start. Whatstart
does is spawn tokio tasks to actually accept connections and handle requests. But I can't see why it's useful to separate these steps. So in this implementation, you callServerBuilder::new()
, customize it, then callbuild()
(which consumesself
and can fail), and then you have your startedHttpServer
.In the process of doing this, I found that the existing code had quite a lot more bifurcation than seemed necessary in both types and code paths for TLS vs. non-TLS. So I wound up unifying these paths quite a bit. I think there's probably more cleanup that could be done here.
Since I was revisiting this interface, I also defined a new
BuildError
enum usingthiserror
. We'd previously been using aGenericError
which was just a typedef for a boxed std error (with a TODO to come up with something better). I changed all the startup code paths that produce errors to produceBuildError
instead.I believe this is not a breaking change because I implemented the existing
HttpServerStarter
in terms of the new builder.In summary: I started off trying to do one thing but wound up reworking basically the whole server startup and connection handling paths for both TLS and non-TLS. That's smaller than it sounds, but assuming we like this (which I think is not a given), this could use some careful review.
Here are some other next steps I'm considering:
ServerStarter::build_starter()
returns anHttpServerStarter
that looks just like the one we have today (i.e., one method calledstart()
). Then we'd createServerStarter::start()
that just callsbuild_starter()?.start()
.