1
1
// All material is licensed under the GNU Free Documentation License
2
2
// https://github.com/ArdanStudios/gotraining/blob/master/LICENSE
3
3
4
- // http://play.golang.org/p/T3QupG_7_X
4
+ // http://play.golang.org/p/yOn3nZU5rf
5
5
6
6
// This sample program demonstrates how to use a buffered
7
7
// channel to receive results from other goroutines in a guaranteed way.
@@ -14,6 +14,13 @@ import (
14
14
"time"
15
15
)
16
16
17
+ // result is what is sent back from each operation.
18
+ type result struct {
19
+ id int
20
+ op string
21
+ err error
22
+ }
23
+
17
24
// init called before main.
18
25
func init () {
19
26
// Seed the random number generator.
@@ -34,30 +41,30 @@ func performInserts() {
34
41
const inserts = routines * 2
35
42
36
43
// Buffered channel to receive information about any possible insert.
37
- ch := make (chan error , inserts )
44
+ ch := make (chan result , inserts )
38
45
39
46
// Number of responses we need to handle.
40
47
waitInserts := inserts
41
48
42
49
// Perform all the inserts.
43
50
for i := 0 ; i < routines ; i ++ {
44
51
go func (id int ) {
45
- ch <- insertDoc1 (id )
46
- ch <- insertDoc2 (id )
52
+ ch <- insertUser (id )
53
+
54
+ // We don't need to wait to start the second insert
55
+ // thanks to the buffered channel. The first send
56
+ // will happen immediately.
57
+ ch <- insertTrans (id )
47
58
}(i )
48
59
}
49
60
50
61
// Process the insert results as they complete.
51
62
for waitInserts > 0 {
52
63
// Wait for a response from a goroutine.
53
- err := <- ch
64
+ r := <- ch
54
65
55
66
// Display the result.
56
- if err != nil {
57
- log .Println ("Received error:" , err )
58
- } else {
59
- log .Println ("Received nil error" )
60
- }
67
+ log .Printf ("ID: %d OP: %s ERR: %v" , r .id , r .op , r .err )
61
68
62
69
// Decrement the wait count and determine if we are done.
63
70
waitInserts --
@@ -66,26 +73,32 @@ func performInserts() {
66
73
log .Println ("Inserts Complete" )
67
74
}
68
75
69
- // insertDoc1 simulates a database operation.
70
- func insertDoc1 (id int ) error {
71
- log .Println ("Insert document 1: " , id )
76
+ // insertUser simulates a database operation.
77
+ func insertUser (id int ) result {
78
+ r := result {
79
+ id : id ,
80
+ op : fmt .Sprintf ("insert USERS value (%d)" , id ),
81
+ }
72
82
73
83
// Randomize if the insert fails or not.
74
84
if rand .Intn (10 ) == 0 {
75
- return fmt .Errorf ("Document ID: %d " , id )
85
+ r . err = fmt .Errorf ("Unable to insert %d into USER table " , id )
76
86
}
77
87
78
- return nil
88
+ return r
79
89
}
80
90
81
- // insertDoc2 simulates a database operation.
82
- func insertDoc2 (id int ) error {
83
- log .Println ("Insert document 2: " , id )
91
+ // insertTrans simulates a database operation.
92
+ func insertTrans (id int ) result {
93
+ r := result {
94
+ id : id ,
95
+ op : fmt .Sprintf ("insert TRANS value (%d)" , id ),
96
+ }
84
97
85
98
// Randomize if the insert fails or not.
86
99
if rand .Intn (10 ) == 0 {
87
- return fmt .Errorf ("Document ID: %d " , id )
100
+ r . err = fmt .Errorf ("Unable to insert %d into USER table " , id )
88
101
}
89
102
90
- return nil
103
+ return r
91
104
}
0 commit comments