package workq

type Queue struct {
	ch chan *Item
}

func NewQueue() *Queue {
	q := new(Queue)
	q.ch = make(chan *Item, 10)
	return q
}

func (q *Queue) Push(item *Item) {
	q.ch <- item
	go item.Translate()
}

func (q *Queue) Pop() <-chan *Item {
	ch := make(chan *Item)
	go func() {
		for item := range q.ch {
			<-item.Done
			ch <- item
		}
	}()
	return ch
}

package workq

import "sync"

type Queue struct {
	items []*Item
	mutex sync.Mutex
}

func (q *Queue) Push(item *Item) {
	q.mutex.Lock()
	defer q.mutex.Unlock()

	q.items = append(q.items, item)
	go item.Translate()
}

func (q *Queue) Pop() *Item {
	q.mutex.Lock()
	defer q.mutex.Unlock()

	if !q.IsEmpty() {
		item := (q.items)[0]
		<-item.Done
		q.items = q.items[1:len(q.items)]
		return item
	}
	return nil
}

func (q *Queue) Len() int {
	return len(q.items)
}

func (q *Queue) IsEmpty() bool {
	return q.Len() == 0
}

--- 
+++ 
@@ -1,37 +1,27 @@
 package workq
 
-import "sync"
+type Queue struct {
+	ch chan *Item
+}
 
-type Queue struct {
-	items []*Item
-	mutex sync.Mutex
+func NewQueue() *Queue {
+	q := new(Queue)
+	q.ch = make(chan *Item, 10)
+	return q
 }
 
 func (q *Queue) Push(item *Item) {
-	q.mutex.Lock()
-	defer q.mutex.Unlock()
-
-	q.items = append(q.items, item)
+	q.ch <- item
 	go item.Translate()
 }
 
-func (q *Queue) Pop() *Item {
-	q.mutex.Lock()
-	defer q.mutex.Unlock()
-
-	if !q.IsEmpty() {
-		item := (q.items)[0]
-		<-item.Done
-		q.items = q.items[1:len(q.items)]
-		return item
-	}
-	return nil
+func (q *Queue) Pop() <-chan *Item {
+	ch := make(chan *Item)
+	go func() {
+		for item := range q.ch {
+			<-item.Done
+			ch <- item
+		}
+	}()
+	return ch
 }
-
-func (q *Queue) Len() int {
-	return len(q.items)
-}
-
-func (q *Queue) IsEmpty() bool {
-	return q.Len() == 0
-}
Use a channel inside the Queue
