An elegant stop program in the Go language

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.
/**go language in the implementation of graceful stop program main Goroutine listen to the operating system messages, received system Stop message after shutting down the server Chan, all the sub-process detected Chan closed, then all exit **/package mainimport ("Log" "" NET " "OS" "Os/signal" "Sync" "Syscall" "Time")//an uninteresting Service.type service struct {ch Chan boolwaitgroup *sync.w aitgroup}//make a new Service.func NewService () *service {return &service{ch:make (chan bool), Waitgroup: & Sync.  waitgroup{},}}//Accept connections and spawn a goroutine to serve each one. Stop listening//If anything is received on the service ' s Channel.func (S *service) Serve (Listener *net. TcpListener) {S.waitgroup.add (1) Defer s.waitgroup.done () for {select {case <-s.ch:log. PRINTLN ("Stopping listening on", listener. ADDR ()) listener. Close () Returndefault:}listener. Setdeadline (time. Now (). ADD (1E9)) conn, err: = Listener. ACCEPTTCP () if nil! = Err {//Determine if the error type is net. Operrorif Operr, OK: = Err. (*net. OPERROR); OK && operr.timeout () {Continue}log. PRINTLN (Err)}log. PRINTLN (Conn. Remoteaddr (), "Connected") go S.serve (conn)}}//Stop the service byClosing the service ' s channel. Block until the service//is really stopped.func (s *service) Stop () {Close (s.ch) s.waitgroup.wait ()}//Serve a connection  By reading and writing who was read.  That's right, this//are an echo service. Stop Reading and writing if anything is received on the//service ' s channel, only after writing what was Read.func (s * Service) Serve (conn *net. Tcpconn) {Defer conn. Close () S.waitgroup.add (1) Defer s.waitgroup.done () for {select {case <-s.ch:log. Println ("disconnecting", Conn. Remoteaddr ()) Returndefault:}conn. Setdeadline (time. Now (). ADD (1E9)) BUF: = Make ([]byte, 4096) If _, err: = conn. Read (BUF); Nil! = Err {if operr, OK: = Err. ( *net. OPERROR); OK && operr.timeout () {Continue}log. PRINTLN (Err) Return}if _, Err: = conn. Write (BUF); Nil! = Err {log.  PRINTLN (Err) Return}}}func main () {//Listen on 127.0.0.1:48879. That's my favorite port number because in//hex 48879 is 0xbeef.laddr, err: = Net. RESOLVETCPADDR ("TCP", "127.0.0.1:48879") if nil! = Err {log. FataLln (Err)}listener, err: = Net. LISTENTCP ("TCP", LADDR) if nil! = Err {log. Fatalln (Err)}log. Println ("Listening on", listener. ADDR ())//Make a new service and send it into the background.service: = NewService () Go service. Serve (Listener)//Handle SIGINT and sigterm.ch: = Make (chan os. Signal) Signal. Notify (CH, syscall. SIGINT, Syscall. SIGTERM) log. PRINTLN ("Signal:", <-ch)//Stop the Service Gracefully.service.Stop ()}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.