Skip to content
This repository was archived by the owner on Nov 20, 2023. It is now read-only.

Commit 1abc547

Browse files
committed
make it safe to call Done() multiple times
1 parent a2e2d4c commit 1abc547

File tree

2 files changed

+42
-4
lines changed

2 files changed

+42
-4
lines changed

que.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,30 @@ type Job struct {
4242
// failed. It is ignored on job creation.
4343
LastError pgx.NullString
4444

45-
mu sync.Mutex
46-
pool *pgx.ConnPool
47-
conn *pgx.Conn
45+
mu sync.Mutex
46+
destroyed bool
47+
pool *pgx.ConnPool
48+
conn *pgx.Conn
4849
}
4950

5051
// Done marks this job as complete by deleting it from the database. It also
5152
// removes the Postgres advisory lock on the job and returns the database
5253
// connection to the pool.
5354
func (j *Job) Done() error {
55+
j.mu.Lock()
56+
defer j.mu.Unlock()
57+
58+
if j.destroyed {
59+
return nil
60+
}
61+
5462
_, err := j.conn.Exec(sqlDeleteJob, j.Queue, j.Priority, j.RunAt, j.ID)
5563
if err != nil {
5664
return err
5765
}
5866

59-
j.unlock()
67+
j.destroyed = true
68+
j._unlock()
6069
return nil
6170
}
6271

@@ -81,6 +90,10 @@ func (j *Job) unlock() {
8190
j.mu.Lock()
8291
defer j.mu.Unlock()
8392

93+
j._unlock()
94+
}
95+
96+
func (j *Job) _unlock() {
8497
var ok bool
8598
// Swallow this error because we don't want an unlock failure to cause work
8699
// to stop.

work_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,31 @@ func TestJobDone(t *testing.T) {
189189
}
190190
}
191191

192+
func TestJobDoneMultiple(t *testing.T) {
193+
c := openTestClient(t)
194+
defer truncateAndClose(c.pool)
195+
196+
if err := c.Enqueue(Job{Type: "MyJob"}); err != nil {
197+
t.Fatal(err)
198+
}
199+
200+
j, err := c.LockJob("")
201+
if err != nil {
202+
t.Fatal(err)
203+
}
204+
if j == nil {
205+
t.Fatal("wanted job, got none")
206+
}
207+
208+
if err = j.Done(); err != nil {
209+
t.Fatal(err)
210+
}
211+
// try calling Done() again
212+
if err = j.Done(); err != nil {
213+
t.Fatal(err)
214+
}
215+
}
216+
192217
func TestJobError(t *testing.T) {
193218
c := openTestClient(t)
194219
defer truncateAndClose(c.pool)

0 commit comments

Comments
 (0)