Original post

Hi,

I find myself in an weird situation whereby I have no colleagues (in between contracts) to rubber duck a problem I’m having. I’m hoping someone can point out the stupid mistake I am making.

I’m making a “server” type struct with the “loop” function running as a separate goroutine, a nice pattern I’ve used a few times.


import (
        "time"

        "backtag/app/policy"
)

type policyServer struct {
        update chan policy.Mandate
}

func (p *policyServer) loop(config Config) bool {
        // declare state for the loop

        next := time.Now().Add(config.PolicyDelay)

        // the mandate to begin with

        mandate := policy.Mandate{}

        // act like a server

        for {
                // determine how long we must wait before fetching the latest mandate

                var wait time.Duration
                if now := time.Now(); next.After(now) {
                        wait = next.Sub(now)
                }

                select {
                // an update is ready
                case update := <-p.update:
                        mandate = update

                        // time to request an update
                case <-time.After(wait):
                        go func(ch chan policy.Mandate) {
                                // will pretend to fetch new mandate for now..
                                time.Sleep(2 * time.Second)
                                ch <- policy.Mandate{}
                        }(p.update)
                        next = next.Add(config.PolicyInterval)
                }
        }
}

func (p *policyServer) BlockTag(number uint) bool {
        panic("implement me")
}

func (p *policyServer) BlockIP(ip string) bool {
        panic("implement me")
}

func NewPolicyServer(config Config) policy.Tester {
        srv := policyServer{}
        go srv.loop(config)
        return &srv
}

My issue is that this won’t compile because the “mandate” var is unused. However, “next” doesn’t have this problem, so it can’t be a scoping issue, which was my first thought.

As you can see, I am (re)assigning “mandate” in a case block, just like “next” in the case block below it.

Can anyone help me out?

Thanks in advance,
Jonathan

The problem is that you declared mandate here

mandate := policy.Mandate{}

And you set it here

           case update := <-p.update:
                        mandate = update

But you didn’t use it anywhere. As far as the compiler is concerned you could delete the declaration and setting of mandate and your program would work fine.

Ah, of course.

The “next” var was distracting me, but I see not only did I assign next, i used it “next.Add(…)”

… had I continued to implement rather than compile half way through, I might not of noticed.

Thanks for the spot!

Jonathan