Created
June 28, 2017 21:06
-
-
Save groob/f4aa22ab6f4090ac24f94fe91e99688e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"os" | |
"os/signal" | |
"time" | |
) | |
func main() { | |
// create the gate actor. | |
// it has a bidirectional channel so we can quit and wait for the closure to close. | |
g := &gate{ | |
actionc: make(chan func()), | |
quitc: make(chan chan struct{}), | |
} | |
defer g.stop() | |
// start the actor loop | |
go g.loop() | |
// wait a bit to observe the loop ticker | |
time.Sleep(10 * time.Second) | |
g.actionc <- func() { | |
// send a closure on the action channel. it will be executed in the loop | |
// because it's managed by the select{} in the loop, we never get a race condition. | |
fmt.Println("hello from inside the loop") | |
fmt.Printf("I see that open is set to: %v\n", g.open) | |
g.open = true | |
fmt.Printf("Now I set it to true: %v\n", g.open) | |
time.Sleep(10 * time.Second) | |
fmt.Printf("It's still true: %v\n", g.open) | |
} | |
fmt.Println("I'll wait until CTRL + C to quit") | |
sig := make(chan os.Signal) | |
signal.Notify(sig, os.Interrupt) | |
<-sig | |
} | |
type gate struct { | |
actionc chan func() | |
quitc chan chan struct{} | |
// private field we care about working with | |
open bool | |
} | |
func (g *gate) loop() { | |
ticker := time.NewTicker(1 * time.Second).C | |
for { | |
select { | |
// if we get a closure on the channel execute it | |
case f := <-g.actionc: | |
f() | |
// every time the timer ticks, flip the value | |
case <-ticker: | |
g.open = !g.open | |
fmt.Printf("flipped value to %v\n", g.open) | |
// if we receive a value on the quit channel, terminate the loop. | |
case quit := <-g.quitc: | |
close(quit) | |
return | |
} | |
} | |
} | |
func (g *gate) stop() { | |
// to stop the loop, we pass a value on the quit channel and | |
// block until it returns | |
fmt.Println("closing gate actor loop") | |
quit := make(chan struct{}) | |
g.quitc <- quit | |
<-quit | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment