Translating concurrency patterns

from

to

  • close on signal
  • Read all from channel
  • Write all from enumerable, then close
  • broadcasting channel closure
  • idiomatic error handling
  • receive first
  • Receive if available
  • Close after timeout
  • Receive with timeout
  • Send with timeout
  • Heartbeat
  • A basic rate limiter + example

Spinner

func spinner(delay time.Duration) {
    for {
        for _, r := range `-\|/` {
            fmt.Printf("\r%c", r)
            time.Sleep(delay)
        }
    }
}

go spinner(100 * time.Millisecond)
def spinner(delay : Time::Span)
  loop do
    "-\|/".each_char { |c|
      printf("\r%c", c)
      sleep delay
    }
  end
end

spawn spinner(0.1.seconds)

TCP connection handler

for {
    conn, err := listener.Accept()
    if err != nil {
        log.Print(err)
        continue
    }
    go handleConn(conn)
}
loop do
  conn = listener.accept
  spawn handle_conn(conn)
rescue ex
  puts ex
end

TCP connection handler

loop do
  if conn = listener.accept?
    spawn handle_conn(conn)
  end
end
for {
    conn, err := listener.Accept()
    if err != nil {
        log.Print(err)
        continue
    }
    go handleConn(conn)
}

Read all from channel

class Channel(T) 
  def listen(&block : T ->)
    loop do
      block.call(self.receive)
    rescue Channel::ClosedError
      break
    end
  end
end
for x := range naturals {
    squares <- x * x
}
close(squares)

References

  • Concurrency in Go
  • Seven concurrency models in seven weeks
      #6 CSP
  • The Go programming language
      #8 Goroutines and channels
  • Clojure applied
      #5 Thinking in processes
      #6 Connecting components with channels
  • Programming Crystal
      #8 Creating concurrent code
  • CSP with core.async