Skip to content

Instantly share code, notes, and snippets.

@seansu4you87
Created March 13, 2014 01:22
Show Gist options
  • Save seansu4you87/9520196 to your computer and use it in GitHub Desktop.
Save seansu4you87/9520196 to your computer and use it in GitHub Desktop.
Concurrency in Go with Accounts
package main
import (
"errors"
"fmt"
)
type Account struct {
balance int
deltaChan chan int
balanceChan chan int
errChan chan error
}
func NewAccount() (a *Account) {
a = &Account{
balance: 0,
deltaChan: make(chan int),
balanceChan: make(chan int),
errChan: make(chan error),
}
go a.run()
return
}
func (a *Account) Balance() int {
return <-a.balanceChan
}
func (a *Account) Deposit(amount int) error {
fmt.Printf("depositing %d\n", amount)
a.deltaChan <- amount
return <-a.errChan
}
func (a *Account) Withdraw(amount int) error {
fmt.Printf("withdrawing %d\n", amount)
a.deltaChan <- -amount
return <-a.errChan
}
func (a *Account) applyDelta(amount int) error {
newBalance := a.balance + amount
if newBalance < 0 {
return errors.New("Insufficient funds")
}
a.balance = newBalance
fmt.Printf("new balance: %d\n", newBalance)
return nil
}
func (a *Account) run() {
var delta int
for {
select {
case delta = <-a.deltaChan:
a.errChan <- a.applyDelta(delta)
case a.balanceChan <- a.balance:
//Do nothing,
}
}
}
func main() {
a := NewAccount()
a.Deposit(1000)
if a.Withdraw(1000) != nil {
fmt.Printf("ERROR\n")
}
fmt.Printf("Balance: %d\n", a.Balance())
if a.Withdraw(1000) != nil {
fmt.Printf("ERROR\n")
}
fmt.Printf("Balance: %d\n", a.Balance())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment