1
1
package pulse
2
2
3
3
import (
4
- "errors "
4
+ "context "
5
5
"fmt"
6
6
"github.com/common-nighthawk/go-figure"
7
7
"net"
8
8
"net/http"
9
- "sync "
9
+ "time "
10
10
)
11
11
12
12
type (
13
13
Pulse struct {
14
14
config * Config
15
15
server * http.Server
16
16
Router * Router
17
- mx sync.Mutex
18
17
}
19
18
20
19
Config struct {
@@ -38,6 +37,7 @@ func New(config ...Config) *Pulse {
38
37
app := & Pulse {
39
38
config : & Config {},
40
39
server : & http.Server {},
40
+ Router : NewRouter (),
41
41
}
42
42
43
43
if len (config ) > 0 {
@@ -55,51 +55,58 @@ func New(config ...Config) *Pulse {
55
55
return app
56
56
}
57
57
58
- func (f * Pulse ) Run (address string ) {
59
- f .mx .Lock ()
60
- defer f .mx .Unlock ()
58
+ func (p * Pulse ) Run (address string ) {
61
59
// setup handler
62
- handler := RouterHandler (f .Router )
63
- f .server .Handler = handler
60
+ handler := RouterHandler (p .Router )
61
+ p .server .Handler = handler
64
62
65
63
// setup listener
66
- listener , err := net .Listen (f .config .Network , address )
64
+ listener , err := net .Listen (p .config .Network , address )
67
65
if err != nil {
68
66
panic (fmt .Errorf ("failed to listen: %v" , err ))
69
67
}
70
68
71
69
// print startup message
72
- fmt .Println (f .startupMessage (listener .Addr ().String ()))
70
+ fmt .Println (p .startupMessage (listener .Addr ().String ()))
73
71
74
72
// start server
75
- err = f .server .Serve (listener )
73
+ err = p .server .Serve (listener )
76
74
if err != nil {
77
75
fmt .Errorf ("failed to start server on %s: %v" , listener .Addr ().String (), err )
78
76
}
79
77
}
80
78
81
- func (f * Pulse ) Stop () error {
82
- f .mx .Lock ()
83
- defer f .mx .Unlock ()
84
-
85
- if f .server == nil {
86
- return errors .New ("server not running" )
79
+ func (p * Pulse ) Stop () error {
80
+ // Check if the server is already stopped.
81
+ if p .server == nil {
82
+ return nil
87
83
}
88
- err := f .server .Shutdown (nil )
84
+
85
+ // Disable HTTP keep-alive connections to prevent the server from
86
+ // accepting any new requests.
87
+ p .server .SetKeepAlivesEnabled (false )
88
+
89
+ // Shutdown the server gracefully to allow existing connections to finish.
90
+ ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
91
+ defer cancel ()
92
+ err := p .server .Shutdown (ctx )
89
93
if err != nil {
90
- return fmt .Errorf ("failed to stop server: %v" , err )
94
+ return fmt .Errorf ("failed to shut down server: %v" , err )
91
95
}
92
- f .server = nil
96
+
97
+ // Set the server to a new instance of http.Server to allow starting it again.
98
+ p .server = & http.Server {}
99
+
93
100
return nil
94
101
}
95
102
96
- func (f * Pulse ) startupMessage (addr string ) string {
103
+ func (p * Pulse ) startupMessage (addr string ) string {
97
104
myFigure := figure .NewFigure ("PULSE" , "" , true )
98
105
myFigure .Print ()
99
106
100
107
var textOne = "=> Server started on <%s>" + "\n "
101
108
var textTwo = "=> App Name: %s" + "\n "
102
109
var textThree = "=> Press CTRL+C to stop" + "\n "
103
110
104
- return fmt .Sprintf (textOne , addr ) + fmt .Sprintf (textTwo , f .config .AppName ) + fmt .Sprintf (textThree )
111
+ return fmt .Sprintf (textOne , addr ) + fmt .Sprintf (textTwo , p .config .AppName ) + fmt .Sprintf (textThree )
105
112
}
0 commit comments