Learn how to gracefully exit the Go Network program from NSQ

Source: Internet
Author: User

Exiting a running program can be rough kill-9 $PID, but this will disrupt the integrity of the business, it is possible that one is executing in the middle of the logic, resulting in abnormal garbage data.

This article summarizes in go language, how can gracefully exit the network application, involves the knowledge including: Signal,channel,waitgroup and so on.

From here: Https://gobyexample.com/channel-synchronization can simply learn how to use the channel in go to achieve goroutines synchronization.

In NSQ, the same mechanism is used, but the encapsulation is more complicated. We use the implementation of Nsqadmin as an example for a simple analysis.

Code Snippet 1 (from: https://github.com/bitly/nsq/blob/master/nsqadmin/main.go):

Exitchan: = make (chan int)

Signalchan: = Make (chan os. Signal, 1)

Go func () {

<-signalchan

Exitchan <-1

}()

Signal. Notify (Signalchan, Syscall. SIGINT, Syscall. SIGTERM)

//....

Nsqadmin. Main ()

<-exitchan

Nsqadmin. Exit ()

When the above code executes normally, it snaps to the <-exitchan of the penultimate sentence until there is data entry in the Exitchan.

When we execute from the command line: Kill-s SIGINT $PID, Signalchan receives a message that goroutines in the fourth line of code stops blocking, continues to execute down, and adds a piece of data to Exitchann. When there is data in the Exitchann, the penultimate sentence stops blocking and executes the nsqadmin. Exit () for graceful exit.

Of course, the above code can also be simplified:

Signalchan: = Make (chan os. Signal, 1)

Signal. Notify (Signalchan, Syscall. SIGINT, Syscall. SIGTERM)

//....

Nsqadmin. Main ()

<-signalchan

Nsqadmin. Exit ()

As to why NSQ did not do so, it is not clear. Ability is limited, can not realize its profound meaning.

The above example only applies to two goroutines, a processing after the business to Exitchan write data, the main Goroutines card in the Exitchan of the upper-class data. (The primary goroutines must exit after processing the goroutines of the business).

If multiple sub-goroutines are opened under a main thread, the channel is not elegant enough. can use Waitgroup, about Waitgroup Introduction can refer to: http://www.baiyuxiong.com/?p=913

The NSQ also uses the Waitgroup implementation to exit.

Code Snippet 2 (from: Https://github.com/bitly/nsq/blob/master/util/wait_group_wrapper.go)

Type Waitgroupwrapper struct {

Sync. Waitgroup

}

Func (w *waitgroupwrapper) Wrap (CB func ()) {

W.add (1)

Go func () {

CB ()

W.done ()

}()

}

Code snippet 3 (from: <a href= "Https://github.com/bitly/nsq/blob/master/nsqadmin/nsqadmin.go" >https://github.com/bitly/ nsq/blob/master/nsqadmin/nsqadmin.go</a>)

Func (n *nsqadmin) Main () {

HttpListener, err: = Net. Listen ("TCP", N.httpaddr.string ())

If err! = Nil {

N.logf ("Fatal:listen (%s) failed-%s", N.HTTPADDR, Err)

Os. Exit (1)

}

N.httplistener = HttpListener

Httpserver: = Newhttpserver (&context{n})

N.waitgroup.wrap (func () {

Util. Httpserver (N.httplistener, Httpserver, N.opts.logger, "HTTP")

})

N.waitgroup.wrap (func () {n.handleadminactions ()})

}

Func (n *nsqadmin) Exit () {

N.httplistener.close ()

Close (n.notifications)

N.waitgroup.wait ()

}

In code Snippet 2, the Waitgroup is simply encapsulated, the goroutines count plus 1 is turned on, and the count minus 1 is executed.

Code Snippet 3, the Main () method, called two times the Waitgroup.wrap () method, the reference code snippet 2 to know, this will start two sub-goroutines, and make the Waitgroup count add 2. While the Goroutines uses the HTTP packet to listen to the network service, blocking the goroutines, so that the count minus 1 operation cannot be called.

In our Code Snippet 1 we can know that after the command line sent Kill, will execute code snippet 3 of the Exit () method, when the method of N.httplistener.close () is called, the Network Service is interrupted, the block in code Snippet 2 will stop, and then the execution count minus 1, When the count of two sub-goroutines is reduced by 1. N.waitgroup.wait () in the exit () method will continue to execute, the main thread ends, and the program exits.

Learn how to gracefully exit the Go Network program from NSQ

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.