简体   繁体   中英

Pin Golang goroutine or channel to request/response

From what I know, the default http router as well as the gorilla/mux router put each incoming HTTP request entrypoint on its own goroutine. Like Node.js domains, where we can pin a request to a domain, can we pin a request in Golang to a goroutine, and if there is any panic in the goroutine, we respond with an error instead of shutting down the server?

In node.js, it might look like:

const domain = require('domain');
const http = require('http');

const server = http.createServer((req,res) => {

  const d = domain.create();

  d.once('error', e =>{
     res.json({error:e}); // check res.headersSent to see if already sent
  });

  res.once('finish', () => {
     d.removeAllListeners(); // prevent memory leak
  });

  d.run(() => {
     handleRequest(req,res);
  });


});

is there a way to do something similar with goroutines in Golang?

The net/http server starts a goroutine for each connection and invokes the root handler on that goroutine. All routers that I know of call through to registered handlers on goroutine the router was called on. One way or another handlers are typically called on the goroutine started on the net/http server. All execution for the request is on that goroutine unless the request handler directly or indirectly starts another goroutine to do work on behalf of the request handler. Because the request handler is in control of the goroutines used, there's no need to "pin" a goroutine to a request.

The net/http server recovers panics on the per connection goroutine. Here's what the documentation says about it :

If ServeHTTP panics, the server (the caller of ServeHTTP) assumes that the effect of the panic was isolated to the active request. It recovers the panic, logs a stack trace to the server error log, and either closes the network connection or sends an HTTP/2 RST_STREAM, depending on the HTTP protocol. To abort a handler so the client sees an interrupted response but the server doesn't log an error, panic with the value ErrAbortHandler.

Request handlers can be wrapped with middleware to recover panics with application supplied logic. The Gorilla handlers package is one example of how to do this.

If the request handler does start a goroutine to do work on behalf of the request, it's the request handler's responsibility to establish a recover in that goroutine.

Yes, you can recover from a goroutine panics. This middleware from gorilla does it but it is also easy to do yourself. It's basically just wrapping your handler in a function that defers calling recover() and handling the panic from there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM