Skip to content

Instantly share code, notes, and snippets.

@btc
Last active August 29, 2015 13:57
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 btc/9518411 to your computer and use it in GitHub Desktop.
Save btc/9518411 to your computer and use it in GitHub Desktop.
A Beautiful Dance: Synchronous Channels in Go
// what a beautiful application of synchronous channels!
// source: https://blog.mozilla.org/services/2014/03/12/sane-concurrency-with-go/
type Account struct {
balance float64
deltaChan chan float64
balanceChan chan float64
errChan chan error
}
func NewAccount() (a *Account) {
a = &Account{
balance: balance,
deltaChan: make(chan float64),
balanceChan: make(chan float64),
errChan: make(chan error),
}
go a.run()
}
func (a *Account) Balance() float64 {
return <-a.balanceChan
}
func (a *Account) Deposit(amount float64) error {
a.deltaChan <- amount
return <-a.errChan
}
func (a *Account) Withdraw(amount float64) error {
a.deltaChan <- -amount
return <-a.errChan
}
func (a *Account) applyDelta(amount float64) error {
newBalance := a.balance + amount
if newBalance < 0 {
return errors.New("Insufficient funds")
}
a.balance = newBalance
return nil
}
func (a *Account) run() {
var delta float64
for {
select {
case delta = <-a.deltaChan:
a.errChan <- a.applyDelta(delta)
case a.balanceChan <- a.balance:
// Do nothing, we've accomplished our goal w/ the channel put.
}
}
}
@jbenet
Copy link

jbenet commented Mar 12, 2014

beautiful.

@ali01
Copy link

ali01 commented Mar 12, 2014

<3

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