dsa89029 2017-06-20 08:07
浏览 79
已采纳

从非陈类型*布尔接收

I want to daemonize myapp but I have one big problem. The channels I'm using are of type chan struct{}. However, with the package getopt (flag package), my flags are of type *bool, so I don't know how can I modify myapp.

It's not enough with channels type bool. I'm sure there are a concept that I don't understand. I attach you the code:

package main

import (
    "os"
    "syscall"
    "time"

    "github.com/pborman/getopt/v2"
    "github.com/sevlyar/go-daemon"
)

var (
    done    = make(chan struct{})
    optQuit = make(chan struct{})
    optRun  = make(chan struct{})
)

func TermHandler(sig os.Signal) error {
    optQuit <- struct{}{}
    if sig == syscall.SIGQUIT {
        <-done
    }
    return nil
}

func main() {
    optHelp := getopt.BoolLong("help", 'h', "Help")
    optQuit := getopt.BoolLong("quit", 0, "Help")
    optRun  := getopt.BoolLong("run", 'r', "Help")

    if *optHelp {
        getopt.Usage()
        os.Exit(0)
    }

    // Create pid file
    cntxt := &daemon.Context{
        PidFileName: "/var/run/myapp.pid",
        PidFilePerm: 0644,
        WorkDir:     "./",
        Umask:       027,
        Args:        []string{"[Z]"},
    }

    if len(daemon.ActiveFlags()) > 0 {
        d, _ := cntxt.Search()
        daemon.SendCommands(d)
        return
    }
    d, err := cntxt.Reborn()
    if d != nil {
        return
    }
    if err != nil {
        os.Exit(1)
    }
    defer cntxt.Release()

    // Define ticker
    ticker := time.NewTicker(time.Second)
    myapp := true

    // Loop
    for myapp {
        select {

        // Case sleep
        case <- ticker.C:
            time.Sleep(time.Second)

        // Case QUIT
        case <- optQuit:
            done <- struct{}{}
            myapp = false
            ticker.Stop()
            os.Exit(0)

        // Case RUN
        case <- optRun:
            // Executes a goroutine...
        }
    }
}

With go install, I can see this errors:

./main.go:72: invalid operation: <-optQuit (receive from non-chan type *bool)
./main.go:79: invalid operation: <-optRun (receive from non-chan type *bool)

I don't know how I should modify the channels (done, optQuit of type struct{}), to resolve this...

P.S.: I show you an example that I did. It runs as daemon and each minute, it executes the function Writer(). After, if you type zdaemon -z quit, the app does a graceful shutdown. You can run it in your machines:

https://play.golang.org/p/RVq7M7usEj

  • 写回答

2条回答 默认 最新

  • 普通网友 2017-06-20 08:11
    关注

    Those two lines in your main function shadow your global variable declaration:

    optQuit := getopt.BoolLong("quit", 0, "Help")
    optRun  := getopt.BoolLong("run", 'r', "Help")
    

    If you only use them, to get a nice usage, why not create a usage function yourself?

    If you insist on using getopt just to create a usage, do

    _ = getopt.BoolLong("quit", 0, "Help")
    _ = getopt.BoolLong("run", 'r', "Help")
    

    instead.

    You also need to call getopt.Parse() before using *optHelp.

    The resulting message

    Usage: test [-hr] [--quit] [parameters ...]
     -h, --help  Help
         --quit  Help
     -r, --run   Help
    

    seems to be less than helpful. Why not just do

    fmt.Printf(`
    Usage: test
      This program will start a daemon service, which you can use like this ...
    `)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 matlab中使用gurobi时报错
  • ¥15 WPF 大屏看板表格背景图片设置
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂