@@ -22,6 +22,7 @@ import (
22
22
"path/filepath"
23
23
"runtime"
24
24
"sort"
25
+ "strings"
25
26
"sync"
26
27
"time"
27
28
@@ -33,7 +34,7 @@ import (
33
34
)
34
35
35
36
type subCmd struct {
36
- subject string
37
+ subjects [] string
37
38
queue string
38
39
durable string
39
40
raw bool
@@ -63,7 +64,7 @@ func configureSubCommand(app commandHost) {
63
64
act := app .Command ("subscribe" , "Generic subscription client" ).Alias ("sub" ).Action (c .subscribe )
64
65
addCheat ("sub" , act )
65
66
66
- act .Arg ("subject " , "Subject to subscribe to" ).StringVar (& c .subject )
67
+ act .Arg ("subjects " , "Subjects to subscribe to" ).StringsVar (& c .subjects )
67
68
act .Flag ("queue" , "Subscribe to a named queue group" ).StringVar (& c .queue )
68
69
act .Flag ("durable" , "Use a durable consumer (requires JetStream)" ).StringVar (& c .durable )
69
70
act .Flag ("raw" , "Show the raw data received" ).Short ('r' ).UnNegatableBoolVar (& c .raw )
@@ -159,15 +160,29 @@ func (c *subCmd) subscribe(p *fisk.ParseContext) error {
159
160
}
160
161
defer nc .Close ()
161
162
162
- if c .subject == "" && c .inbox {
163
- c .subject = nc .NewRespInbox ()
164
- } else if c .subject == "" && c .stream == "" {
163
+ c .jetStream = c .sseq > 0 || len (c .durable ) > 0 || c .deliverAll || c .deliverNew || c .deliverLast || c .deliverSince != "" || c .deliverLastPerSubject || c .stream != ""
164
+
165
+ switch {
166
+ case len (c .subjects ) == 0 && c .inbox :
167
+ c .subjects = []string {nc .NewRespInbox ()}
168
+ case len (c .subjects ) == 0 && c .stream == "" :
165
169
return fmt .Errorf ("subject is required" )
170
+ case len (c .subjects ) > 1 && c .jetStream :
171
+ return fmt .Errorf ("streams subscribe support only 1 subject" )
166
172
}
167
173
174
+ if c .inbox && c .jetStream {
175
+ return fmt .Errorf ("generating inboxes is not compatible with JetStream subscriptions" )
176
+ }
177
+ if c .queue != "" && c .jetStream {
178
+ return fmt .Errorf ("queue group subscriptions are not supported with JetStream" )
179
+ }
168
180
if c .dump == "-" && c .inbox {
169
181
return fmt .Errorf ("generating inboxes is not compatible with dumping to stdout using null terminated strings" )
170
182
}
183
+ if c .reportSubjects && c .reportSubjectsCount == 0 {
184
+ return fmt .Errorf ("subject count must be at least one" )
185
+ }
171
186
172
187
if c .dump != "" && c .dump != "-" {
173
188
err = os .MkdirAll (c .dump , 0700 )
@@ -176,21 +191,8 @@ func (c *subCmd) subscribe(p *fisk.ParseContext) error {
176
191
}
177
192
}
178
193
179
- c .jetStream = c .sseq > 0 || len (c .durable ) > 0 || c .deliverAll || c .deliverNew || c .deliverLast || c .deliverSince != "" || c .deliverLastPerSubject || c .stream != ""
180
-
181
- if c .inbox && c .jetStream {
182
- return fmt .Errorf ("generating inboxes is not compatible with JetStream subscriptions" )
183
- }
184
- if c .queue != "" && c .jetStream {
185
- return fmt .Errorf ("queue group subscriptions are not supported with JetStream" )
186
- }
187
-
188
- if c .reportSubjects && c .reportSubjectsCount == 0 {
189
- return fmt .Errorf ("subject count must be at least one" )
190
- }
191
-
192
194
var (
193
- sub * nats.Subscription
195
+ subs [] * nats.Subscription
194
196
mu = sync.Mutex {}
195
197
subjMu = sync.Mutex {}
196
198
dump = c .dump != ""
@@ -269,7 +271,10 @@ func (c *subCmd) subscribe(p *fisk.ParseContext) error {
269
271
}
270
272
271
273
if ctr == c .limit {
272
- sub .Unsubscribe ()
274
+ for _ , sub := range subs {
275
+ sub .Unsubscribe ()
276
+ }
277
+
273
278
// if no reply matching, or if didn't yet get all replies
274
279
if ! c .match || len (matchMap ) == 0 {
275
280
cancel ()
@@ -335,15 +340,22 @@ func (c *subCmd) subscribe(p *fisk.ParseContext) error {
335
340
case c .jetStream :
336
341
// logs later depending on settings
337
342
case c .jsAck :
338
- log .Printf ("Subscribing on %s with acknowledgement of JetStream messages %s" , c .subject , ignoredSubjInfo )
343
+ log .Printf ("Subscribing on %s with acknowledgement of JetStream messages %s" , c .firstSubject () , ignoredSubjInfo )
339
344
default :
340
- log .Printf ("Subscribing on %s %s" , c . subject , ignoredSubjInfo )
345
+ log .Printf ("Subscribing on %s %s" , strings . Join ( c . subjects , ", " ) , ignoredSubjInfo )
341
346
}
342
347
}
343
348
344
349
switch {
345
350
case c .reportSubjects :
346
- sub , err = nc .Subscribe (c .subject , handler )
351
+ for _ , subj := range c .subjects {
352
+ sub , err := nc .Subscribe (subj , handler )
353
+ if err != nil {
354
+ return err
355
+ }
356
+ subs = append (subs , sub )
357
+ }
358
+
347
359
startSubjectReporting (ctx , & subjMu , subjectReportMap , subjectBytesReportMap , c .reportSubjectsCount )
348
360
349
361
case c .jetStream :
@@ -378,9 +390,9 @@ func (c *subCmd) subscribe(p *fisk.ParseContext) error {
378
390
}
379
391
}
380
392
381
- subMsg := c .subject
393
+ subMsg := c .firstSubject ()
382
394
if c .stream != "" {
383
- if c . subject == "" {
395
+ if len ( c . subjects ) == 0 {
384
396
str , err := js .StreamInfo (c .stream )
385
397
if err != nil {
386
398
return err
@@ -422,17 +434,36 @@ func (c *subCmd) subscribe(p *fisk.ParseContext) error {
422
434
}
423
435
424
436
if bindDurable {
425
- sub , err = js .Subscribe ("" , handler , nats .Bind (c .stream , c .durable ))
437
+ sub , err := js .Subscribe ("" , handler , nats .Bind (c .stream , c .durable ))
438
+ if err != nil {
439
+ return err
440
+ }
441
+ subs = append (subs , sub )
426
442
} else {
427
443
c .jsAck = false
428
- sub , err = js .Subscribe (c .subject , handler , opts ... )
444
+ sub , err := js .Subscribe (c .firstSubject (), handler , opts ... )
445
+ if err != nil {
446
+ return err
447
+ }
448
+ subs = append (subs , sub )
429
449
}
430
450
431
451
case c .queue != "" :
432
- sub , err = nc .QueueSubscribe (c .subject , c .queue , handler )
452
+ sub , err := nc .QueueSubscribe (c .firstSubject (), c .queue , handler )
453
+ if err != nil {
454
+ return err
455
+ }
456
+ subs = append (subs , sub )
433
457
434
458
default :
435
- sub , err = nc .Subscribe (c .subject , handler )
459
+ for _ , subj := range c .subjects {
460
+ sub , err := nc .Subscribe (subj , handler )
461
+ if err != nil {
462
+ return err
463
+ }
464
+ subs = append (subs , sub )
465
+ }
466
+
436
467
}
437
468
if err != nil {
438
469
return err
@@ -450,6 +481,14 @@ func (c *subCmd) subscribe(p *fisk.ParseContext) error {
450
481
return nil
451
482
}
452
483
484
+ func (c * subCmd ) firstSubject () string {
485
+ if len (c .subjects ) == 0 {
486
+ return ""
487
+ }
488
+
489
+ return c .subjects [0 ]
490
+ }
491
+
453
492
func (c * subCmd ) printMsg (msg * nats.Msg , reply * nats.Msg , ctr uint ) {
454
493
var info * jsm.MsgInfo
455
494
if msg .Reply != "" {
0 commit comments