github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/net/server_windows.go (about) 1 // +build windows 2 3 package net 4 5 import ( 6 "errors" 7 "os" 8 "os/signal" 9 "runtime" 10 "sync" 11 "syscall" 12 "time" 13 ) 14 15 // commandBufferSize represents the buffer size of event-loop command channel on Windows. 16 const ( 17 commandBufferSize = 512 18 ) 19 20 var errCloseAllConns = errors.New("close all connections in event-loop") 21 22 type server struct { 23 ln *listener // all the listeners 24 cond *sync.Cond // shutdown signaler 25 opts *Options // options with server 26 serr error // signal error 27 once sync.Once // make sure only signalShutdown once 28 codec ICodec // codec for TCP stream 29 loopWG sync.WaitGroup // loop close WaitGroup 30 logger Logger // customized logger for logging info 31 ticktock chan time.Duration // ticker channel 32 listenerWG sync.WaitGroup // listener close WaitGroup 33 eventHandler EventHandler // user eventHandler 34 subEventLoopSet loadBalancer // event-loops for handling events 35 } 36 37 // waitForShutdown waits for a signal to shutdown. 38 func (svr *server) waitForShutdown() error { 39 svr.cond.L.Lock() 40 svr.cond.Wait() 41 err := svr.serr 42 svr.cond.L.Unlock() 43 return err 44 } 45 46 // signalShutdown signals a shutdown an begins server closing. 47 func (svr *server) signalShutdown(err error) { 48 svr.once.Do(func() { 49 svr.cond.L.Lock() 50 svr.serr = err 51 svr.cond.Signal() 52 svr.cond.L.Unlock() 53 }) 54 } 55 56 func (svr *server) startListener() { 57 svr.listenerWG.Add(1) 58 go func() { 59 svr.listenerRun() 60 svr.listenerWG.Done() 61 }() 62 } 63 64 func (svr *server) startLoops(numEventLoop int) { 65 for i := 0; i < numEventLoop; i++ { 66 el := &eventloop{ 67 ch: make(chan interface{}, commandBufferSize), 68 svr: svr, 69 codec: svr.codec, 70 connections: make(map[*stdConn]struct{}), 71 eventHandler: svr.eventHandler, 72 calibrateCallback: svr.subEventLoopSet.calibrate, 73 } 74 svr.subEventLoopSet.register(el) 75 } 76 77 svr.loopWG.Add(svr.subEventLoopSet.len()) 78 svr.subEventLoopSet.iterate(func(i int, el *eventloop) bool { 79 go el.loopRun() 80 return true 81 }) 82 } 83 84 func (svr *server) stop() { 85 // Wait on a signal for shutdown. 86 svr.logger.Printf("server is being shutdown with err: %v\n", svr.waitForShutdown()) 87 88 // Close listener. 89 svr.ln.close() 90 svr.listenerWG.Wait() 91 92 // Notify all loops to close. 93 svr.subEventLoopSet.iterate(func(i int, el *eventloop) bool { 94 el.ch <- errServerShutdown 95 return true 96 }) 97 98 // Wait on all loops to close. 99 svr.loopWG.Wait() 100 101 // Close all connections. 102 svr.loopWG.Add(svr.subEventLoopSet.len()) 103 svr.subEventLoopSet.iterate(func(i int, el *eventloop) bool { 104 el.ch <- errCloseAllConns 105 return true 106 }) 107 svr.loopWG.Wait() 108 } 109 110 func serve(eventHandler EventHandler, listener *listener, options *Options) (err error) { 111 // Figure out the correct number of loops/goroutines to use. 112 numEventLoop := 1 113 if options.Multicore { 114 numEventLoop = runtime.NumCPU() 115 } 116 if options.NumEventLoop > 0 { 117 numEventLoop = options.NumEventLoop 118 } 119 120 svr := new(server) 121 svr.opts = options 122 svr.eventHandler = eventHandler 123 svr.ln = listener 124 125 switch options.LB { 126 case RoundRobin: 127 svr.subEventLoopSet = new(roundRobinEventLoopSet) 128 case LeastConnections: 129 svr.subEventLoopSet = new(leastConnectionsEventLoopSet) 130 case SourceAddrHash: 131 svr.subEventLoopSet = new(sourceAddrHashEventLoopSet) 132 } 133 134 svr.ticktock = make(chan time.Duration, 1) 135 svr.cond = sync.NewCond(&sync.Mutex{}) 136 svr.logger = func() Logger { 137 if options.Logger == nil { 138 return defaultLogger 139 } 140 return options.Logger 141 }() 142 svr.codec = func() ICodec { 143 if options.Codec == nil { 144 return new(BuiltInFrameCodec) 145 } 146 return options.Codec 147 }() 148 149 server := Server{ 150 svr: svr, 151 Multicore: options.Multicore, 152 Addr: listener.lnaddr, 153 NumEventLoop: numEventLoop, 154 ReusePort: options.ReusePort, 155 TCPKeepAlive: options.TCPKeepAlive, 156 } 157 switch svr.eventHandler.OnInitComplete(server) { 158 case None: 159 case Shutdown: 160 return 161 } 162 defer svr.eventHandler.OnShutdown(server) 163 164 shutdown := make(chan os.Signal, 1) 165 signal.Notify(shutdown, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) 166 defer close(shutdown) 167 168 go func() { 169 if <-shutdown == nil { 170 return 171 } 172 svr.signalShutdown(errors.New("caught OS signal")) 173 }() 174 175 // Start all loops. 176 svr.startLoops(numEventLoop) 177 // Start listener. 178 svr.startListener() 179 defer svr.stop() 180 181 return 182 }