@@ -11,12 +11,15 @@ import (
11
11
)
12
12
13
13
var ctx = context .Background ()
14
- var consStopped = false
15
14
15
+ // This example is not supposed to be run as is. It is just a test to see how pubsub behaves in relation to pool management.
16
+ // It was used to find regressions in pool management in hitless mode.
17
+ // Please don't use it as a reference for how to use pubsub.
16
18
func main () {
17
19
wg := & sync.WaitGroup {}
18
20
rdb := redis .NewClient (& redis.Options {
19
- Addr : ":6379" ,
21
+ Addr : ":6379" ,
22
+ HitlessUpgrades : true ,
20
23
})
21
24
_ = rdb .FlushDB (ctx ).Err ()
22
25
@@ -30,21 +33,22 @@ func main() {
30
33
if err != nil {
31
34
panic (err )
32
35
}
33
- if err := rdb .Set (ctx , "prods " , "0" , 0 ).Err (); err != nil {
36
+ if err := rdb .Set (ctx , "publishers " , "0" , 0 ).Err (); err != nil {
34
37
panic (err )
35
38
}
36
- if err := rdb .Set (ctx , "cons " , "0" , 0 ).Err (); err != nil {
39
+ if err := rdb .Set (ctx , "subscribers " , "0" , 0 ).Err (); err != nil {
37
40
panic (err )
38
41
}
39
- if err := rdb .Set (ctx , "cntr " , "0" , 0 ).Err (); err != nil {
42
+ if err := rdb .Set (ctx , "published " , "0" , 0 ).Err (); err != nil {
40
43
panic (err )
41
44
}
42
- if err := rdb .Set (ctx , "recs " , "0" , 0 ).Err (); err != nil {
45
+ if err := rdb .Set (ctx , "received " , "0" , 0 ).Err (); err != nil {
43
46
panic (err )
44
47
}
45
- fmt .Println ("cntr " , rdb .Get (ctx , "cntr " ).Val ())
46
- fmt .Println ("recs " , rdb .Get (ctx , "recs " ).Val ())
48
+ fmt .Println ("published " , rdb .Get (ctx , "published " ).Val ())
49
+ fmt .Println ("received " , rdb .Get (ctx , "received " ).Val ())
47
50
subCtx , cancelSubCtx := context .WithCancel (ctx )
51
+ pubCtx , cancelPublishers := context .WithCancel (ctx )
48
52
for i := 0 ; i < 10 ; i ++ {
49
53
wg .Add (1 )
50
54
go subscribe (subCtx , rdb , "test" , i , wg )
@@ -54,32 +58,39 @@ func main() {
54
58
time .Sleep (time .Second )
55
59
subCtx , cancelSubCtx = context .WithCancel (ctx )
56
60
for i := 0 ; i < 10 ; i ++ {
57
- if err := rdb .Incr (ctx , "prods " ).Err (); err != nil {
61
+ if err := rdb .Incr (ctx , "publishers " ).Err (); err != nil {
58
62
panic (err )
59
63
}
60
64
wg .Add (1 )
61
- go floodThePool (subCtx , rdb , wg )
65
+ go floodThePool (pubCtx , rdb , wg )
62
66
}
63
67
64
68
for i := 0 ; i < 500 ; i ++ {
65
- if err := rdb .Incr (ctx , "cons " ).Err (); err != nil {
69
+ if err := rdb .Incr (ctx , "subscribers " ).Err (); err != nil {
66
70
panic (err )
67
71
}
68
72
wg .Add (1 )
69
73
go subscribe (subCtx , rdb , "test2" , i , wg )
70
74
}
75
+ time .Sleep (5 * time .Second )
76
+ fmt .Println ("canceling publishers" )
77
+ cancelPublishers ()
71
78
time .Sleep (10 * time .Second )
72
- fmt .Println ("canceling" )
79
+ fmt .Println ("canceling subscribers " )
73
80
cancelSubCtx ()
74
81
wg .Wait ()
75
- cntr , err := rdb .Get (ctx , "cntr" ).Result ()
76
- recs , err := rdb .Get (ctx , "recs" ).Result ()
77
- prods , err := rdb .Get (ctx , "prods" ).Result ()
78
- cons , err := rdb .Get (ctx , "cons" ).Result ()
79
- fmt .Printf ("cntr: %s\n " , cntr )
80
- fmt .Printf ("recs: %s\n " , recs )
81
- fmt .Printf ("prods: %s\n " , prods )
82
- fmt .Printf ("cons: %s\n " , cons )
82
+ published , err := rdb .Get (ctx , "published" ).Result ()
83
+ received , err := rdb .Get (ctx , "received" ).Result ()
84
+ publishers , err := rdb .Get (ctx , "publishers" ).Result ()
85
+ subscribers , err := rdb .Get (ctx , "subscribers" ).Result ()
86
+ fmt .Printf ("publishers: %s\n " , publishers )
87
+ fmt .Printf ("published: %s\n " , published )
88
+ fmt .Printf ("subscribers: %s\n " , subscribers )
89
+ fmt .Printf ("received: %s\n " , received )
90
+ publishedInt , err := rdb .Get (ctx , "published" ).Int ()
91
+ subscribersInt , err := rdb .Get (ctx , "subscribers" ).Int ()
92
+ fmt .Printf ("if drained = published*subscribers: %d\n " , publishedInt * subscribersInt )
93
+
83
94
time .Sleep (2 * time .Second )
84
95
}
85
96
@@ -88,8 +99,6 @@ func floodThePool(ctx context.Context, rdb *redis.Client, wg *sync.WaitGroup) {
88
99
for {
89
100
select {
90
101
case <- ctx .Done ():
91
- fmt .Println ("floodThePool stopping" )
92
- consStopped = true
93
102
return
94
103
default :
95
104
}
@@ -99,7 +108,7 @@ func floodThePool(ctx context.Context, rdb *redis.Client, wg *sync.WaitGroup) {
99
108
//log.Println("publish error:", err)
100
109
}
101
110
102
- err = rdb .Incr (ctx , "cntr " ).Err ()
111
+ err = rdb .Incr (ctx , "published " ).Err ()
103
112
if err != nil {
104
113
// noop
105
114
//log.Println("incr error:", err)
@@ -110,36 +119,24 @@ func floodThePool(ctx context.Context, rdb *redis.Client, wg *sync.WaitGroup) {
110
119
111
120
func subscribe (ctx context.Context , rdb * redis.Client , topic string , subscriberId int , wg * sync.WaitGroup ) {
112
121
defer wg .Done ()
113
- defer fmt .Printf ("subscriber %d stopping\n " , subscriberId )
114
122
rec := rdb .Subscribe (ctx , topic )
115
123
recChan := rec .Channel ()
116
124
for {
117
125
select {
118
126
case <- ctx .Done ():
119
127
rec .Close ()
120
- if subscriberId == 199 {
121
- fmt .Printf ("subscriber %d done\n " , subscriberId )
122
- }
123
128
return
124
129
default :
125
130
select {
126
131
case <- ctx .Done ():
127
132
rec .Close ()
128
- if subscriberId == 199 {
129
- fmt .Printf ("subscriber %d done\n " , subscriberId )
130
- }
131
133
return
132
134
case msg := <- recChan :
133
- err := rdb .Incr (ctx , "recs " ).Err ()
135
+ err := rdb .Incr (ctx , "received " ).Err ()
134
136
if err != nil {
135
137
log .Println ("incr error:" , err )
136
138
}
137
- if consStopped {
138
- fmt .Printf ("subscriber %d received %s\n " , subscriberId , msg .Payload )
139
- }
140
- if subscriberId == 199 {
141
- fmt .Printf ("subscriber %d received %s\n " , subscriberId , msg .Payload )
142
- }
139
+ _ = msg // Use the message to avoid unused variable warning
143
140
}
144
141
}
145
142
}
0 commit comments