1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

net.http: add a close method to immediatly close the listener of a started http.Server, add more tests (#11248)

This commit is contained in:
Fabricio Pashaj
2021-08-24 19:21:24 +03:00
committed by GitHub
parent 3c85a03b8a
commit 0bf9197f41
3 changed files with 145 additions and 16 deletions

View File

@@ -7,12 +7,24 @@ import io
import net
import time
// ServerStatus is the current status of the server.
// .running means that the server is active and serving.
// .stopped means that the server is not active but still listening.
// .closed means that the server is completely inactive.
pub enum ServerStatus {
running
stopped
closed
}
interface Handler {
handle(Request) Response
}
pub struct Server {
stop_signal chan bool = chan bool{cap: 1}
mut:
state ServerStatus = .closed
listener net.TcpListener
pub mut:
port int = 8080
handler Handler = DebugHandler{}
@@ -21,22 +33,20 @@ pub mut:
accept_timeout time.Duration = 30 * time.second
}
pub fn (s &Server) listen_and_serve() ? {
pub fn (mut s Server) listen_and_serve() ? {
if s.handler is DebugHandler {
eprintln('Server handler not set, using debug handler')
}
mut l := net.listen_tcp(.ip6, ':$s.port') ?
l.set_accept_timeout(s.accept_timeout)
s.listener = net.listen_tcp(.ip6, ':$s.port') ?
s.listener.set_accept_timeout(s.accept_timeout)
eprintln('Listening on :$s.port')
s.state = .running
for {
// break if we have a stop signal (non-blocking check)
select {
_ := <-s.stop_signal {
break
}
else {}
// break if we have a stop signal
if s.state != .running {
break
}
mut conn := l.accept() or {
mut conn := s.listener.accept() or {
if err.msg != 'net: op timed out' {
eprintln('accept() failed: $err; skipping')
}
@@ -47,10 +57,27 @@ pub fn (s &Server) listen_and_serve() ? {
// TODO: make concurrent
s.parse_and_respond(mut conn)
}
if s.state == .stopped {
s.close()
}
}
pub fn (s Server) stop() {
s.stop_signal <- true
// stop signals the server that it should not respond anymore
[inline]
pub fn (mut s Server) stop() {
s.state = .stopped
}
// close immediatly closes the port and signals the server that it has been closed
[inline]
pub fn (mut s Server) close() {
s.state = .closed
s.listener.close() or { return }
}
[inline]
pub fn (s &Server) status() ServerStatus {
return s.state
}
fn (s &Server) parse_and_respond(mut conn net.TcpConn) {