mirror of
https://github.com/denoland/deno.git
synced 2024-12-23 15:49:44 -05:00
feat: stabilize Deno.HttpServer.shutdown and Unix socket support (#21463)
This commit stabilizes "Deno.HttpServer.shutdown" API as well as Unix socket support in "Deno.serve" API. --------- Co-authored-by: Yoshiya Hinosawa <stibium121@gmail.com>
This commit is contained in:
parent
e372fc73e8
commit
a931a47511
3 changed files with 130 additions and 142 deletions
125
cli/tsc/dts/lib.deno.ns.d.ts
vendored
125
cli/tsc/dts/lib.deno.ns.d.ts
vendored
|
@ -5939,6 +5939,50 @@ declare namespace Deno {
|
|||
handler: ServeHandler;
|
||||
}
|
||||
|
||||
export interface ServeUnixOptions {
|
||||
/** The unix domain socket path to listen on. */
|
||||
path: string;
|
||||
|
||||
/** An {@linkcode AbortSignal} to close the server and all connections. */
|
||||
signal?: AbortSignal;
|
||||
|
||||
/** The handler to invoke when route handlers throw an error. */
|
||||
onError?: (error: unknown) => Response | Promise<Response>;
|
||||
|
||||
/** The callback which is called when the server starts listening. */
|
||||
onListen?: (params: { path: string }) => void;
|
||||
}
|
||||
|
||||
/** Information for a unix domain socket HTTP request.
|
||||
*
|
||||
* @category HTTP Server
|
||||
*/
|
||||
export interface ServeUnixHandlerInfo {
|
||||
/** The remote address of the connection. */
|
||||
remoteAddr: Deno.UnixAddr;
|
||||
}
|
||||
|
||||
/** A handler for unix domain socket HTTP requests. Consumes a request and returns a response.
|
||||
*
|
||||
* If a handler throws, the server calling the handler will assume the impact
|
||||
* of the error is isolated to the individual request. It will catch the error
|
||||
* and if necessary will close the underlying connection.
|
||||
*
|
||||
* @category HTTP Server
|
||||
*/
|
||||
export type ServeUnixHandler = (
|
||||
request: Request,
|
||||
info: ServeUnixHandlerInfo,
|
||||
) => Response | Promise<Response>;
|
||||
|
||||
/**
|
||||
* @category HTTP Server
|
||||
*/
|
||||
export interface ServeUnixInit {
|
||||
/** The handler to invoke to process each incoming request. */
|
||||
handler: ServeUnixHandler;
|
||||
}
|
||||
|
||||
/** An instance of the server created using `Deno.serve()` API.
|
||||
*
|
||||
* @category HTTP Server
|
||||
|
@ -5959,6 +6003,11 @@ declare namespace Deno {
|
|||
|
||||
/** Make the server not block the event loop from finishing. */
|
||||
unref(): void;
|
||||
|
||||
/** Gracefully close the server. No more new connections will be accepted,
|
||||
* while pending requests will be allowed to finish.
|
||||
*/
|
||||
shutdown(): Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5978,6 +6027,55 @@ declare namespace Deno {
|
|||
* @category HTTP Server
|
||||
*/
|
||||
export function serve(handler: ServeHandler): HttpServer;
|
||||
/** Serves HTTP requests with the given option bag and handler.
|
||||
*
|
||||
* You can specify the socket path with `path` option.
|
||||
*
|
||||
* ```ts
|
||||
* Deno.serve(
|
||||
* { path: "path/to/socket" },
|
||||
* (_req) => new Response("Hello, world")
|
||||
* );
|
||||
* ```
|
||||
*
|
||||
* You can stop the server with an {@linkcode AbortSignal}. The abort signal
|
||||
* needs to be passed as the `signal` option in the options bag. The server
|
||||
* aborts when the abort signal is aborted. To wait for the server to close,
|
||||
* await the promise returned from the `Deno.serve` API.
|
||||
*
|
||||
* ```ts
|
||||
* const ac = new AbortController();
|
||||
*
|
||||
* const server = Deno.serve(
|
||||
* { signal: ac.signal, path: "path/to/socket" },
|
||||
* (_req) => new Response("Hello, world")
|
||||
* );
|
||||
* server.finished.then(() => console.log("Server closed"));
|
||||
*
|
||||
* console.log("Closing server...");
|
||||
* ac.abort();
|
||||
* ```
|
||||
*
|
||||
* By default `Deno.serve` prints the message
|
||||
* `Listening on path/to/socket` on listening. If you like to
|
||||
* change this behavior, you can specify a custom `onListen` callback.
|
||||
*
|
||||
* ```ts
|
||||
* Deno.serve({
|
||||
* onListen({ path }) {
|
||||
* console.log(`Server started at ${path}`);
|
||||
* // ... more info specific to your server ..
|
||||
* },
|
||||
* path: "path/to/socket",
|
||||
* }, (_req) => new Response("Hello, world"));
|
||||
* ```
|
||||
*
|
||||
* @category HTTP Server
|
||||
*/
|
||||
export function serve(
|
||||
options: ServeUnixOptions,
|
||||
handler: ServeUnixHandler,
|
||||
): HttpServer;
|
||||
/** Serves HTTP requests with the given option bag and handler.
|
||||
*
|
||||
* You can specify an object with a port and hostname option, which is the
|
||||
|
@ -6038,6 +6136,33 @@ declare namespace Deno {
|
|||
options: ServeOptions | ServeTlsOptions,
|
||||
handler: ServeHandler,
|
||||
): HttpServer;
|
||||
/** Serves HTTP requests with the given option bag.
|
||||
*
|
||||
* You can specify an object with the path option, which is the
|
||||
* unix domain socket to listen on.
|
||||
*
|
||||
* ```ts
|
||||
* const ac = new AbortController();
|
||||
*
|
||||
* const server = Deno.serve({
|
||||
* path: "path/to/socket",
|
||||
* handler: (_req) => new Response("Hello, world"),
|
||||
* signal: ac.signal,
|
||||
* onListen({ path }) {
|
||||
* console.log(`Server started at ${path}`);
|
||||
* },
|
||||
* });
|
||||
* server.finished.then(() => console.log("Server closed"));
|
||||
*
|
||||
* console.log("Closing server...");
|
||||
* ac.abort();
|
||||
* ```
|
||||
*
|
||||
* @category HTTP Server
|
||||
*/
|
||||
export function serve(
|
||||
options: ServeUnixInit & ServeUnixOptions,
|
||||
): HttpServer;
|
||||
/** Serves HTTP requests with the given option bag.
|
||||
*
|
||||
* You can specify an object with a port and hostname option, which is the
|
||||
|
|
132
cli/tsc/dts/lib.deno.unstable.d.ts
vendored
132
cli/tsc/dts/lib.deno.unstable.d.ts
vendored
|
@ -2099,138 +2099,6 @@ declare namespace Deno {
|
|||
readonly value: bigint;
|
||||
}
|
||||
|
||||
/** An instance of the server created using `Deno.serve()` API.
|
||||
*
|
||||
* @category HTTP Server
|
||||
*/
|
||||
export interface HttpServer {
|
||||
/** Gracefully close the server. No more new connections will be accepted,
|
||||
* while pending requests will be allowed to finish.
|
||||
*/
|
||||
shutdown(): Promise<void>;
|
||||
}
|
||||
|
||||
export interface ServeUnixOptions {
|
||||
/** The unix domain socket path to listen on. */
|
||||
path: string;
|
||||
|
||||
/** An {@linkcode AbortSignal} to close the server and all connections. */
|
||||
signal?: AbortSignal;
|
||||
|
||||
/** The handler to invoke when route handlers throw an error. */
|
||||
onError?: (error: unknown) => Response | Promise<Response>;
|
||||
|
||||
/** The callback which is called when the server starts listening. */
|
||||
onListen?: (params: { path: string }) => void;
|
||||
}
|
||||
|
||||
/** Information for a unix domain socket HTTP request.
|
||||
*
|
||||
* @category HTTP Server
|
||||
*/
|
||||
export interface ServeUnixHandlerInfo {
|
||||
/** The remote address of the connection. */
|
||||
remoteAddr: Deno.UnixAddr;
|
||||
}
|
||||
|
||||
/** A handler for unix domain socket HTTP requests. Consumes a request and returns a response.
|
||||
*
|
||||
* If a handler throws, the server calling the handler will assume the impact
|
||||
* of the error is isolated to the individual request. It will catch the error
|
||||
* and if necessary will close the underlying connection.
|
||||
*
|
||||
* @category HTTP Server
|
||||
*/
|
||||
export type ServeUnixHandler = (
|
||||
request: Request,
|
||||
info: ServeUnixHandlerInfo,
|
||||
) => Response | Promise<Response>;
|
||||
|
||||
/**
|
||||
* @category HTTP Server
|
||||
*/
|
||||
export interface ServeUnixInit {
|
||||
/** The handler to invoke to process each incoming request. */
|
||||
handler: ServeUnixHandler;
|
||||
}
|
||||
|
||||
/** Serves HTTP requests with the given option bag and handler.
|
||||
*
|
||||
* You can specify the socket path with `path` option.
|
||||
*
|
||||
* ```ts
|
||||
* Deno.serve(
|
||||
* { path: "path/to/socket" },
|
||||
* (_req) => new Response("Hello, world")
|
||||
* );
|
||||
* ```
|
||||
*
|
||||
* You can stop the server with an {@linkcode AbortSignal}. The abort signal
|
||||
* needs to be passed as the `signal` option in the options bag. The server
|
||||
* aborts when the abort signal is aborted. To wait for the server to close,
|
||||
* await the promise returned from the `Deno.serve` API.
|
||||
*
|
||||
* ```ts
|
||||
* const ac = new AbortController();
|
||||
*
|
||||
* const server = Deno.serve(
|
||||
* { signal: ac.signal, path: "path/to/socket" },
|
||||
* (_req) => new Response("Hello, world")
|
||||
* );
|
||||
* server.finished.then(() => console.log("Server closed"));
|
||||
*
|
||||
* console.log("Closing server...");
|
||||
* ac.abort();
|
||||
* ```
|
||||
*
|
||||
* By default `Deno.serve` prints the message
|
||||
* `Listening on path/to/socket` on listening. If you like to
|
||||
* change this behavior, you can specify a custom `onListen` callback.
|
||||
*
|
||||
* ```ts
|
||||
* Deno.serve({
|
||||
* onListen({ path }) {
|
||||
* console.log(`Server started at ${path}`);
|
||||
* // ... more info specific to your server ..
|
||||
* },
|
||||
* path: "path/to/socket",
|
||||
* }, (_req) => new Response("Hello, world"));
|
||||
* ```
|
||||
*
|
||||
* @category HTTP Server
|
||||
*/
|
||||
export function serve(
|
||||
options: ServeUnixOptions,
|
||||
handler: ServeUnixHandler,
|
||||
): Server;
|
||||
/** Serves HTTP requests with the given option bag.
|
||||
*
|
||||
* You can specify an object with the path option, which is the
|
||||
* unix domain socket to listen on.
|
||||
*
|
||||
* ```ts
|
||||
* const ac = new AbortController();
|
||||
*
|
||||
* const server = Deno.serve({
|
||||
* path: "path/to/socket",
|
||||
* handler: (_req) => new Response("Hello, world"),
|
||||
* signal: ac.signal,
|
||||
* onListen({ path }) {
|
||||
* console.log(`Server started at ${path}`);
|
||||
* },
|
||||
* });
|
||||
* server.finished.then(() => console.log("Server closed"));
|
||||
*
|
||||
* console.log("Closing server...");
|
||||
* ac.abort();
|
||||
* ```
|
||||
*
|
||||
* @category HTTP Server
|
||||
*/
|
||||
export function serve(
|
||||
options: ServeUnixInit & ServeUnixOptions,
|
||||
): Server;
|
||||
|
||||
/**
|
||||
* A namespace containing runtime APIs available in Jupyter notebooks.
|
||||
*
|
||||
|
|
|
@ -87,6 +87,11 @@ static USE_WRITEV: Lazy<bool> = Lazy::new(|| {
|
|||
false
|
||||
});
|
||||
|
||||
// NOTE(bartlomieju): currently we don't have any unstable HTTP features,
|
||||
// but let's keep this const here, because:
|
||||
// a) we still need to support `--unstable-http` flag to not break user's CLI;
|
||||
// b) we might add more unstable features in the future.
|
||||
#[allow(dead_code)]
|
||||
pub const UNSTABLE_FEATURE_NAME: &str = "http";
|
||||
|
||||
/// All HTTP/2 connections start with this byte string.
|
||||
|
@ -1183,16 +1188,6 @@ pub async fn op_http_close(
|
|||
|
||||
if graceful {
|
||||
http_general_trace!("graceful shutdown");
|
||||
// TODO(bartlomieju): replace with `state.feature_checker.check_or_exit`
|
||||
// once we phase out `check_or_exit_with_legacy_fallback`
|
||||
state
|
||||
.borrow()
|
||||
.feature_checker
|
||||
.check_or_exit_with_legacy_fallback(
|
||||
UNSTABLE_FEATURE_NAME,
|
||||
"Deno.Server.shutdown",
|
||||
);
|
||||
|
||||
// In a graceful shutdown, we close the listener and allow all the remaining connections to drain
|
||||
join_handle.listen_cancel_handle().cancel();
|
||||
poll_fn(|cx| join_handle.server_state.poll_complete(cx)).await;
|
||||
|
|
Loading…
Reference in a new issue