func Dequeue(ctx context.Context, store *coal.Store, job Job, timeout time.Duration) (bool, int, error) {
	meta := GetMeta(job)
	ctx, span := xo.Trace(ctx, "axe/Dequeue")
	span.Tag("name", meta.Name)
	span.Tag("id", job.ID().Hex())
	span.Tag("timeout", timeout.String())
	defer span.End()
	if timeout == 0 {
		return false, 0, xo.F("missing timeout")
	}
	now := time.Now()
	var model Model
	found, err := store.M(&Model{}).UpdateFirst(ctx, &model, bson.M{
		"_id": job.ID(),
		"State": bson.M{
			"$in": bson.A{Enqueued, Dequeued, Failed},
		},
		"Available": bson.M{
			"$lte": now,
		},
	}, bson.M{
		"$set": bson.M{
			"State":     Dequeued,
			"Available": now.Add(timeout),
			"Started":   now,
			"Ended":     nil,
		},
		"$inc": bson.M{
			"Attempts": 1,
		},
		"$push": bson.M{
			"Events": Event{
				Timestamp: now,
				State:     Dequeued,
			},
		},
	}, nil, false)
	if err != nil {
		return false, 0, err
	} else if !found {
		return false, 0, nil
	}
	err = model.Data.Unmarshal(job, meta.Coding)
	if err != nil {
		return false, 0, err
	}
	job.GetBase().Label = model.Label
	span.Tag("label", model.Label)
	err = job.Validate()
	if err != nil {
		return false, 0, err
	}
	return true, model.Attempts, nil
}
Dequeue will dequeue the specified job. The provided timeout will be set to
allow the job to be dequeued if the worker failed to set its state. Only
jobs in the "enqueued", "dequeued" (passed timeout) or "failed" state are
dequeued. It will return whether a job has been dequeued.
package axe
import (
	"context"
	"time"
	"github.com/256dpi/xo"
	"go.mongodb.org/mongo-driver/bson"
	"github.com/256dpi/fire/coal"
	"github.com/256dpi/fire/stick"
)
func Enqueue(ctx context.Context, store *coal.Store, job Job, delay, isolation time.Duration) (bool, error) {
	meta := GetMeta(job)
	base := job.GetBase()
	if base.DocID.IsZero() {
		base.DocID = coal.New()
	}
	ctx, span := xo.Trace(ctx, "axe/Enqueue")
	span.Tag("name", meta.Name)
	span.Tag("label", base.Label)
	span.Tag("id", job.ID().Hex())
	span.Tag("delay", delay.String())
	span.Tag("isolation", isolation.String())
	defer span.End()
	ok, ts := coal.GetTransaction(ctx)
	if ok && ts != store {
		return false, xo.F("transaction store does not match supplied store")
	}
	err := job.Validate()
	if err != nil {
		return false, err
	}
	var data stick.Map
	err = data.Marshal(job, meta.Coding)
	if err != nil {
		return false, err
	}
	now := time.Now()
	model := &Model{
		Base:      coal.B(base.DocID),
		Name:      meta.Name,
		Label:     base.Label,
		Data:      data,
		State:     Enqueued,
		Created:   now,
		Available: now.Add(delay),
		Events: []Event{
			{
				Timestamp: now,
				State:     Enqueued,
			},
		},
	}
	if base.Label == "" && isolation == 0 {
		err := store.M(&Model{}).Insert(ctx, model)
		if err != nil {
			return false, err
		}
		return true, nil
	}
	filter := bson.M{
		"Name":  meta.Name,
		"Label": base.Label,
		"State": bson.M{
			"$in": bson.A{Enqueued, Dequeued, Failed},
		},
	}
	if isolation > 0 {
		delete(filter, "State")
		filter["$or"] = bson.A{
			bson.M{
				"State": bson.M{
					"$in": bson.A{Enqueued, Dequeued, Failed},
				},
				"Finished": nil,
			},
			bson.M{
				"State": bson.M{
					"$in": bson.A{Completed, Cancelled},
				},
				"Finished": bson.M{
					"$gt": now.Add(-isolation),
				},
			},
		}
	}
	inserted, err := store.M(&Model{}).InsertIfMissing(ctx, filter, model, false)
	if err != nil {
		return false, err
	}
	return inserted, nil
}