• go语言 go-svc包


    阅读 NSQ 源码时,看到NSQ使用了 go-svc 来启动nsq的相关程序,使得在程序退出的时候可以做一些释放资源等收尾工作。
    使用起来非常简单,定义一个Service,实现其 svc.Service中的接口即可。
     
    简单使用:
    func main() {
    	prg := &program{}
    	//运行程序
    	if err := svc.Run(prg, syscall.SIGINT, syscall.SIGTERM); err != nil {
    		log.Fatal(err)
    	}
    }
    //初始化方法
    func (p *program)  Init(env svc.Environment) error {
    	fmt.Println("init.....")
    	return nil
    }
    //启动方法
    func (program) Start() error {
    	fmt.Println("start.....")
    	fmt.Println(syscall.Getpid())
    	go func() {
    		ticker := time.NewTicker(2 * time.Second)
    		for t := range ticker.C {
    			fmt.Println("tick at", t)
    		}
    	}()
    	return nil
    }
    //结束方法
    func (program) Stop() error {
    	fmt.Println("stop.....")
    	
    

      

    注意事项

    1.Start方法中不能只直接阻塞,需要在Start方法中新开goroutine去写需要阻塞的代码。
    2.svc.Run()方法的第二个参数可以指定需要程序监听的信号,默认情况下不指定的话,默认会监听 SIGINT和 SIGTERM两个。根据具体需要进行指定,比如本例中还监听了SIGUSR1.

    实现原理

    其实go-svc代码实现很简单,使用了标准库中的os/signalNotify方法。
    下面的代码截取于judwhite/go-svc/svc/svc-other.go:

    // Run runs your Service.
    //
    // Run will block until one of the signals specified in sig is received.
    // If sig is empty syscall.SIGINT and syscall.SIGTERM are used by default.
    func Run(service Service, sig ...os.Signal) error {
        env := environment{}
        if err := service.Init(env); err != nil {
            return err
        }
    
        if err := service.Start(); err != nil {
            return err
        }
    
        if len(sig) == 0 {
            sig = []os.Signal{syscall.SIGINT, syscall.SIGTERM}
        }
    
        signalChan := make(chan os.Signal, 1)
        signalNotify(signalChan, sig...)
        //signalNotify方法其实就是 signal.Notify 方法
        //var signalNotify = signal.Notify
        <-signalChan
    
        return service.Stop()
    }
    

      标准库里面的 os/signal中的 Notfiy方法签名如下:

    func Notify(c chan<- os.Signal, sig ...os.Signal) {}
    

      其实还有个开源包 endless 也是做类似的事情,大家有兴趣可以看看。

  • 相关阅读:
    ReSharper.8.0.14.856注册码
    asp.net 301重定向代码
    WebResource.axd 404 错误
    【原创】asp.net导出word 检索 COM 类工厂中 CLSID 为 {000209FF-0000-0000-C000-000000000046} 的组件失败,原因是出现以下错误: 8000401a
    C#操作word或excel及水晶报表,检索 COM 类工厂中 CLSID 为 {} 的组件时失败,原因是出现以下错误: 80070005
    Repository 设计模式介绍
    将15位身份证转换成18位
    清理数据库木马文件
    Oracle的创建表空间及用户
    使用python脚本执行地理处理工具
  • 原文地址:https://www.cnblogs.com/gwyy/p/13551571.html
Copyright © 2020-2023  润新知