github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/net/server_unix.go (about) 1 // +build linux darwin netbsd freebsd openbsd dragonfly 2 3 package net 4 5 import ( 6 "os" 7 "os/signal" 8 "runtime" 9 "sync" 10 "syscall" 11 "time" 12 13 "github.com/angenalZZZ/gofunc/net/internal/netpoll" 14 ) 15 16 type server struct { 17 ln *listener // all the listeners 18 wg sync.WaitGroup // event-loop close WaitGroup 19 opts *Options // options with server 20 once sync.Once // make sure only signalShutdown once 21 cond *sync.Cond // shutdown signaler 22 codec ICodec // codec for TCP stream 23 logger Logger // customized logger for logging info 24 ticktock chan time.Duration // ticker channel 25 mainLoop *eventloop // main loop for accepting connections 26 eventHandler EventHandler // user eventHandler 27 subEventLoopSet loadBalancer // event-loops for handling events 28 } 29 30 // waitForShutdown waits for a signal to shutdown 31 func (svr *server) waitForShutdown() { 32 svr.cond.L.Lock() 33 svr.cond.Wait() 34 svr.cond.L.Unlock() 35 } 36 37 // signalShutdown signals a shutdown an begins server closing 38 func (svr *server) signalShutdown() { 39 svr.once.Do(func() { 40 svr.cond.L.Lock() 41 svr.cond.Signal() 42 svr.cond.L.Unlock() 43 }) 44 } 45 46 func (svr *server) startLoops() { 47 svr.subEventLoopSet.iterate(func(i int, el *eventloop) bool { 48 svr.wg.Add(1) 49 go func() { 50 el.loopRun() 51 svr.wg.Done() 52 }() 53 return true 54 }) 55 } 56 57 func (svr *server) closeLoops() { 58 svr.subEventLoopSet.iterate(func(i int, el *eventloop) bool { 59 _ = el.poller.Close() 60 return true 61 }) 62 } 63 64 func (svr *server) startReactors() { 65 svr.subEventLoopSet.iterate(func(i int, el *eventloop) bool { 66 svr.wg.Add(1) 67 go func() { 68 svr.activateSubReactor(el) 69 svr.wg.Done() 70 }() 71 return true 72 }) 73 } 74 75 func (svr *server) activateLoops(numEventLoop int) error { 76 // Create loops locally and bind the listeners. 77 for i := 0; i < numEventLoop; i++ { 78 if p, err := netpoll.OpenPoller(); err == nil { 79 el := &eventloop{ 80 svr: svr, 81 codec: svr.codec, 82 poller: p, 83 packet: make([]byte, 0x10000), 84 connections: make(map[int]*conn), 85 eventHandler: svr.eventHandler, 86 calibrateCallback: svr.subEventLoopSet.calibrate, 87 } 88 _ = el.poller.AddRead(svr.ln.fd) 89 svr.subEventLoopSet.register(el) 90 } else { 91 return err 92 } 93 } 94 // Start loops in background 95 svr.startLoops() 96 return nil 97 } 98 99 func (svr *server) activateReactors(numEventLoop int) error { 100 for i := 0; i < numEventLoop; i++ { 101 if p, err := netpoll.OpenPoller(); err == nil { 102 el := &eventloop{ 103 svr: svr, 104 codec: svr.codec, 105 poller: p, 106 packet: make([]byte, 0x10000), 107 connections: make(map[int]*conn), 108 eventHandler: svr.eventHandler, 109 calibrateCallback: svr.subEventLoopSet.calibrate, 110 } 111 svr.subEventLoopSet.register(el) 112 } else { 113 return err 114 } 115 } 116 117 // Start sub reactors. 118 svr.startReactors() 119 120 if p, err := netpoll.OpenPoller(); err == nil { 121 el := &eventloop{ 122 idx: -1, 123 poller: p, 124 svr: svr, 125 } 126 _ = el.poller.AddRead(svr.ln.fd) 127 svr.mainLoop = el 128 // Start main reactor. 129 svr.wg.Add(1) 130 go func() { 131 svr.activateMainReactor() 132 svr.wg.Done() 133 }() 134 } else { 135 return err 136 } 137 return nil 138 } 139 140 func (svr *server) start(numEventLoop int) error { 141 if svr.opts.ReusePort || svr.ln.pconn != nil { 142 return svr.activateLoops(numEventLoop) 143 } 144 return svr.activateReactors(numEventLoop) 145 } 146 147 func (svr *server) stop() { 148 // Wait on a signal for shutdown 149 svr.waitForShutdown() 150 151 // Notify all loops to close by closing all listeners 152 svr.subEventLoopSet.iterate(func(i int, el *eventloop) bool { 153 sniffErrorAndLog(el.poller.Trigger(func() error { 154 return errServerShutdown 155 })) 156 return true 157 }) 158 159 if svr.mainLoop != nil { 160 svr.ln.close() 161 sniffErrorAndLog(svr.mainLoop.poller.Trigger(func() error { 162 return errServerShutdown 163 })) 164 } 165 166 // Wait on all loops to complete reading events 167 svr.wg.Wait() 168 169 svr.closeLoops() 170 171 if svr.mainLoop != nil { 172 sniffErrorAndLog(svr.mainLoop.poller.Close()) 173 } 174 } 175 176 func serve(eventHandler EventHandler, listener *listener, options *Options) error { 177 // Figure out the correct number of loops/goroutines to use. 178 numEventLoop := 1 179 if options.Multicore { 180 numEventLoop = runtime.NumCPU() 181 } 182 if options.NumEventLoop > 0 { 183 numEventLoop = options.NumEventLoop 184 } 185 186 svr := new(server) 187 svr.opts = options 188 svr.eventHandler = eventHandler 189 svr.ln = listener 190 191 switch options.LB { 192 case RoundRobin: 193 svr.subEventLoopSet = new(roundRobinEventLoopSet) 194 case LeastConnections: 195 svr.subEventLoopSet = new(leastConnectionsEventLoopSet) 196 case SourceAddrHash: 197 svr.subEventLoopSet = new(sourceAddrHashEventLoopSet) 198 } 199 200 svr.cond = sync.NewCond(&sync.Mutex{}) 201 svr.ticktock = make(chan time.Duration, 1) 202 svr.logger = func() Logger { 203 if options.Logger == nil { 204 return defaultLogger 205 } 206 return options.Logger 207 }() 208 svr.codec = func() ICodec { 209 if options.Codec == nil { 210 return new(BuiltInFrameCodec) 211 } 212 return options.Codec 213 }() 214 215 server := Server{ 216 svr: svr, 217 Multicore: options.Multicore, 218 Addr: listener.lnaddr, 219 NumEventLoop: numEventLoop, 220 ReusePort: options.ReusePort, 221 TCPKeepAlive: options.TCPKeepAlive, 222 } 223 switch svr.eventHandler.OnInitComplete(server) { 224 case None: 225 case Shutdown: 226 return nil 227 } 228 defer svr.eventHandler.OnShutdown(server) 229 230 shutdown := make(chan os.Signal, 1) 231 signal.Notify(shutdown, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) 232 defer close(shutdown) 233 234 go func() { 235 if <-shutdown == nil { 236 return 237 } 238 svr.signalShutdown() 239 }() 240 241 if err := svr.start(numEventLoop); err != nil { 242 svr.closeLoops() 243 svr.logger.Printf("gnet server is stoping with error: %v\n", err) 244 return err 245 } 246 defer svr.stop() 247 248 return nil 249 }