Skip to content

Commit 127fac2

Browse files
fix: NewScheduler incorrectly creates underlying Client, closing broker properly (#977)
* fix: NewScheduler wrongly creates a client whose sharedConnection value is always true * This is affecting the PeriodicManager as well as the Scheduler * fix: closing the Client also closes the broker * The error was also previously unhandled. For shared connections an error will be returned by the broker itself because the sharedConnection bool is also set on the client. This also means we can get rid of the sharedConnection flag on the Scheduler itself and let it work internally.
1 parent 106c07a commit 127fac2

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

scheduler.go

+17-10
Original file line numberDiff line numberDiff line change
@@ -44,29 +44,41 @@ type Scheduler struct {
4444
// to avoid using cron.EntryID as the public API of
4545
// the Scheduler.
4646
idmap map[string]cron.EntryID
47-
// When a Scheduler has been created with an existing Redis connection, we do
48-
// not want to close it.
49-
sharedConnection bool
5047
}
5148

5249
const defaultHeartbeatInterval = 10 * time.Second
5350

5451
// NewScheduler returns a new Scheduler instance given the redis connection option.
5552
// The parameter opts is optional, defaults will be used if opts is set to nil
5653
func NewScheduler(r RedisConnOpt, opts *SchedulerOpts) *Scheduler {
54+
scheduler := newScheduler(opts)
55+
5756
redisClient, ok := r.MakeRedisClient().(redis.UniversalClient)
5857
if !ok {
5958
panic(fmt.Sprintf("asynq: unsupported RedisConnOpt type %T", r))
6059
}
61-
scheduler := NewSchedulerFromRedisClient(redisClient, opts)
62-
scheduler.sharedConnection = false
60+
61+
rdb := rdb.NewRDB(redisClient)
62+
63+
scheduler.rdb = rdb
64+
scheduler.client = &Client{broker: rdb, sharedConnection: false}
65+
6366
return scheduler
6467
}
6568

6669
// NewSchedulerFromRedisClient returns a new instance of Scheduler given a redis.UniversalClient
6770
// The parameter opts is optional, defaults will be used if opts is set to nil.
6871
// Warning: The underlying redis connection pool will not be closed by Asynq, you are responsible for closing it.
6972
func NewSchedulerFromRedisClient(c redis.UniversalClient, opts *SchedulerOpts) *Scheduler {
73+
scheduler := newScheduler(opts)
74+
75+
scheduler.rdb = rdb.NewRDB(c)
76+
scheduler.client = NewClientFromRedisClient(c)
77+
78+
return scheduler
79+
}
80+
81+
func newScheduler(opts *SchedulerOpts) *Scheduler {
7082
if opts == nil {
7183
opts = &SchedulerOpts{}
7284
}
@@ -93,8 +105,6 @@ func NewSchedulerFromRedisClient(c redis.UniversalClient, opts *SchedulerOpts) *
93105
state: &serverState{value: srvStateNew},
94106
heartbeatInterval: heartbeatInterval,
95107
logger: logger,
96-
client: NewClientFromRedisClient(c),
97-
rdb: rdb.NewRDB(c),
98108
cron: cron.New(cron.WithLocation(loc)),
99109
location: loc,
100110
done: make(chan struct{}),
@@ -294,9 +304,6 @@ func (s *Scheduler) Shutdown() {
294304
if err := s.client.Close(); err != nil {
295305
s.logger.Errorf("Failed to close redis client connection: %v", err)
296306
}
297-
if !s.sharedConnection {
298-
s.rdb.Close()
299-
}
300307
s.logger.Info("Scheduler stopped")
301308
}
302309

0 commit comments

Comments
 (0)