aboutsummaryrefslogtreecommitdiff
path: root/mocking-bob/more-parallelism.go
blob: 64b841b20caeb758f953ee1247b20eb1cfa41f97 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package main

import (
	// we want *real* random
	"crypto/rand"
	"fmt"
	"os"
	"unicode"
)

func main() {
	jobList := make(chan [2]chan rune, 4096)

	// spin up an appropriate amount of workers for this task
	go worker(jobList)
	go worker(jobList)
	go worker(jobList)
	go worker(jobList)
	go worker(jobList)
	go worker(jobList)
	go worker(jobList)
	go worker(jobList)
	go worker(jobList)
	go worker(jobList)
	go worker(jobList)
	go worker(jobList)
	go worker(jobList)
	go worker(jobList)
	go worker(jobList)
	go worker(jobList)

	outchans := make(chan chan rune, 4096)
	done := make(chan struct{}, 1)

	go func(o chan chan rune) {
		for r := range o {
			fmt.Printf("%c", <-r)
		}
		done <- struct{}{}
	}(outchans)

	for _, str := range os.Args[1:] {
		for _, c := range str {
			in := make(chan rune, 1)
			out := make(chan rune, 1)
			outchans <- out
			jobList <- [2]chan rune{in, out}
			in <- c
			close(in)
		}
		out := make(chan rune, 1)
		outchans <- out
		out <- ' '
		close(out)
	}
	close(outchans)

	<-done
}

func worker(jobList chan [2]chan rune) {
	b := make([]byte, 1)
	for job := range jobList {
		c := <-job[0]
		_, err := rand.Read(b)
		if err != nil {
			job[1] <- c
			close(job[1])
			continue
		}
		if b[0]%2 == 0 {
			// switch case
			if unicode.ToUpper(c) == c {
				job[1] <- unicode.ToLower(c)
			} else {
				job[1] <- unicode.ToUpper(c)
			}
			close(job[1])
			continue
		}
		job[1] <- c
		close(job[1])
	}
}