awesome-patterns/concurrency/confinement/lexical/main.go
2018-01-16 11:32:21 +10:00

46 lines
1.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import "fmt"
// Confinement is the simple yet powerful idea of ensuring information is only ever available from one concurrent process.
// There are two kinds of confinement possible: ad hoc and lexical.
// Lexical confinement involves using lexical scope to expose only the correct data and
// concurrency primitives for multiple concurrent processes to use. It makes it impossible to do the wrong thing.
func main() {
lexicalDemo()
}
func lexicalDemo() {
// Here we instantiate the channel within the lexical scope of the chanOwner function.
// This limits the scope of the write aspect of the results channel to the closure
// defined below it. In other words, it confines the write aspect of this channel to
// prevent other goroutines from writing to it.
chanOwner := func() <-chan int {
results := make(chan int, 5)
go func() {
defer close(results)
for i := 0; i <= 5; i++ {
results <- i
}
}()
return results
}
// Here we receive a read-only copy of an int channel. By declaring that the only
// usage we require is read access, we confine usage of the channel within the consume function to only reads
comsumer := func(results <-chan int) {
for result := range results {
fmt.Println("Received: %d\n", result)
}
fmt.Println("Done Receiving!")
}
// Here we receive the read aspect of the channel and were able to pass it into the
// consumer, which can do nothing but read from it. Once again this confines the
// main goroutine to a read-only view of the channel.
results := chanOwner()
comsumer(results)
}