func (qr *Qr) Close() {
	close(qr.q)
	close(qr.planb)
	filename := qr.batchFilename(0)  
	fh, err := os.Create(filename)
	if err != nil {
		qr.logf("QR create err: %v", err)
		return
	}
	enc := gob.NewEncoder(fh)
	count := 0
	for e := range qr.out {
		count++
		if err = enc.Encode(&e); err != nil {
			qr.logf("QR encode err: %v", err)
		}
	}
	fh.Close()
	if count == 0 {
		os.Remove(filename)
	}
}
Close shuts down all Go routines and closes the Dequeue() channel. It'll
write all in-flight entries to disk. Calling Enqueue() after Close will
panic.
package qr
import (
	"encoding/gob"
	"errors"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
	"reflect"
	"sort"
	"strings"
	"sync/atomic"
	"time"
)
const (
	DefaultTimeout = 10 * time.Second
	DefaultBuffer = 1000
	fileExtension = ".qr"
)
var (
	ErrInvalidPrefix = errors.New("invalid prefix")
)
type Qr struct {
	q          chan interface{}  
	planb      chan interface{}  
	confluence chan interface{}  
	out        chan interface{}
	dir        string
	prefix     string
	timeout    time.Duration
	bufferSize int
	logf       func(string, ...interface{})  
	fileCount  int64                         
}
type Option func(qr *Qr) error
func OptionTimeout(t time.Duration) Option {
	return func(qr *Qr) error {
		qr.timeout = t
		return nil
	}
}
func OptionBuffer(n int) Option {
	return func(qr *Qr) error {
		qr.bufferSize = n
		return nil
	}
}
func OptionLogger(l func(string, ...interface{})) Option {
	return func(qr *Qr) error {
		qr.logf = l
		return nil
	}
}
func OptionTest(t interface{}) Option {
	return func(qr *Qr) error {
		return qr.test(t)
	}
}
func New(dir, prefix string, options ...Option) (*Qr, error) {
	if len(prefix) == 0 || strings.ContainsAny(prefix, ":-/") {
		return nil, ErrInvalidPrefix
	}
	qr := Qr{
		planb:      make(chan interface{}),
		confluence: make(chan interface{}),
		out:        make(chan interface{}),
		dir:        dir,
		prefix:     prefix,
		timeout:    DefaultTimeout,
		bufferSize: DefaultBuffer,
		logf:       log.Printf,
	}
	for _, cb := range options {
		if err := cb(&qr); err != nil {
			return nil, err
		}
	}
	qr.q = make(chan interface{}, qr.bufferSize)
	var (
		filesToDisk   = make(chan string)
		filesFromDisk = make(chan string)
	)
	go qr.merge()
	go qr.swapout(filesToDisk)
	go qr.fs(filesToDisk, filesFromDisk)
	go qr.swapin(filesFromDisk)
	for _, f := range qr.findOld() {
		filesToDisk <- f
	}
	return &qr, nil
}
func (qr *Qr) Enqueue(e interface{}) {
	select {
	case qr.q <- e:
	default:
		qr.planb <- e
	}
}
func (qr *Qr) Dequeue() <-chan interface{} {
	return qr.out
}
func (qr *Qr) FileCount() int {
	return int(atomic.LoadInt64(&qr.fileCount))
}