Skip to content

Instantly share code, notes, and snippets.

@WhisperingChaos
Last active February 15, 2018 12:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save WhisperingChaos/c1c1cd01b48ae3d376a7d5d8288fb306 to your computer and use it in GitHub Desktop.
Save WhisperingChaos/c1c1cd01b48ae3d376a7d5d8288fb306 to your computer and use it in GitHub Desktop.
Nil Channel favor/bias channels: Complete Solution
package main
import (
"fmt"
)
type msg_1 struct {
}
func (msg_1) msgType() {
fmt.Println("msg type 1")
}
type msg_2 struct {
}
func (msg_2) msgType() {
fmt.Println("msg type 2")
}
func main() {
msg_1ch := make(chan msg_1, 28)
msg_2ch := make(chan msg_2, 35)
defer close(msg_1ch)
defer close(msg_2ch)
for i := 0; i < 28; i++ {
msg_1ch <- msg_1{}
}
for i := 0; i < 35; i++ {
msg_2ch <- msg_2{}
}
fmt.Println("Ordered by Channel Select Semantics")
consumeAccordingToChannelSemantics(msg_1ch, msg_2ch)
fmt.Println("Ordered using nil implemented Bias")
consumeOrderedByBias(msg_1ch, msg_2ch)
}
func consumeAccordingToChannelSemantics(msg_1ch chan msg_1, msg_2ch chan msg_2) {
// because the channels were asychronous and completely full
// before running this routine, select's channel semantics
// considers the messages as having arrived at the same time.
// select therefore randomly reads one of the channels. since
// only two case statements, probability of selection is
// equivalent to a random coin toss.
for msgCnt := 0; msgCnt < 21; msgCnt++ {
select {
case msg, ok := <-msg_1ch:
if ok {
msg.msgType()
}
case msg, ok := <-msg_2ch:
if ok {
msg.msgType()
}
}
}
}
func consumeOrderedByBias(msg_1ch chan msg_1, msg_2ch chan msg_2) {
// copy channels to enable their restoration
msg_1_save := msg_1ch
msg_2_save := msg_2ch
// bias function encoded as a for loop
for msgCnt := 0; msgCnt < 21; msgCnt++ {
// use modulus math to help implement bias function
if msgCnt%3 == 0 {
// favor channel 1 when processing muliples of 3
msg_1ch = msg_1_save
// bias channel 2
msg_2ch = nil
} else {
// favor channel 2 when not a multiple of 3
msg_2ch = msg_2_save
// bias channel 1
msg_1ch = nil
}
select {
case msg, ok := <-msg_1ch:
if ok {
msg.msgType()
}
case msg, ok := <-msg_2ch:
if ok {
msg.msgType()
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment