Skip to content

Instantly share code, notes, and snippets.

@cheshir
Last active July 30, 2020 21:22
Show Gist options
  • Save cheshir/306292406ca4dfa2de861e17ba5b43e5 to your computer and use it in GitHub Desktop.
Save cheshir/306292406ca4dfa2de861e17ba5b43e5 to your computer and use it in GitHub Desktop.
Mobalytics live coding results
package main
import (
"context"
"fmt"
"sync"
"time"
)
func main() {
c1 := make(chan int, 1)
c2 := make(chan int, 1)
ctx, _ := context.WithTimeout(context.Background(), 100*time.Millisecond)
out := merge(ctx, c1, c2)
go func() {
for v := range out {
fmt.Printf("Got %v\n", v)
}
}()
c1 <- 100
time.Sleep(120 * time.Millisecond)
c2 <- 500
close(c1)
close(c2)
}
func merge(ctx context.Context, cs ...<-chan int) <-chan int {
var wg sync.WaitGroup
out := make(chan int)
wg.Add(len(cs))
for _, c := range cs {
go func(c <-chan int) {
for {
select {
case v := <-c:
out <- v
case <-ctx.Done():
wg.Done()
return
}
}
}(c)
}
go func() {
wg.Wait()
close(out)
}()
return out
}
package main
import (
"fmt"
"sync/atomic"
"time"
)
func main() {
hosts := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
hostBalancer := newHostBalancer(hosts)
for i := 0; i < 4; i++ {
go func(workerID int) {
for {
host := hostBalancer.Next()
fmt.Printf("#%d %v\n", workerID, host)
}
}(i)
}
time.Sleep(6 * time.Second)
}
type hostBalancer struct {
hosts []int
cursor int32
len int
}
func newHostBalancer(hosts []int) *hostBalancer {
return &hostBalancer{
hosts: hosts,
len: len(hosts),
}
}
func (s *hostBalancer) Next() int {
index := int(atomic.LoadInt32(&s.cursor))
index++
if index == s.len {
index = 0
}
atomic.StoreInt32(&s.cursor, int32(index))
host := s.hosts[index]
return host
}
@cheshir
Copy link
Author

cheshir commented Jul 30, 2020

We were talking about sync.CompareAndSwap. Here you can get an example of how I use it:
https://github.com/cheshir/go-mq/blob/ace498b45beb18ef423af470a208c4ab7a097c71/mq.go#L404

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment