Skip to content

Commit

Permalink
feat(queue): all task has been done after closing the channel (#56)
Browse files Browse the repository at this point in the history
  • Loading branch information
appleboy committed Mar 29, 2022
1 parent fe0fb0e commit 18f5bb4
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 32 deletions.
7 changes: 5 additions & 2 deletions consumer.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,13 @@ func (s *Consumer) Queue(task QueuedMessage) error {

func (s *Consumer) Request() (QueuedMessage, error) {
select {
case task := <-s.taskQueue:
case task, ok := <-s.taskQueue:
if !ok {
return nil, ErrQueueHasBeenClosed
}
return task, nil
default:
return nil, errors.New("no task in queue")
return nil, ErrNoTaskInQueue
}
}

Expand Down
5 changes: 2 additions & 3 deletions consumer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,10 @@ func TestGoroutineLeak(t *testing.T) {
for {
select {
case <-ctx.Done():
log.Println("get data:", string(m.Bytes()))
if errors.Is(ctx.Err(), context.Canceled) {
log.Println("queue has been shutdown and cancel the job")
log.Println("queue has been shutdown and cancel the job: " + string(m.Bytes()))
} else if errors.Is(ctx.Err(), context.DeadlineExceeded) {
log.Println("job deadline exceeded")
log.Println("job deadline exceeded: " + string(m.Bytes()))
}
return nil
default:
Expand Down
10 changes: 10 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package queue

import "errors"

var (
// ErrNoTaskInQueue there is nothing in the queue
ErrNoTaskInQueue = errors.New("no task in queue")
// ErrQueueHasBeenClosed the current queue is closed
ErrQueueHasBeenClosed = errors.New("queue has been closed")
)
49 changes: 22 additions & 27 deletions queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,46 +246,41 @@ func (q *Queue) start() {
tasks := make(chan QueuedMessage, 1)

for {
var task QueuedMessage

// request task from queue in background
q.routineGroup.Run(func() {
for {
select {
case <-q.quit:
return
default:
t, err := q.worker.Request()
if t == nil || err != nil {
if err != nil {
select {
case <-q.quit:
t, err := q.worker.Request()
if t == nil || err != nil {
if err != nil {
select {
case <-q.quit:
if !errors.Is(err, ErrNoTaskInQueue) {
close(tasks)
return
case <-time.After(time.Second):
// sleep 1 second to fetch new task
}
case <-time.After(time.Second):
// sleep 1 second to fetch new task
}
}
if t != nil {
tasks <- t
}
if t != nil {
tasks <- t
return
}

select {
case <-q.quit:
if !errors.Is(err, ErrNoTaskInQueue) {
close(tasks)
return
}
default:
}
}
})

// read task
select {
case task = <-tasks:
case <-q.quit:
select {
case task = <-tasks:
// queue task before shutdown the service
if err := q.worker.Queue(task); err != nil {
q.logger.Errorf("can't re-queue task: %v", err)
}
default:
}
task, ok := <-tasks
if !ok {
return
}

Expand Down

0 comments on commit 18f5bb4

Please sign in to comment.