Created
November 16, 2016 19:01
-
-
Save eriknelson/e158e04e9f54eecd279b65a1116c47ab to your computer and use it in GitHub Desktop.
Async go workers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"math/rand" | |
"runtime" | |
"sync" | |
"time" | |
) | |
const ( | |
INITIALIZING = iota | |
RUNNING = iota | |
FINALIZING = iota | |
FINISHED = iota | |
) | |
var ( | |
stateText map[int]string | |
wg sync.WaitGroup | |
) | |
type WorkMachine struct { | |
name string | |
stateGraph map[int]int | |
currentState int | |
stateWeights map[int]int | |
totalWeight int | |
totalTicks int | |
stateTicks int | |
totalProgress float32 | |
stateProgress float32 | |
} | |
func NewWorkMachine(name string) WorkMachine { | |
stateGraph := map[int]int{ | |
INITIALIZING: RUNNING, | |
RUNNING: FINALIZING, | |
FINALIZING: FINISHED, | |
} | |
stateWeights := make(map[int]int) | |
shortWeight := random(3, 7) | |
longWeight := random(7, 12) | |
totalWeight := shortWeight*2 + longWeight | |
stateWeights[INITIALIZING] = shortWeight | |
stateWeights[RUNNING] = longWeight | |
stateWeights[FINALIZING] = shortWeight | |
return WorkMachine{ | |
name: name, | |
stateWeights: stateWeights, | |
stateGraph: stateGraph, | |
totalWeight: totalWeight, | |
} | |
} | |
func (m *WorkMachine) Tick() { | |
// check to see if we need to transition to the next state | |
if m.stateWeights[m.currentState] == m.stateTicks { | |
m.stateTicks = 0 // Reset state ticker | |
m.currentState = m.stateGraph[m.currentState] // Transition to next state | |
} | |
m.totalTicks++ | |
m.stateTicks++ | |
m.totalProgress = float32(m.totalTicks) / float32(m.totalWeight) | |
m.stateProgress = float32(m.stateTicks) / float32(m.stateWeights[m.currentState]) | |
} | |
func (m *WorkMachine) Report() { | |
fmt.Printf("%s -> State: %s, State Progress: %.2f, Total Progress: %.2f \n", | |
m.name, stateText[m.currentState], m.stateProgress, m.totalProgress) | |
} | |
func init() { | |
runtime.GOMAXPROCS(2) | |
stateText = map[int]string{ | |
INITIALIZING: "Initializing", | |
RUNNING: "Running", | |
FINALIZING: "Finalizing", | |
FINISHED: "Finished", | |
} | |
rand.Seed(time.Now().UnixNano()) | |
} | |
func main() { | |
wg.Add(2) | |
fmt.Println("Starting machines!") | |
runMachine("FOO") | |
runMachine("BAR") | |
fmt.Println("Waiting for the machines to finish up!") | |
wg.Wait() | |
fmt.Println("All finished!") | |
} | |
func runMachine(name string) { | |
machine := NewWorkMachine(name) | |
go func() { | |
defer wg.Done() | |
fmt.Printf("total weight -> %d\n", machine.totalWeight) | |
fmt.Println(machine.stateWeights) | |
for { | |
if machine.currentState == FINISHED { | |
break | |
} | |
machine.Tick() | |
if machine.currentState != FINISHED { | |
machine.Report() | |
} | |
} | |
fmt.Printf("Finished -> %d, %d, %.2f\n", | |
machine.currentState, | |
machine.totalTicks, | |
machine.totalProgress, | |
) | |
}() | |
} | |
func random(min, max int) int { | |
return rand.Intn(max-min) + min | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment