···
// calculate how many subscribers we need
totalDids := len(j.cfg.WantedDids)
subscribersNeeded := (totalDids + j.maxDidsPerSubscriber - 1) / j.maxDidsPerSubscriber // ceiling division
+
// first case: no subscribers yet; create all needed subscribers
+
if len(j.subscribers) == 0 {
+
for i := range subscribersNeeded {
+
startIdx := i * j.maxDidsPerSubscriber
+
endIdx := min((i+1)*j.maxDidsPerSubscriber, totalDids)
+
subscriberDids := j.cfg.WantedDids[startIdx:endIdx]
+
subCfg.WantedDids = subscriberDids
+
ident := fmt.Sprintf("%s-%d", j.baseIdent, i)
+
subscriber := &JetstreamSubscriber{
+
j.subscribers = append(j.subscribers, subscriber)
+
go j.startSubscriber(subscriber, &subCfg)
+
// second case: we have more subscribers than needed, stop extra subscribers
+
if len(j.subscribers) > subscribersNeeded {
+
for i := subscribersNeeded; i < len(j.subscribers); i++ {
+
sub := j.subscribers[i]
+
if sub.running && sub.cancel != nil {
+
j.subscribers = j.subscribers[:subscribersNeeded]
+
// third case: we need more subscribers
+
if len(j.subscribers) < subscribersNeeded {
+
existingCount := len(j.subscribers)
+
// Create additional subscribers
+
for i := existingCount; i < subscribersNeeded; i++ {
+
startIdx := i * j.maxDidsPerSubscriber
+
endIdx := min((i+1)*j.maxDidsPerSubscriber, totalDids)
+
subscriberDids := j.cfg.WantedDids[startIdx:endIdx]
+
subCfg.WantedDids = subscriberDids
+
ident := fmt.Sprintf("%s-%d", j.baseIdent, i)
+
subscriber := &JetstreamSubscriber{
+
j.subscribers = append(j.subscribers, subscriber)
+
go j.startSubscriber(subscriber, &subCfg)
+
// fourth case: update existing subscribers with new wantedDids
+
for i := 0; i < subscribersNeeded && i < len(j.subscribers); i++ {
startIdx := i * j.maxDidsPerSubscriber
endIdx := min((i+1)*j.maxDidsPerSubscriber, totalDids)
+
newDids := j.cfg.WantedDids[startIdx:endIdx]
+
// if the dids for this subscriber have changed, restart it
+
sub := j.subscribers[i]
+
if !didSlicesEqual(sub.dids, newDids) {
+
j.l.Info("subscriber DIDs changed, updating",
+
"subscriber", sub.ident,
+
"old_count", len(sub.dids),
+
"new_count", len(newDids))
+
if sub.running && sub.cancel != nil {
+
subCfg.WantedDids = newDids
+
go j.startSubscriber(sub, &subCfg)
+
func didSlicesEqual(a, b []string) bool {
+
aMap := make(map[string]struct{}, len(a))
+
for _, did := range a {
+
for _, did := range b {
+
if _, exists := aMap[did]; !exists {
// startSubscriber initializes and starts a single subscriber