Full Code of RichardKnop/machinery for AI

master 26dbe0308408 cached
209 files
966.3 KB
306.6k tokens
1445 symbols
1 requests
Download .txt
Showing preview only (1,024K chars total). Download the full file or copy to clipboard to get everything.
Repository: RichardKnop/machinery
Branch: master
Commit: 26dbe0308408
Files: 209
Total size: 966.3 KB

Directory structure:
gitextract_kvdc2vnc/

├── .deepsource.toml
├── .gitignore
├── .travis.yml
├── Dockerfile.gcppubsub
├── Dockerfile.test
├── LICENSE
├── Makefile
├── README.md
├── docker-compose.test.yml
├── example/
│   ├── amqp/
│   │   └── main.go
│   ├── redis/
│   │   └── main.go
│   ├── tasks/
│   │   └── tasks.go
│   └── tracers/
│       └── jaeger.go
├── go.mod
├── go.sum
├── instruction-notes/
│   └── dynamodb.md
├── integration-tests/
│   ├── amqp_amqp_test.go
│   ├── amqp_get_pending_tasks_test.go
│   ├── amqp_memcache_test.go
│   ├── amqp_mongodb_test.go
│   ├── amqp_redis_test.go
│   ├── eager_eager_test.go
│   ├── gcppubsub_redis_test.go
│   ├── redis_get_pending_tasks_test.go
│   ├── redis_memcache_test.go
│   ├── redis_mongodb_test.go
│   ├── redis_redis_test.go
│   ├── redis_socket_test.go
│   ├── sqs_amqp_test.go
│   ├── sqs_mongodb_test.go
│   ├── suite_test.go
│   └── worker_only_consumes_registered_tasks_test.go
├── v1/
│   ├── backends/
│   │   ├── amqp/
│   │   │   ├── amqp.go
│   │   │   └── amqp_test.go
│   │   ├── dynamodb/
│   │   │   ├── dynamodb.go
│   │   │   ├── dynamodb_export_test.go
│   │   │   └── dynamodb_test.go
│   │   ├── eager/
│   │   │   ├── eager.go
│   │   │   └── eager_test.go
│   │   ├── iface/
│   │   │   └── interfaces.go
│   │   ├── memcache/
│   │   │   ├── memcache.go
│   │   │   └── memcache_test.go
│   │   ├── mongo/
│   │   │   ├── mongodb.go
│   │   │   └── mongodb_test.go
│   │   ├── null/
│   │   │   └── null.go
│   │   ├── package.go
│   │   ├── redis/
│   │   │   ├── goredis.go
│   │   │   ├── goredis_test.go
│   │   │   ├── redis.go
│   │   │   └── redis_test.go
│   │   └── result/
│   │       └── async_result.go
│   ├── brokers/
│   │   ├── amqp/
│   │   │   ├── amqp.go
│   │   │   ├── amqp_concurrence_test.go
│   │   │   └── amqp_test.go
│   │   ├── eager/
│   │   │   └── eager.go
│   │   ├── errs/
│   │   │   └── errors.go
│   │   ├── gcppubsub/
│   │   │   └── gcp_pubsub.go
│   │   ├── iface/
│   │   │   └── interfaces.go
│   │   ├── package.go
│   │   ├── redis/
│   │   │   ├── goredis.go
│   │   │   └── redis.go
│   │   └── sqs/
│   │       ├── sqs.go
│   │       ├── sqs_export_test.go
│   │       └── sqs_test.go
│   ├── common/
│   │   ├── amqp.go
│   │   ├── backend.go
│   │   ├── broker.go
│   │   ├── broker_test.go
│   │   └── redis.go
│   ├── config/
│   │   ├── config.go
│   │   ├── env.go
│   │   ├── env_test.go
│   │   ├── file.go
│   │   ├── file_test.go
│   │   ├── test.env
│   │   └── testconfig.yml
│   ├── factories.go
│   ├── factories_test.go
│   ├── locks/
│   │   ├── eager/
│   │   │   ├── eager.go
│   │   │   └── eager_test.go
│   │   ├── iface/
│   │   │   └── interfaces.go
│   │   └── redis/
│   │       └── redis.go
│   ├── log/
│   │   ├── log.go
│   │   └── log_test.go
│   ├── package.go
│   ├── retry/
│   │   ├── fibonacci.go
│   │   ├── fibonacci_test.go
│   │   └── retry.go
│   ├── server.go
│   ├── server_test.go
│   ├── tasks/
│   │   ├── errors.go
│   │   ├── reflect.go
│   │   ├── reflect_test.go
│   │   ├── result.go
│   │   ├── result_test.go
│   │   ├── signature.go
│   │   ├── state.go
│   │   ├── state_test.go
│   │   ├── task.go
│   │   ├── task_test.go
│   │   ├── validate.go
│   │   ├── validate_test.go
│   │   ├── workflow.go
│   │   └── workflow_test.go
│   ├── tracing/
│   │   └── tracing.go
│   ├── utils/
│   │   ├── deepcopy.go
│   │   ├── deepcopy_test.go
│   │   ├── utils.go
│   │   ├── utils_test.go
│   │   ├── uuid.go
│   │   └── uuid_test.go
│   ├── worker.go
│   └── worker_test.go
├── v2/
│   ├── Dockerfile.test
│   ├── Makefile
│   ├── backends/
│   │   ├── amqp/
│   │   │   ├── amqp.go
│   │   │   └── amqp_test.go
│   │   ├── dynamodb/
│   │   │   ├── dynamodb.go
│   │   │   ├── dynamodb_export_test.go
│   │   │   └── dynamodb_test.go
│   │   ├── eager/
│   │   │   ├── eager.go
│   │   │   └── eager_test.go
│   │   ├── iface/
│   │   │   ├── dynamodb/
│   │   │   │   └── api.go
│   │   │   └── interfaces.go
│   │   ├── memcache/
│   │   │   ├── memcache.go
│   │   │   └── memcache_test.go
│   │   ├── mongo/
│   │   │   ├── mongodb.go
│   │   │   └── mongodb_test.go
│   │   ├── null/
│   │   │   └── null.go
│   │   ├── package.go
│   │   ├── redis/
│   │   │   ├── goredis.go
│   │   │   ├── goredis_test.go
│   │   │   ├── redis.go
│   │   │   └── redis_test.go
│   │   └── result/
│   │       └── async_result.go
│   ├── brokers/
│   │   ├── amqp/
│   │   │   ├── amqp.go
│   │   │   ├── amqp_concurrence_test.go
│   │   │   └── amqp_test.go
│   │   ├── eager/
│   │   │   └── eager.go
│   │   ├── errs/
│   │   │   └── errors.go
│   │   ├── gcppubsub/
│   │   │   └── gcp_pubsub.go
│   │   ├── iface/
│   │   │   ├── interfaces.go
│   │   │   └── sqs/
│   │   │       └── api.go
│   │   ├── package.go
│   │   ├── redis/
│   │   │   ├── goredis.go
│   │   │   └── redis.go
│   │   └── sqs/
│   │       ├── sqs.go
│   │       ├── sqs_export_test.go
│   │       └── sqs_test.go
│   ├── common/
│   │   ├── amqp.go
│   │   ├── backend.go
│   │   ├── broker.go
│   │   ├── broker_test.go
│   │   └── redis.go
│   ├── config/
│   │   ├── config.go
│   │   ├── env.go
│   │   ├── env_test.go
│   │   ├── file.go
│   │   ├── file_test.go
│   │   ├── test.env
│   │   └── testconfig.yml
│   ├── docker-compose.test.yml
│   ├── example/
│   │   ├── amqp/
│   │   │   └── main.go
│   │   ├── go-redis/
│   │   │   └── main.go
│   │   ├── redigo/
│   │   │   └── main.go
│   │   ├── tasks/
│   │   │   └── tasks.go
│   │   └── tracers/
│   │       └── jaeger.go
│   ├── go.mod
│   ├── go.sum
│   ├── integration-tests/
│   │   ├── amqp_amqp_test.go
│   │   ├── redis_redis_test.go
│   │   └── suite_test.go
│   ├── locks/
│   │   ├── eager/
│   │   │   ├── eager.go
│   │   │   └── eager_test.go
│   │   ├── iface/
│   │   │   └── interfaces.go
│   │   └── redis/
│   │       └── redis.go
│   ├── log/
│   │   ├── log.go
│   │   └── log_test.go
│   ├── package.go
│   ├── retry/
│   │   ├── fibonacci.go
│   │   ├── fibonacci_test.go
│   │   └── retry.go
│   ├── server.go
│   ├── server_test.go
│   ├── tasks/
│   │   ├── errors.go
│   │   ├── reflect.go
│   │   ├── reflect_test.go
│   │   ├── result.go
│   │   ├── result_test.go
│   │   ├── signature.go
│   │   ├── state.go
│   │   ├── state_test.go
│   │   ├── task.go
│   │   ├── task_test.go
│   │   ├── validate.go
│   │   ├── validate_test.go
│   │   ├── workflow.go
│   │   └── workflow_test.go
│   ├── tracing/
│   │   └── tracing.go
│   ├── utils/
│   │   ├── deepcopy.go
│   │   ├── deepcopy_test.go
│   │   ├── utils.go
│   │   ├── utils_test.go
│   │   ├── uuid.go
│   │   └── uuid_test.go
│   ├── wait-for-it.sh
│   ├── worker.go
│   └── worker_test.go
└── wait-for-it.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .deepsource.toml
================================================
version = 1

test_patterns = ["**/*_test.go"]

exclude_patterns = ["example/**"]

[[analyzers]]
name = "go"
enabled = true

  [analyzers.meta]
  import_paths = ["github.com/RichardKnop/machinery"]

================================================
FILE: .gitignore
================================================
coverage*
_vendor-*
.idea/
.env
.DS_Store
dump.rdb


================================================
FILE: .travis.yml
================================================
---
language: go

go:
  - 1.13.x

env:
  - GO111MODULE=on

services:
  - docker

script:
  - make ci

after_success:
  - bash <(curl -s https://codecov.io/bash)


================================================
FILE: Dockerfile.gcppubsub
================================================
FROM google/cloud-sdk:530.0.0-alpine

RUN apk --update add openjdk8-jre
RUN gcloud components install --quiet beta pubsub-emulator
RUN mkdir -p /var/pubsub

EXPOSE 8085

CMD [ "gcloud", "beta", "emulators", "pubsub", "start", "--host-port=0.0.0.0:8085"]


================================================
FILE: Dockerfile.test
================================================
# Start from a Debian image with the latest version of Go installed
# and a workspace (GOPATH) configured at /go.
FROM golang

# Set environment variables
ENV PATH /go/bin:$PATH

# Cd into the source code directory
WORKDIR /go/src/github.com/RichardKnop/machinery

# Copy the local package files to the container's workspace.
ADD . /go/src/github.com/RichardKnop/machinery

# Run integration tests as default command
CMD /go/src/github.com/RichardKnop/machinery/wait-for-it.sh rabbitmq:5672 -- make test-with-coverage


================================================
FILE: LICENSE
================================================
Mozilla Public License, version 2.0

1. Definitions

1.1. “Contributor”

     means each individual or legal entity that creates, contributes to the
     creation of, or owns Covered Software.

1.2. “Contributor Version”

     means the combination of the Contributions of others (if any) used by a
     Contributor and that particular Contributor’s Contribution.

1.3. “Contribution”

     means Covered Software of a particular Contributor.

1.4. “Covered Software”

     means Source Code Form to which the initial Contributor has attached the
     notice in Exhibit A, the Executable Form of such Source Code Form, and
     Modifications of such Source Code Form, in each case including portions
     thereof.

1.5. “Incompatible With Secondary Licenses”
     means

     a. that the initial Contributor has attached the notice described in
        Exhibit B to the Covered Software; or

     b. that the Covered Software was made available under the terms of version
        1.1 or earlier of the License, but not also under the terms of a
        Secondary License.

1.6. “Executable Form”

     means any form of the work other than Source Code Form.

1.7. “Larger Work”

     means a work that combines Covered Software with other material, in a separate
     file or files, that is not Covered Software.

1.8. “License”

     means this document.

1.9. “Licensable”

     means having the right to grant, to the maximum extent possible, whether at the
     time of the initial grant or subsequently, any and all of the rights conveyed by
     this License.

1.10. “Modifications”

     means any of the following:

     a. any file in Source Code Form that results from an addition to, deletion
        from, or modification of the contents of Covered Software; or

     b. any new file in Source Code Form that contains any Covered Software.

1.11. “Patent Claims” of a Contributor

      means any patent claim(s), including without limitation, method, process,
      and apparatus claims, in any patent Licensable by such Contributor that
      would be infringed, but for the grant of the License, by the making,
      using, selling, offering for sale, having made, import, or transfer of
      either its Contributions or its Contributor Version.

1.12. “Secondary License”

      means either the GNU General Public License, Version 2.0, the GNU Lesser
      General Public License, Version 2.1, the GNU Affero General Public
      License, Version 3.0, or any later versions of those licenses.

1.13. “Source Code Form”

      means the form of the work preferred for making modifications.

1.14. “You” (or “Your”)

      means an individual or a legal entity exercising rights under this
      License. For legal entities, “You” includes any entity that controls, is
      controlled by, or is under common control with You. For purposes of this
      definition, “control” means (a) the power, direct or indirect, to cause
      the direction or management of such entity, whether by contract or
      otherwise, or (b) ownership of more than fifty percent (50%) of the
      outstanding shares or beneficial ownership of such entity.


2. License Grants and Conditions

2.1. Grants

     Each Contributor hereby grants You a world-wide, royalty-free,
     non-exclusive license:

     a. under intellectual property rights (other than patent or trademark)
        Licensable by such Contributor to use, reproduce, make available,
        modify, display, perform, distribute, and otherwise exploit its
        Contributions, either on an unmodified basis, with Modifications, or as
        part of a Larger Work; and

     b. under Patent Claims of such Contributor to make, use, sell, offer for
        sale, have made, import, and otherwise transfer either its Contributions
        or its Contributor Version.

2.2. Effective Date

     The licenses granted in Section 2.1 with respect to any Contribution become
     effective for each Contribution on the date the Contributor first distributes
     such Contribution.

2.3. Limitations on Grant Scope

     The licenses granted in this Section 2 are the only rights granted under this
     License. No additional rights or licenses will be implied from the distribution
     or licensing of Covered Software under this License. Notwithstanding Section
     2.1(b) above, no patent license is granted by a Contributor:

     a. for any code that a Contributor has removed from Covered Software; or

     b. for infringements caused by: (i) Your and any other third party’s
        modifications of Covered Software, or (ii) the combination of its
        Contributions with other software (except as part of its Contributor
        Version); or

     c. under Patent Claims infringed by Covered Software in the absence of its
        Contributions.

     This License does not grant any rights in the trademarks, service marks, or
     logos of any Contributor (except as may be necessary to comply with the
     notice requirements in Section 3.4).

2.4. Subsequent Licenses

     No Contributor makes additional grants as a result of Your choice to
     distribute the Covered Software under a subsequent version of this License
     (see Section 10.2) or under the terms of a Secondary License (if permitted
     under the terms of Section 3.3).

2.5. Representation

     Each Contributor represents that the Contributor believes its Contributions
     are its original creation(s) or it has sufficient rights to grant the
     rights to its Contributions conveyed by this License.

2.6. Fair Use

     This License is not intended to limit any rights You have under applicable
     copyright doctrines of fair use, fair dealing, or other equivalents.

2.7. Conditions

     Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
     Section 2.1.


3. Responsibilities

3.1. Distribution of Source Form

     All distribution of Covered Software in Source Code Form, including any
     Modifications that You create or to which You contribute, must be under the
     terms of this License. You must inform recipients that the Source Code Form
     of the Covered Software is governed by the terms of this License, and how
     they can obtain a copy of this License. You may not attempt to alter or
     restrict the recipients’ rights in the Source Code Form.

3.2. Distribution of Executable Form

     If You distribute Covered Software in Executable Form then:

     a. such Covered Software must also be made available in Source Code Form,
        as described in Section 3.1, and You must inform recipients of the
        Executable Form how they can obtain a copy of such Source Code Form by
        reasonable means in a timely manner, at a charge no more than the cost
        of distribution to the recipient; and

     b. You may distribute such Executable Form under the terms of this License,
        or sublicense it under different terms, provided that the license for
        the Executable Form does not attempt to limit or alter the recipients’
        rights in the Source Code Form under this License.

3.3. Distribution of a Larger Work

     You may create and distribute a Larger Work under terms of Your choice,
     provided that You also comply with the requirements of this License for the
     Covered Software. If the Larger Work is a combination of Covered Software
     with a work governed by one or more Secondary Licenses, and the Covered
     Software is not Incompatible With Secondary Licenses, this License permits
     You to additionally distribute such Covered Software under the terms of
     such Secondary License(s), so that the recipient of the Larger Work may, at
     their option, further distribute the Covered Software under the terms of
     either this License or such Secondary License(s).

3.4. Notices

     You may not remove or alter the substance of any license notices (including
     copyright notices, patent notices, disclaimers of warranty, or limitations
     of liability) contained within the Source Code Form of the Covered
     Software, except that You may alter any license notices to the extent
     required to remedy known factual inaccuracies.

3.5. Application of Additional Terms

     You may choose to offer, and to charge a fee for, warranty, support,
     indemnity or liability obligations to one or more recipients of Covered
     Software. However, You may do so only on Your own behalf, and not on behalf
     of any Contributor. You must make it absolutely clear that any such
     warranty, support, indemnity, or liability obligation is offered by You
     alone, and You hereby agree to indemnify every Contributor for any
     liability incurred by such Contributor as a result of warranty, support,
     indemnity or liability terms You offer. You may include additional
     disclaimers of warranty and limitations of liability specific to any
     jurisdiction.

4. Inability to Comply Due to Statute or Regulation

   If it is impossible for You to comply with any of the terms of this License
   with respect to some or all of the Covered Software due to statute, judicial
   order, or regulation then You must: (a) comply with the terms of this License
   to the maximum extent possible; and (b) describe the limitations and the code
   they affect. Such description must be placed in a text file included with all
   distributions of the Covered Software under this License. Except to the
   extent prohibited by statute or regulation, such description must be
   sufficiently detailed for a recipient of ordinary skill to be able to
   understand it.

5. Termination

5.1. The rights granted under this License will terminate automatically if You
     fail to comply with any of its terms. However, if You become compliant,
     then the rights granted under this License from a particular Contributor
     are reinstated (a) provisionally, unless and until such Contributor
     explicitly and finally terminates Your grants, and (b) on an ongoing basis,
     if such Contributor fails to notify You of the non-compliance by some
     reasonable means prior to 60 days after You have come back into compliance.
     Moreover, Your grants from a particular Contributor are reinstated on an
     ongoing basis if such Contributor notifies You of the non-compliance by
     some reasonable means, this is the first time You have received notice of
     non-compliance with this License from such Contributor, and You become
     compliant prior to 30 days after Your receipt of the notice.

5.2. If You initiate litigation against any entity by asserting a patent
     infringement claim (excluding declaratory judgment actions, counter-claims,
     and cross-claims) alleging that a Contributor Version directly or
     indirectly infringes any patent, then the rights granted to You by any and
     all Contributors for the Covered Software under Section 2.1 of this License
     shall terminate.

5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
     license agreements (excluding distributors and resellers) which have been
     validly granted by You or Your distributors under this License prior to
     termination shall survive termination.

6. Disclaimer of Warranty

   Covered Software is provided under this License on an “as is” basis, without
   warranty of any kind, either expressed, implied, or statutory, including,
   without limitation, warranties that the Covered Software is free of defects,
   merchantable, fit for a particular purpose or non-infringing. The entire
   risk as to the quality and performance of the Covered Software is with You.
   Should any Covered Software prove defective in any respect, You (not any
   Contributor) assume the cost of any necessary servicing, repair, or
   correction. This disclaimer of warranty constitutes an essential part of this
   License. No use of  any Covered Software is authorized under this License
   except under this disclaimer.

7. Limitation of Liability

   Under no circumstances and under no legal theory, whether tort (including
   negligence), contract, or otherwise, shall any Contributor, or anyone who
   distributes Covered Software as permitted above, be liable to You for any
   direct, indirect, special, incidental, or consequential damages of any
   character including, without limitation, damages for lost profits, loss of
   goodwill, work stoppage, computer failure or malfunction, or any and all
   other commercial damages or losses, even if such party shall have been
   informed of the possibility of such damages. This limitation of liability
   shall not apply to liability for death or personal injury resulting from such
   party’s negligence to the extent applicable law prohibits such limitation.
   Some jurisdictions do not allow the exclusion or limitation of incidental or
   consequential damages, so this exclusion and limitation may not apply to You.

8. Litigation

   Any litigation relating to this License may be brought only in the courts of
   a jurisdiction where the defendant maintains its principal place of business
   and such litigation shall be governed by laws of that jurisdiction, without
   reference to its conflict-of-law provisions. Nothing in this Section shall
   prevent a party’s ability to bring cross-claims or counter-claims.

9. Miscellaneous

   This License represents the complete agreement concerning the subject matter
   hereof. If any provision of this License is held to be unenforceable, such
   provision shall be reformed only to the extent necessary to make it
   enforceable. Any law or regulation which provides that the language of a
   contract shall be construed against the drafter shall not be used to construe
   this License against a Contributor.


10. Versions of the License

10.1. New Versions

      Mozilla Foundation is the license steward. Except as provided in Section
      10.3, no one other than the license steward has the right to modify or
      publish new versions of this License. Each version will be given a
      distinguishing version number.

10.2. Effect of New Versions

      You may distribute the Covered Software under the terms of the version of
      the License under which You originally received the Covered Software, or
      under the terms of any subsequent version published by the license
      steward.

10.3. Modified Versions

      If you create software not governed by this License, and you want to
      create a new license for such software, you may create and use a modified
      version of this License if you rename the license and remove any
      references to the name of the license steward (except to note that such
      modified license differs from this License).

10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
      If You choose to distribute Source Code Form that is Incompatible With
      Secondary Licenses under the terms of this version of the License, the
      notice described in Exhibit B of this License must be attached.

Exhibit A - Source Code Form License Notice

      This Source Code Form is subject to the
      terms of the Mozilla Public License, v.
      2.0. If a copy of the MPL was not
      distributed with this file, You can
      obtain one at
      http://mozilla.org/MPL/2.0/.

If it is not possible or desirable to put the notice in a particular file, then
You may include the notice in a location (such as a LICENSE file in a relevant
directory) where a recipient would be likely to look for such a notice.

You may add additional accurate notices of copyright ownership.

Exhibit B - “Incompatible With Secondary Licenses” Notice

      This Source Code Form is “Incompatible
      With Secondary Licenses”, as defined by
      the Mozilla Public License, v. 2.0.



================================================
FILE: Makefile
================================================
.PHONY: fmt lint golint test test-with-coverage ci
# TODO: When Go 1.9 is released vendor folder should be ignored automatically
PACKAGES=`go list ./... | grep -v vendor | grep -v mocks`

fmt:
	for pkg in ${PACKAGES}; do \
		go fmt $$pkg; \
	done;

lint:
	gometalinter --tests --disable-all --deadline=120s -E vet -E gofmt -E misspell -E ineffassign -E goimports -E deadcode ./...

golint:
	for pkg in ${PACKAGES}; do \
		golint -set_exit_status $$pkg || GOLINT_FAILED=1; \
	done; \
	[ -z "$$GOLINT_FAILED" ]

test:
	TEST_FAILED= ; \
	for pkg in ${PACKAGES}; do \
		go test $$pkg || TEST_FAILED=1; \
	done; \
	[ -z "$$TEST_FAILED" ]

test-with-coverage:
	echo "" > coverage.out
	echo "mode: set" > coverage-all.out
	TEST_FAILED= ; \
	for pkg in ${PACKAGES}; do \
		go test -coverprofile=coverage.out -covermode=set $$pkg || TEST_FAILED=1; \
		tail -n +2 coverage.out >> coverage-all.out; \
	done; \
	[ -z "$$TEST_FAILED" ]
	#go tool cover -html=coverage-all.out

ci:
	bash -c 'docker-compose -f docker-compose.test.yml -p machinery_ci up --build --abort-on-container-exit --exit-code-from sut'


================================================
FILE: README.md
================================================
[1]: https://raw.githubusercontent.com/RichardKnop/assets/master/machinery/example_worker.png
[2]: https://raw.githubusercontent.com/RichardKnop/assets/master/machinery/example_worker_receives_tasks.png
[3]: http://patreon_public_assets.s3.amazonaws.com/sized/becomeAPatronBanner.png

## Machinery

Machinery is an asynchronous task queue/job queue based on distributed message passing.

[![godoc for RichardKnop/machinery](https://godoc.org/github.com/nathany/looper?status.svg)](http://godoc.org/github.com/RichardKnop/machinery/v1)
[![codecov for RichardKnop/machinery](https://codecov.io/gh/RichardKnop/machinery/branch/master/graph/badge.svg)](https://codecov.io/gh/RichardKnop/machinery)

[![Go Report Card](https://goreportcard.com/badge/github.com/RichardKnop/machinery)](https://goreportcard.com/report/github.com/RichardKnop/machinery)
[![OpenTracing Badge](https://img.shields.io/badge/OpenTracing-enabled-blue.svg)](http://opentracing.io)

[![Sourcegraph for RichardKnop/machinery](https://sourcegraph.com/github.com/RichardKnop/machinery/-/badge.svg)](https://sourcegraph.com/github.com/RichardKnop/machinery?badge)
[![Donate Bitcoin](https://img.shields.io/badge/donate-bitcoin-orange.svg)](https://richardknop.github.io/donate/)

---

* [V2 Experiment](#v2-experiment)
* [First Steps](#first-steps)
* [Configuration](#configuration)
  * [Lock](#lock)
  * [Broker](#broker)
  * [DefaultQueue](#defaultqueue)
  * [ResultBackend](#resultbackend)
  * [ResultsExpireIn](#resultsexpirein)
  * [AMQP](#amqp-2)
  * [DynamoDB](#dynamodb)
  * [Redis](#redis-2)
  * [GCPPubSub](#gcppubsub)
* [Custom Logger](#custom-logger)
* [Server](#server)
* [Workers](#workers)
* [Tasks](#tasks)
  * [Registering Tasks](#registering-tasks)
  * [Signatures](#signatures)
  * [Supported Types](#supported-types)
  * [Sending Tasks](#sending-tasks)
  * [Delayed Tasks](#delayed-tasks)
  * [Retry Tasks](#retry-tasks)
  * [Get Pending Tasks](#get-pending-tasks)
  * [Keeping Results](#keeping-results)
* [Workflows](#workflows)
  * [Groups](#groups)
  * [Chords](#chords)
  * [Chains](#chains)
* [Periodic Tasks & Workflows](#periodic-tasks--workflows)
  * [Periodic Tasks](#periodic-tasks)
  * [Periodic Groups](#periodic-groups)
  * [Periodic Chains](#periodic-chains)
  * [Periodic Chords](#periodic-chords)
* [Development](#development)
  * [Requirements](#requirements)
  * [Dependencies](#dependencies)
  * [Testing](#testing)

### V2

I recommend using V2 in order to avoid having to import all dependencies for brokers and backends you are not using.

Instead of factory, you will need to inject broker and backend objects to the server constructor:

```go
import (
  "github.com/RichardKnop/machinery/v2"
  backendsiface "github.com/RichardKnop/machinery/v2/backends/iface"
  brokersiface "github.com/RichardKnop/machinery/v2/brokers/iface"
  locksiface "github.com/RichardKnop/machinery/v2/locks/iface"
)

var broker brokersiface.Broker
var backend backendsiface.Backend
var lock locksiface.Lock
server := machinery.NewServer(cnf, broker, backend, lock)
// server.NewWorker("machinery", 10)
```

### First Steps

To install recommended v2 release:

```sh
go get github.com/RichardKnop/machinery/v2
```

If you want to use legacy v1 version, you still can:

```sh
go get github.com/RichardKnop/machinery
```

First, you will need to define some tasks. Look at sample tasks in `v2/example/tasks/tasks.go` to see a few examples.

Second, you will need to launch a worker process with one of these commands (v2 is recommended since it doesn't import dependencies for all brokers / backends, only those you actually need):

```sh
cd v2/
go run example/amqp/main.go worker
go run example/redigo/main.go worker // Redis with redigo driver
go run example/go-redis/main.go worker // Redis with Go Redis driver

go run example/amqp/main.go worker
go run example/redis/main.go worker
```

![Example worker][1]

Finally, once you have a worker running and waiting for tasks to consume, send some tasks with one of these commands (v2 is recommended since it doesn't import dependencies for all brokers / backends, only those you actually need):

```sh
cd v2
go run v2/example/amqp/main.go send
go run v2/example/redigo/main.go send // Redis with redigo driver
go run v2/example/go-redis/main.go send // Redis with Go Redis driver
```

You will be able to see the tasks being processed asynchronously by the worker:

![Example worker receives tasks][2]

### Configuration

The [config](/v2/config/config.go) package has convenience methods for loading configuration from environment variables or a YAML file. For example, load configuration from environment variables:

```go
cnf, err := config.NewFromEnvironment()
```

Or load from YAML file:

```go
cnf, err := config.NewFromYaml("config.yml", true)
```

Second boolean flag enables live reloading of configuration every 10 seconds. Use `false` to disable live reloading.

Machinery configuration is encapsulated by a `Config` struct and injected as a dependency to objects that need it.

#### Lock

##### Redis

Use Redis URL in one of these formats:

```
redis://[password@]host[port][/db_num]
```

For example:

1. `redis://localhost:6379`, or with password `redis://password@localhost:6379`

#### Broker

A message broker. Currently supported brokers are:

##### AMQP

Use AMQP URL in the format:

```
amqp://[username:password@]@host[:port]
```

For example:

1. `amqp://guest:guest@localhost:5672`

AMQP also supports multiples brokers urls. You need to specify the URL separator in the `MultipleBrokerSeparator` field.

##### Redis

Use Redis URL in one of these formats:

```
redis://[password@]host[port][/db_num]
redis+socket://[password@]/path/to/file.sock[:/db_num]
```

For example:

1. `redis://localhost:6379`, or with password `redis://password@localhost:6379`
2. `redis+socket://password@/path/to/file.sock:/0`

##### AWS SQS

Use AWS SQS URL in the format:

```
https://sqs.us-east-2.amazonaws.com/123456789012
```

See [AWS SQS docs](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html) for more information.
Also, configuring `AWS_REGION` is required, or an error would be thrown.

To use a manually configured SQS Client:

```go
var sqsClient = sqs.New(session.Must(session.NewSession(&aws.Config{
  Region:         aws.String("YOUR_AWS_REGION"),
  Credentials:    credentials.NewStaticCredentials("YOUR_AWS_ACCESS_KEY", "YOUR_AWS_ACCESS_SECRET", ""),
  HTTPClient:     &http.Client{
    Timeout: time.Second * 120,
  },
})))
var visibilityTimeout = 20
var cnf = &config.Config{
  Broker:          "YOUR_SQS_URL"
  DefaultQueue:    "machinery_tasks",
  ResultBackend:   "YOUR_BACKEND_URL",
  SQS: &config.SQSConfig{
    Client: sqsClient,
    // if VisibilityTimeout is nil default to the overall visibility timeout setting for the queue
    // https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html
    VisibilityTimeout: &visibilityTimeout,
    WaitTimeSeconds: 30,
  },
}
```

##### GCP Pub/Sub

Use GCP Pub/Sub URL in the format:

```
gcppubsub://YOUR_GCP_PROJECT_ID/YOUR_PUBSUB_SUBSCRIPTION_NAME
```

To use a manually configured Pub/Sub Client:

```go
pubsubClient, err := pubsub.NewClient(
    context.Background(),
    "YOUR_GCP_PROJECT_ID",
    option.WithServiceAccountFile("YOUR_GCP_SERVICE_ACCOUNT_FILE"),
)

cnf := &config.Config{
  Broker:          "gcppubsub://YOUR_GCP_PROJECT_ID/YOUR_PUBSUB_SUBSCRIPTION_NAME"
  DefaultQueue:    "YOUR_PUBSUB_TOPIC_NAME",
  ResultBackend:   "YOUR_BACKEND_URL",
  GCPPubSub: config.GCPPubSubConfig{
    Client: pubsubClient,
  },
}
```

#### DefaultQueue

Default queue name, e.g. `machinery_tasks`.

#### ResultBackend

Result backend to use for keeping task states and results.

Currently supported backends are:

##### Redis

Use Redis URL in one of these formats:

```
redis://[password@]host[port][/db_num]
redis+socket://[password@]/path/to/file.sock[:/db_num]
```

For example:

1. `redis://localhost:6379`, or with password `redis://password@localhost:6379`
2. `redis+socket://password@/path/to/file.sock:/0`
3. cluster/sentinel `redis://host1:port1,host2:port2,host3:port3/0`
4. cluster/sentinel with password `redis://pass@host1:port1,host2:port2,host3:port3/0`

##### Memcache

Use Memcache URL in the format:

```
memcache://host1[:port1][,host2[:port2],...[,hostN[:portN]]]
```

For example:

1. `memcache://localhost:11211` for a single instance, or
2. `memcache://10.0.0.1:11211,10.0.0.2:11211` for a cluster

##### AMQP

Use AMQP URL in the format:

```
amqp://[username:password@]@host[:port]
```

For example:

1. `amqp://guest:guest@localhost:5672`

> Keep in mind AMQP is not recommended as a result backend. See [Keeping Results](https://github.com/RichardKnop/machinery#keeping-results)

##### MongoDB

Use Mongodb URL in the format:

```
mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
```

For example:

1. `mongodb://localhost:27017/taskresults`

See [MongoDB docs](https://docs.mongodb.org/manual/reference/connection-string/) for more information.


#### ResultsExpireIn

How long to store task results for in seconds. Defaults to `3600` (1 hour).

#### AMQP

RabbitMQ related configuration. Not necessary if you are using other broker/backend.

* `Exchange`: exchange name, e.g. `machinery_exchange`
* `ExchangeType`: exchange type, e.g. `direct`
* `QueueBindingArguments`: an optional map of additional arguments used when binding to an AMQP queue
* `BindingKey`: The queue is bind to the exchange with this key, e.g. `machinery_task`
* `PrefetchCount`: How many tasks to prefetch (set to `1` if you have long running tasks)
* `DelayedQueue`: delayed queue name to be used for task retry or delayed task (if empty it will follow auto create and delate delayed queues)

#### DynamoDB

DynamoDB related configuration. Not necessary if you are using other backend.
* `TaskStatesTable`: Custom table name for saving task states. Default one is `task_states`, and make sure to create this table in your AWS admin first, using `TaskUUID` as table's primary key.
* `GroupMetasTable`: Custom table name for saving group metas. Default one is `group_metas`, and make sure to create this table in your AWS admin first, using `GroupUUID` as table's primary key.
For example:

```
dynamodb:
  task_states_table: 'task_states'
  group_metas_table: 'group_metas'
```
If these tables are not found, an fatal error would be thrown.

If you wish to expire the records, you can configure the `TTL` field in AWS admin for these tables. The `TTL` field is set based on the `ResultsExpireIn` value in the Server's config. See https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/howitworks-ttl.html for more information.

#### Redis

Redis related configuration. Not necessary if you are using other backend.

See: [config](/v1/config/config.go) (TODO)

#### GCPPubSub

GCPPubSub related configuration. Not necessary if you are using other backend.

See: [config](/v1/config/config.go) (TODO)

### Custom Logger

You can define a custom logger by implementing the following interface:

```go
type Interface interface {
  Print(...interface{})
  Printf(string, ...interface{})
  Println(...interface{})

  Fatal(...interface{})
  Fatalf(string, ...interface{})
  Fatalln(...interface{})

  Panic(...interface{})
  Panicf(string, ...interface{})
  Panicln(...interface{})
}
```

Then just set the logger in your setup code by calling `Set` function exported by `github.com/RichardKnop/machinery/v1/log` package:

```go
log.Set(myCustomLogger)
```

### Server

A Machinery library must be instantiated before use. The way this is done is by creating a `Server` instance. `Server` is a base object which stores Machinery configuration and registered tasks. E.g.:

```go
import (
  "github.com/RichardKnop/machinery/v1/config"
  "github.com/RichardKnop/machinery/v1"
)

var cnf = &config.Config{
  Broker:        "amqp://guest:guest@localhost:5672/",
  DefaultQueue:  "machinery_tasks",
  ResultBackend: "amqp://guest:guest@localhost:5672/",
  AMQP: &config.AMQPConfig{
    Exchange:     "machinery_exchange",
    ExchangeType: "direct",
    BindingKey:   "machinery_task",
  },
}

server, err := machinery.NewServer(cnf)
if err != nil {
  // do something with the error
}
```

### Workers

In order to consume tasks, you need to have one or more workers running. All you need to run a worker is a `Server` instance with registered tasks. E.g.:

```go
worker := server.NewWorker("worker_name", 10)
err := worker.Launch()
if err != nil {
  // do something with the error
}
```

Each worker will only consume registered tasks. For each task on the queue the Worker.Process() method will be run
in a goroutine. Use the second parameter of `server.NewWorker` to limit the number of concurrently running Worker.Process()
calls (per worker). Example: 1 will serialize task execution while 0 makes the number of concurrently executed tasks unlimited (default).

### Tasks

Tasks are a building block of Machinery applications. A task is a function which defines what happens when a worker receives a message.

Each task needs to return an error as a last return value. In addition to error tasks can now return any number of arguments.

Examples of valid tasks:

```go
func Add(args ...int64) (int64, error) {
  sum := int64(0)
  for _, arg := range args {
    sum += arg
  }
  return sum, nil
}

func Multiply(args ...int64) (int64, error) {
  sum := int64(1)
  for _, arg := range args {
    sum *= arg
  }
  return sum, nil
}

// You can use context.Context as first argument to tasks, useful for open tracing
func TaskWithContext(ctx context.Context, arg Arg) error {
  // ... use ctx ...
  return nil
}

// Tasks need to return at least error as a minimal requirement
func DummyTask(arg string) error {
  return errors.New(arg)
}

// You can also return multiple results from the task
func DummyTask2(arg1, arg2 string) (string, string, error) {
  return arg1, arg2, nil
}
```

#### Registering Tasks

Before your workers can consume a task, you need to register it with the server. This is done by assigning a task a unique name:

```go
server.RegisterTasks(map[string]interface{}{
  "add":      Add,
  "multiply": Multiply,
})
```

Tasks can also be registered one by one:

```go
server.RegisterTask("add", Add)
server.RegisterTask("multiply", Multiply)
```

Simply put, when a worker receives a message like this:

```json
{
  "UUID": "48760a1a-8576-4536-973b-da09048c2ac5",
  "Name": "add",
  "RoutingKey": "",
  "ETA": null,
  "GroupUUID": "",
  "GroupTaskCount": 0,
  "Args": [
    {
      "Type": "int64",
      "Value": 1,
    },
    {
      "Type": "int64",
      "Value": 1,
    }
  ],
  "Immutable": false,
  "RetryCount": 0,
  "RetryTimeout": 0,
  "OnSuccess": null,
  "OnError": null,
  "ChordCallback": null
}
```

It will call Add(1, 1). Each task should return an error as well so we can handle failures.

Ideally, tasks should be idempotent which means there will be no unintended consequences when a task is called multiple times with the same arguments.

#### Signatures

A signature wraps calling arguments, execution options (such as immutability) and success/error callbacks of a task so it can be sent across the wire to workers. Task signatures implement a simple interface:

```go
// Arg represents a single argument passed to invocation fo a task
type Arg struct {
  Type  string
  Value interface{}
}

// Headers represents the headers which should be used to direct the task
type Headers map[string]interface{}

// Signature represents a single task invocation
type Signature struct {
  UUID           string
  Name           string
  RoutingKey     string
  ETA            *time.Time
  GroupUUID      string
  GroupTaskCount int
  Args           []Arg
  Headers        Headers
  Immutable      bool
  RetryCount     int
  RetryTimeout   int
  OnSuccess      []*Signature
  OnError        []*Signature
  ChordCallback  *Signature
}
```

`UUID` is a unique ID of a task. You can either set it yourself or it will be automatically generated.

`Name` is the unique task name by which it is registered against a Server instance.

`RoutingKey` is used for routing a task to correct queue. If you leave it empty, the default behaviour will be to set it to the default queue's binding key for direct exchange type and to the default queue name for other exchange types.

`ETA` is  a timestamp used for delaying a task. if it's nil, the task will be published for workers to consume immediately. If it is set, the task will be delayed until the ETA timestamp.

`GroupUUID`, `GroupTaskCount` are useful for creating groups of tasks.

`Args` is a list of arguments that will be passed to the task when it is executed by a worker.

`Headers` is a list of headers that will be used when publishing the task to AMQP queue.

`Immutable` is a flag which defines whether a result of the executed task can be modified or not. This is important with `OnSuccess` callbacks. Immutable task will not pass its result to its success callbacks while a mutable task will prepend its result to args sent to callback tasks. Long story short, set Immutable to false if you want to pass result of the first task in a chain to the second task.

`RetryCount` specifies how many times a failed task should be retried (defaults to 0). Retry attempts will be spaced out in time, after each failure another attempt will be scheduled further to the future.

`RetryTimeout` specifies how long to wait before resending task to the queue for retry attempt. Default behaviour is to use fibonacci sequence to increase the timeout after each failed retry attempt.

`OnSuccess` defines tasks which will be called after the task has executed successfully. It is a slice of task signature structs.

`OnError` defines tasks which will be called after the task execution fails. The first argument passed to error callbacks will be the error string returned from the failed task.

`ChordCallback` is used to create a callback to a group of tasks.

#### Supported Types

Machinery encodes tasks to JSON before sending them to the broker. Task results are also stored in the backend as JSON encoded strings. Therefor only types with native JSON representation can be supported. Currently supported types are:

* `bool`
* `int`
* `int8`
* `int16`
* `int32`
* `int64`
* `uint`
* `uint8`
* `uint16`
* `uint32`
* `uint64`
* `float32`
* `float64`
* `string`
* `[]bool`
* `[]int`
* `[]int8`
* `[]int16`
* `[]int32`
* `[]int64`
* `[]uint`
* `[]uint8`
* `[]uint16`
* `[]uint32`
* `[]uint64`
* `[]float32`
* `[]float64`
* `[]string`

#### Sending Tasks

Tasks can be called by passing an instance of `Signature` to an `Server` instance. E.g:

```go
import (
  "github.com/RichardKnop/machinery/v1/tasks"
)

signature := &tasks.Signature{
  Name: "add",
  Args: []tasks.Arg{
    {
      Type:  "int64",
      Value: 1,
    },
    {
      Type:  "int64",
      Value: 1,
    },
  },
}

asyncResult, err := server.SendTask(signature)
if err != nil {
  // failed to send the task
  // do something with the error
}
```

#### Delayed Tasks

You can delay a task by setting the `ETA` timestamp field on the task signature.

```go
// Delay the task by 5 seconds
eta := time.Now().UTC().Add(time.Second * 5)
signature.ETA = &eta
```

#### Retry Tasks

You can set a number of retry attempts before declaring task as failed. Fibonacci sequence will be used to space out retry requests over time. (See `RetryTimeout` for details.)

```go
// If the task fails, retry it up to 3 times
signature.RetryCount = 3
```

Alternatively, you can return `tasks.ErrRetryTaskLater` from your task and specify duration after which the task should be retried, e.g.:

```go
return tasks.NewErrRetryTaskLater("some error", 4 * time.Hour)
```

#### Get Pending Tasks

Tasks currently waiting in the queue to be consumed by workers can be inspected, e.g.:

```go
server.GetBroker().GetPendingTasks("some_queue")
```

> Currently only supported by Redis broker.

#### Keeping Results

If you configure a result backend, the task states and results will be persisted. Possible states:

```go
const (
	// StatePending - initial state of a task
	StatePending = "PENDING"
	// StateReceived - when task is received by a worker
	StateReceived = "RECEIVED"
	// StateStarted - when the worker starts processing the task
	StateStarted = "STARTED"
	// StateRetry - when failed task has been scheduled for retry
	StateRetry = "RETRY"
	// StateSuccess - when the task is processed successfully
	StateSuccess = "SUCCESS"
	// StateFailure - when processing of the task fails
	StateFailure = "FAILURE"
)
```

> When using AMQP as a result backend, task states will be persisted in separate queues for each task. Although RabbitMQ can scale up to thousands of queues, it is strongly advised to use a better suited result backend (e.g. Memcache) when you are expecting to run a large number of parallel tasks.

```go
// TaskResult represents an actual return value of a processed task
type TaskResult struct {
  Type  string      `bson:"type"`
  Value interface{} `bson:"value"`
}

// TaskState represents a state of a task
type TaskState struct {
  TaskUUID  string        `bson:"_id"`
  State     string        `bson:"state"`
  Results   []*TaskResult `bson:"results"`
  Error     string        `bson:"error"`
}

// GroupMeta stores useful metadata about tasks within the same group
// E.g. UUIDs of all tasks which are used in order to check if all tasks
// completed successfully or not and thus whether to trigger chord callback
type GroupMeta struct {
  GroupUUID      string   `bson:"_id"`
  TaskUUIDs      []string `bson:"task_uuids"`
  ChordTriggered bool     `bson:"chord_triggered"`
  Lock           bool     `bson:"lock"`
}
```

`TaskResult` represents a slice of return values of a processed task.

`TaskState` struct will be serialized and stored every time a task state changes.

`GroupMeta` stores useful metadata about tasks within the same group. E.g. UUIDs of all tasks which are used in order to check if all tasks completed successfully or not and thus whether to trigger chord callback.

`AsyncResult` object allows you to check for the state of a task:

```go
taskState := asyncResult.GetState()
fmt.Printf("Current state of %v task is:\n", taskState.TaskUUID)
fmt.Println(taskState.State)
```

There are couple of convenient methods to inspect the task status:

```go
asyncResult.GetState().IsCompleted()
asyncResult.GetState().IsSuccess()
asyncResult.GetState().IsFailure()
```

You can also do a synchronous blocking call to wait for a task result:

```go
results, err := asyncResult.Get(time.Duration(time.Millisecond * 5))
if err != nil {
  // getting result of a task failed
  // do something with the error
}
for _, result := range results {
  fmt.Println(result.Interface())
}
```

#### Error Handling

When a task returns with an error, the default behavior is to first attempty to retry the task if it's retriable, otherwise log the error and then eventually call any error callbacks.

To customize this, you can set a custom error handler on the worker which can do more than just logging after retries fail and error callbacks are trigerred:

```go
worker.SetErrorHandler(func (err error) {
  customHandler(err)
})
```

### Workflows

Running a single asynchronous task is fine but often you will want to design a workflow of tasks to be executed in an orchestrated way. There are couple of useful functions to help you design workflows.

#### Groups

`Group` is a set of tasks which will be executed in parallel, independent of each other. E.g.:

```go
import (
  "github.com/RichardKnop/machinery/v1/tasks"
  "github.com/RichardKnop/machinery/v1"
)

signature1 := tasks.Signature{
  Name: "add",
  Args: []tasks.Arg{
    {
      Type:  "int64",
      Value: 1,
    },
    {
      Type:  "int64",
      Value: 1,
    },
  },
}

signature2 := tasks.Signature{
  Name: "add",
  Args: []tasks.Arg{
    {
      Type:  "int64",
      Value: 5,
    },
    {
      Type:  "int64",
      Value: 5,
    },
  },
}

group, _ := tasks.NewGroup(&signature1, &signature2)
asyncResults, err := server.SendGroup(group, 0) //The second parameter specifies the number of concurrent sending tasks. 0 means unlimited.
if err != nil {
  // failed to send the group
  // do something with the error
}
```

`SendGroup` returns a slice of `AsyncResult` objects. So you can do a blocking call and wait for the result of groups tasks:

```go
for _, asyncResult := range asyncResults {
  results, err := asyncResult.Get(time.Duration(time.Millisecond * 5))
  if err != nil {
    // getting result of a task failed
    // do something with the error
  }
  for _, result := range results {
    fmt.Println(result.Interface())
  }
}
```

#### Chords

`Chord` allows you to define a callback to be executed after all tasks in a group finished processing, e.g.:

```go
import (
  "github.com/RichardKnop/machinery/v1/tasks"
  "github.com/RichardKnop/machinery/v1"
)

signature1 := tasks.Signature{
  Name: "add",
  Args: []tasks.Arg{
    {
      Type:  "int64",
      Value: 1,
    },
    {
      Type:  "int64",
      Value: 1,
    },
  },
}

signature2 := tasks.Signature{
  Name: "add",
  Args: []tasks.Arg{
    {
      Type:  "int64",
      Value: 5,
    },
    {
      Type:  "int64",
      Value: 5,
    },
  },
}

signature3 := tasks.Signature{
  Name: "multiply",
}

group := tasks.NewGroup(&signature1, &signature2)
chord, _ := tasks.NewChord(group, &signature3)
chordAsyncResult, err := server.SendChord(chord, 0) //The second parameter specifies the number of concurrent sending tasks. 0 means unlimited.
if err != nil {
  // failed to send the chord
  // do something with the error
}
```

The above example executes task1 and task2 in parallel, aggregates their results and passes them to task3. Therefore what would end up happening is:

```
multiply(add(1, 1), add(5, 5))
```

More explicitly:

```
(1 + 1) * (5 + 5) = 2 * 10 = 20
```

`SendChord` returns `ChordAsyncResult` which follows AsyncResult's interface. So you can do a blocking call and wait for the result of the callback:

```go
results, err := chordAsyncResult.Get(time.Duration(time.Millisecond * 5))
if err != nil {
  // getting result of a chord failed
  // do something with the error
}
for _, result := range results {
  fmt.Println(result.Interface())
}
```

#### Chains

`Chain` is simply a set of tasks which will be executed one by one, each successful task triggering the next task in the chain. E.g.:

```go
import (
  "github.com/RichardKnop/machinery/v1/tasks"
  "github.com/RichardKnop/machinery/v1"
)

signature1 := tasks.Signature{
  Name: "add",
  Args: []tasks.Arg{
    {
      Type:  "int64",
      Value: 1,
    },
    {
      Type:  "int64",
      Value: 1,
    },
  },
}

signature2 := tasks.Signature{
  Name: "add",
  Args: []tasks.Arg{
    {
      Type:  "int64",
      Value: 5,
    },
    {
      Type:  "int64",
      Value: 5,
    },
  },
}

signature3 := tasks.Signature{
  Name: "multiply",
  Args: []tasks.Arg{
    {
      Type:  "int64",
      Value: 4,
    },
  },
}

chain, _ := tasks.NewChain(&signature1, &signature2, &signature3)
chainAsyncResult, err := server.SendChain(chain)
if err != nil {
  // failed to send the chain
  // do something with the error
}
```

The above example executes task1, then task2 and then task3. When a task is completed successfully, the result is appended to the end of list of arguments for the next task in the chain. Therefore what would end up happening is:

```
multiply(4, add(5, 5, add(1, 1)))
```

More explicitly:

```
  4 * (5 + 5 + (1 + 1))   # task1: add(1, 1)        returns 2
= 4 * (5 + 5 + 2)         # task2: add(5, 5, 2)     returns 12
= 4 * (12)                # task3: multiply(4, 12)  returns 48
= 48
```

`SendChain` returns `ChainAsyncResult` which follows AsyncResult's interface. So you can do a blocking call and wait for the result of the whole chain:

```go
results, err := chainAsyncResult.Get(time.Duration(time.Millisecond * 5))
if err != nil {
  // getting result of a chain failed
  // do something with the error
}
for _, result := range results {
  fmt.Println(result.Interface())
}
```

### Periodic Tasks & Workflows

Machinery now supports scheduling periodic tasks and workflows. See examples bellow.

#### Periodic Tasks

```go
import (
  "github.com/RichardKnop/machinery/v1/tasks"
)

signature := &tasks.Signature{
  Name: "add",
  Args: []tasks.Arg{
    {
      Type:  "int64",
      Value: 1,
    },
    {
      Type:  "int64",
      Value: 1,
    },
  },
}
err := server.RegisterPeriodicTask("0 6 * * ?", "periodic-task", signature)
if err != nil {
  // failed to register periodic task
}
```

#### Periodic Groups

```go
import (
  "github.com/RichardKnop/machinery/v1/tasks"
  "github.com/RichardKnop/machinery/v1"
)

signature1 := tasks.Signature{
  Name: "add",
  Args: []tasks.Arg{
    {
      Type:  "int64",
      Value: 1,
    },
    {
      Type:  "int64",
      Value: 1,
    },
  },
}

signature2 := tasks.Signature{
  Name: "add",
  Args: []tasks.Arg{
    {
      Type:  "int64",
      Value: 5,
    },
    {
      Type:  "int64",
      Value: 5,
    },
  },
}

group, _ := tasks.NewGroup(&signature1, &signature2)
err := server.RegisterPeriodicGroup("0 6 * * ?", "periodic-group", group)
if err != nil {
  // failed to register periodic group
}
```

#### Periodic Chains

```go
import (
  "github.com/RichardKnop/machinery/v1/tasks"
  "github.com/RichardKnop/machinery/v1"
)

signature1 := tasks.Signature{
  Name: "add",
  Args: []tasks.Arg{
    {
      Type:  "int64",
      Value: 1,
    },
    {
      Type:  "int64",
      Value: 1,
    },
  },
}

signature2 := tasks.Signature{
  Name: "add",
  Args: []tasks.Arg{
    {
      Type:  "int64",
      Value: 5,
    },
    {
      Type:  "int64",
      Value: 5,
    },
  },
}

signature3 := tasks.Signature{
  Name: "multiply",
  Args: []tasks.Arg{
    {
      Type:  "int64",
      Value: 4,
    },
  },
}

chain, _ := tasks.NewChain(&signature1, &signature2, &signature3)
err := server.RegisterPeriodicChain("0 6 * * ?", "periodic-chain", chain)
if err != nil {
  // failed to register periodic chain
}
```

#### Chord

```go
import (
  "github.com/RichardKnop/machinery/v1/tasks"
  "github.com/RichardKnop/machinery/v1"
)

signature1 := tasks.Signature{
  Name: "add",
  Args: []tasks.Arg{
    {
      Type:  "int64",
      Value: 1,
    },
    {
      Type:  "int64",
      Value: 1,
    },
  },
}

signature2 := tasks.Signature{
  Name: "add",
  Args: []tasks.Arg{
    {
      Type:  "int64",
      Value: 5,
    },
    {
      Type:  "int64",
      Value: 5,
    },
  },
}

signature3 := tasks.Signature{
  Name: "multiply",
}

group := tasks.NewGroup(&signature1, &signature2)
chord, _ := tasks.NewChord(group, &signature3)
err := server.RegisterPeriodicChord("0 6 * * ?", "periodic-chord", chord)
if err != nil {
  // failed to register periodic chord
}
```

### Development

#### Requirements

* Go
* RabbitMQ (optional)
* Redis
* Memcached (optional)
* MongoDB (optional)

On OS X systems, you can install requirements using [Homebrew](http://brew.sh/):

```sh
brew install go
brew install rabbitmq
brew install redis
brew install memcached
brew install mongodb
```

Or optionally use the corresponding [Docker](http://docker.io/) containers:

```
docker run -d -p 5672:5672 rabbitmq
docker run -d -p 6379:6379 redis
docker run -d -p 11211:11211 memcached
docker run -d -p 27017:27017 mongo
docker run -d -p 6831:6831/udp -p 16686:16686 jaegertracing/all-in-one:latest
```

#### Dependencies

Since Go 1.11, a new recommended dependency management system is via [modules](https://github.com/golang/go/wiki/Modules).

This is one of slight weaknesses of Go as dependency management is not a solved problem. Previously Go was officially recommending to use the [dep tool](https://github.com/golang/dep) but that has been abandoned now in favor of modules.

#### Testing

Easiest (and platform agnostic) way to run tests is via `docker-compose`:

```sh
make ci
```

This will basically run docker-compose command:

```sh
(docker-compose -f docker-compose.test.yml -p machinery_ci up --build -d) && (docker logs -f machinery_sut &) && (docker wait machinery_sut)
```

Alternative approach is to setup a development environment on your machine.

In order to enable integration tests, you will need to install all required services (RabbitMQ, Redis, Memcache, MongoDB) and export these environment variables:

```sh
export AMQP_URL=amqp://guest:guest@localhost:5672/
export REDIS_URL=localhost:6379
export MEMCACHE_URL=localhost:11211
export MONGODB_URL=localhost:27017
```

To run integration tests against an SQS instance, you will need to create a "test_queue" in SQS and export these environment variables:

```sh
export SQS_URL=https://YOUR_SQS_URL
export AWS_ACCESS_KEY_ID=YOUR_AWS_ACCESS_KEY_ID
export AWS_SECRET_ACCESS_KEY=YOUR_AWS_SECRET_ACCESS_KEY
export AWS_DEFAULT_REGION=YOUR_AWS_DEFAULT_REGION
```

Then just run:

```sh
make test
```

If the environment variables are not exported, `make test` will only run unit tests.


================================================
FILE: docker-compose.test.yml
================================================
version: "2"

services:
  sut:
    container_name: machinery_sut
    image: machinery_sut:latest
    volumes:
      - "./:/go/src/github.com/RichardKnop/machinery"
    depends_on:
      - rabbitmq
      - redis
      - memcached
      - mongo
      - gcppubsub
    links:
      - rabbitmq
      - redis
      - memcached
      - mongo
      - gcppubsub
    build:
      context: .
      dockerfile: ./Dockerfile.test
    environment:
      AMQP_URLS: 'amqp://guest:guest@dummy:5672/,amqp://guest:guest@rabbitmq:5672/'
      AMQP_URLS_SEPARATOR: ','
      REDIS_URL: 'redis:6379'
      MEMCACHE_URL: 'memcached:11211'
      MONGODB_URL: 'mongo:27017'
      SQS_URL: ${SQS_URL}
      AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
      AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
      AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION}
      AWS_REGION: 'us-west-2'
      GCPPUBSUB_URL: 'gcppubsub://example-project/test_subscription_queue'
      GCPPUBSUB_TOPIC: 'test_topic_queue'
      PUBSUB_EMULATOR_HOST: 'gcppubsub:8085'

  rabbitmq:
    container_name: machinery_sut_rabbitmq
    image: rabbitmq
    environment:
      - RABBITMQ_DEFAULT_USER=guest
      - RABBITMQ_DEFAULT_PASS=guest
    logging:
      driver: none

  redis:
    container_name: machinery_sut_redis
    image: redis
    logging:
      driver: none

  memcached:
    container_name: machinery_sut_memcached
    image: memcached
    logging:
      driver: none

  mongo:
    container_name: machinery_sut_mongo
    image: mongo
    logging:
      driver: none

  gcppubsub:
    container_name: machinery_sut_gcppubsub
    build:
      context: .
      dockerfile: ./Dockerfile.gcppubsub
    logging:
      driver: none

================================================
FILE: example/amqp/main.go
================================================
package main

import (
	"context"
	"errors"
	"fmt"
	"os"
	"time"

	"github.com/google/uuid"
	"github.com/urfave/cli"

	"github.com/RichardKnop/machinery/v1"
	"github.com/RichardKnop/machinery/v1/config"
	"github.com/RichardKnop/machinery/v1/log"
	"github.com/RichardKnop/machinery/v1/tasks"

	exampletasks "github.com/RichardKnop/machinery/example/tasks"
	tracers "github.com/RichardKnop/machinery/example/tracers"
	opentracing "github.com/opentracing/opentracing-go"
	opentracing_log "github.com/opentracing/opentracing-go/log"
)

var (
	app *cli.App
)

func init() {
	// Initialise a CLI app
	app = cli.NewApp()
	app.Name = "machinery"
	app.Usage = "machinery worker and send example tasks with machinery send"
	app.Version = "0.0.0"
}

func main() {
	// Set the CLI app commands
	app.Commands = []cli.Command{
		{
			Name:  "worker",
			Usage: "launch machinery worker",
			Action: func(c *cli.Context) error {
				if err := worker(); err != nil {
					return cli.NewExitError(err.Error(), 1)
				}
				return nil
			},
		},
		{
			Name:  "send",
			Usage: "send example tasks ",
			Action: func(c *cli.Context) error {
				if err := send(); err != nil {
					return cli.NewExitError(err.Error(), 1)
				}
				return nil
			},
		},
	}

	// Run the CLI app
	app.Run(os.Args)
}

func startServer() (*machinery.Server, error) {
	cnf := &config.Config{
		Broker:          "amqp://guest:guest@localhost:5672/",
		DefaultQueue:    "machinery_tasks",
		ResultBackend:   "amqp://guest:guest@localhost:5672/",
		ResultsExpireIn: 3600,
		AMQP: &config.AMQPConfig{
			Exchange:      "machinery_exchange",
			ExchangeType:  "direct",
			BindingKey:    "machinery_task",
			PrefetchCount: 3,
		},
	}

	server, err := machinery.NewServer(cnf)
	if err != nil {
		return nil, err
	}

	// Register tasks
	tasks := map[string]interface{}{
		"add":               exampletasks.Add,
		"multiply":          exampletasks.Multiply,
		"sum_ints":          exampletasks.SumInts,
		"sum_floats":        exampletasks.SumFloats,
		"concat":            exampletasks.Concat,
		"split":             exampletasks.Split,
		"panic_task":        exampletasks.PanicTask,
		"long_running_task": exampletasks.LongRunningTask,
	}

	return server, server.RegisterTasks(tasks)
}

func worker() error {
	consumerTag := "machinery_worker"

	cleanup, err := tracers.SetupTracer(consumerTag)
	if err != nil {
		log.FATAL.Fatalln("Unable to instantiate a tracer:", err)
	}
	defer cleanup()

	server, err := startServer()
	if err != nil {
		return err
	}

	// The second argument is a consumer tag
	// Ideally, each worker should have a unique tag (worker1, worker2 etc)
	worker := server.NewWorker(consumerTag, 0)

	// Here we inject some custom code for error handling,
	// start and end of task hooks, useful for metrics for example.
	errorhandler := func(err error) {
		log.ERROR.Println("I am an error handler:", err)
	}

	pretaskhandler := func(signature *tasks.Signature) {
		log.INFO.Println("I am a start of task handler for:", signature.Name)
	}

	posttaskhandler := func(signature *tasks.Signature) {
		log.INFO.Println("I am an end of task handler for:", signature.Name)
	}

	worker.SetPostTaskHandler(posttaskhandler)
	worker.SetErrorHandler(errorhandler)
	worker.SetPreTaskHandler(pretaskhandler)

	return worker.Launch()
}

func send() error {
	cleanup, err := tracers.SetupTracer("sender")
	if err != nil {
		log.FATAL.Fatalln("Unable to instantiate a tracer:", err)
	}
	defer cleanup()

	server, err := startServer()
	if err != nil {
		return err
	}

	var (
		addTask0, addTask1, addTask2                      tasks.Signature
		multiplyTask0, multiplyTask1                      tasks.Signature
		sumIntsTask, sumFloatsTask, concatTask, splitTask tasks.Signature
		panicTask                                         tasks.Signature
		longRunningTask                                   tasks.Signature
	)

	var initTasks = func() {
		addTask0 = tasks.Signature{
			Name: "add",
			Args: []tasks.Arg{
				{
					Type:  "int64",
					Value: 1,
				},
				{
					Type:  "int64",
					Value: 1,
				},
			},
		}

		addTask1 = tasks.Signature{
			Name: "add",
			Args: []tasks.Arg{
				{
					Type:  "int64",
					Value: 2,
				},
				{
					Type:  "int64",
					Value: 2,
				},
			},
		}

		addTask2 = tasks.Signature{
			Name: "add",
			Args: []tasks.Arg{
				{
					Type:  "int64",
					Value: 5,
				},
				{
					Type:  "int64",
					Value: 6,
				},
			},
		}

		multiplyTask0 = tasks.Signature{
			Name: "multiply",
			Args: []tasks.Arg{
				{
					Type:  "int64",
					Value: 4,
				},
			},
		}

		multiplyTask1 = tasks.Signature{
			Name: "multiply",
		}

		sumIntsTask = tasks.Signature{
			Name: "sum_ints",
			Args: []tasks.Arg{
				{
					Type:  "[]int64",
					Value: []int64{1, 2},
				},
			},
		}

		sumFloatsTask = tasks.Signature{
			Name: "sum_floats",
			Args: []tasks.Arg{
				{
					Type:  "[]float64",
					Value: []float64{1.5, 2.7},
				},
			},
		}

		concatTask = tasks.Signature{
			Name: "concat",
			Args: []tasks.Arg{
				{
					Type:  "[]string",
					Value: []string{"foo", "bar"},
				},
			},
		}

		splitTask = tasks.Signature{
			Name: "split",
			Args: []tasks.Arg{
				{
					Type:  "string",
					Value: "foo",
				},
			},
		}

		panicTask = tasks.Signature{
			Name: "panic_task",
		}

		longRunningTask = tasks.Signature{
			Name: "long_running_task",
		}
	}

	/*
	 * Lets start a span representing this run of the `send` command and
	 * set a batch id as baggage so it can travel all the way into
	 * the worker functions.
	 */
	span, ctx := opentracing.StartSpanFromContext(context.Background(), "send")
	defer span.Finish()

	batchID := uuid.New().String()
	span.SetBaggageItem("batch.id", batchID)
	span.LogFields(opentracing_log.String("batch.id", batchID))

	log.INFO.Println("Starting batch:", batchID)
	/*
	 * First, let's try sending a single task
	 */
	initTasks()

	log.INFO.Println("Single task:")

	asyncResult, err := server.SendTaskWithContext(ctx, &addTask0)
	if err != nil {
		return fmt.Errorf("Could not send task: %s", err.Error())
	}

	results, err := asyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		return fmt.Errorf("Getting task result failed with error: %s", err.Error())
	}
	log.INFO.Printf("1 + 1 = %v\n", tasks.HumanReadableResults(results))

	/*
	 * Try couple of tasks with a slice argument and slice return value
	 */
	asyncResult, err = server.SendTaskWithContext(ctx, &sumIntsTask)
	if err != nil {
		return fmt.Errorf("Could not send task: %s", err.Error())
	}

	results, err = asyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		return fmt.Errorf("Getting task result failed with error: %s", err.Error())
	}
	log.INFO.Printf("sum([1, 2]) = %v\n", tasks.HumanReadableResults(results))

	asyncResult, err = server.SendTaskWithContext(ctx, &sumFloatsTask)
	if err != nil {
		return fmt.Errorf("Could not send task: %s", err.Error())
	}

	results, err = asyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		return fmt.Errorf("Getting task result failed with error: %s", err.Error())
	}
	log.INFO.Printf("sum([1.5, 2.7]) = %v\n", tasks.HumanReadableResults(results))

	asyncResult, err = server.SendTaskWithContext(ctx, &concatTask)
	if err != nil {
		return fmt.Errorf("Could not send task: %s", err.Error())
	}

	results, err = asyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		return fmt.Errorf("Getting task result failed with error: %s", err.Error())
	}
	log.INFO.Printf("concat([\"foo\", \"bar\"]) = %v\n", tasks.HumanReadableResults(results))

	asyncResult, err = server.SendTaskWithContext(ctx, &splitTask)
	if err != nil {
		return fmt.Errorf("Could not send task: %s", err.Error())
	}

	results, err = asyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		return fmt.Errorf("Getting task result failed with error: %s", err.Error())
	}
	log.INFO.Printf("split([\"foo\"]) = %v\n", tasks.HumanReadableResults(results))

	/*
	 * Now let's explore ways of sending multiple tasks
	 */

	// Now let's try a parallel execution
	initTasks()
	log.INFO.Println("Group of tasks (parallel execution):")

	group, err := tasks.NewGroup(&addTask0, &addTask1, &addTask2)
	if err != nil {
		return fmt.Errorf("Error creating group: %s", err.Error())
	}

	asyncResults, err := server.SendGroupWithContext(ctx, group, 10)
	if err != nil {
		return fmt.Errorf("Could not send group: %s", err.Error())
	}

	for _, asyncResult := range asyncResults {
		results, err = asyncResult.Get(time.Duration(time.Millisecond * 5))
		if err != nil {
			return fmt.Errorf("Getting task result failed with error: %s", err.Error())
		}
		log.INFO.Printf(
			"%v + %v = %v\n",
			asyncResult.Signature.Args[0].Value,
			asyncResult.Signature.Args[1].Value,
			tasks.HumanReadableResults(results),
		)
	}

	// Now let's try a group with a chord
	initTasks()
	log.INFO.Println("Group of tasks with a callback (chord):")

	group, err = tasks.NewGroup(&addTask0, &addTask1, &addTask2)
	if err != nil {
		return fmt.Errorf("Error creating group: %s", err.Error())
	}

	chord, err := tasks.NewChord(group, &multiplyTask1)
	if err != nil {
		return fmt.Errorf("Error creating chord: %s", err)
	}

	chordAsyncResult, err := server.SendChordWithContext(ctx, chord, 10)
	if err != nil {
		return fmt.Errorf("Could not send chord: %s", err.Error())
	}

	results, err = chordAsyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		return fmt.Errorf("Getting chord result failed with error: %s", err.Error())
	}
	log.INFO.Printf("(1 + 1) * (2 + 2) * (5 + 6) = %v\n", tasks.HumanReadableResults(results))

	// Now let's try chaining task results
	initTasks()
	log.INFO.Println("Chain of tasks:")

	chain, err := tasks.NewChain(&addTask0, &addTask1, &addTask2, &multiplyTask0)
	if err != nil {
		return fmt.Errorf("Error creating chain: %s", err)
	}

	chainAsyncResult, err := server.SendChainWithContext(ctx, chain)
	if err != nil {
		return fmt.Errorf("Could not send chain: %s", err.Error())
	}

	results, err = chainAsyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		return fmt.Errorf("Getting chain result failed with error: %s", err.Error())
	}
	log.INFO.Printf("(((1 + 1) + (2 + 2)) + (5 + 6)) * 4 = %v\n", tasks.HumanReadableResults(results))

	// Let's try a task which throws panic to make sure stack trace is not lost
	initTasks()
	asyncResult, err = server.SendTaskWithContext(ctx, &panicTask)
	if err != nil {
		return fmt.Errorf("Could not send task: %s", err.Error())
	}

	_, err = asyncResult.Get(time.Duration(time.Millisecond * 5))
	if err == nil {
		return errors.New("Error should not be nil if task panicked")
	}
	log.INFO.Printf("Task panicked and returned error = %v\n", err.Error())

	// Let's try a long running task
	initTasks()
	asyncResult, err = server.SendTaskWithContext(ctx, &longRunningTask)
	if err != nil {
		return fmt.Errorf("Could not send task: %s", err.Error())
	}

	results, err = asyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		return fmt.Errorf("Getting long running task result failed with error: %s", err.Error())
	}
	log.INFO.Printf("Long running task returned = %v\n", tasks.HumanReadableResults(results))

	return nil
}


================================================
FILE: example/redis/main.go
================================================
package main

import (
	"context"
	"errors"
	"fmt"
	"os"
	"time"

	"github.com/google/uuid"
	"github.com/urfave/cli"

	"github.com/RichardKnop/machinery/v1"
	"github.com/RichardKnop/machinery/v1/config"
	"github.com/RichardKnop/machinery/v1/log"
	"github.com/RichardKnop/machinery/v1/tasks"

	exampletasks "github.com/RichardKnop/machinery/example/tasks"
	tracers "github.com/RichardKnop/machinery/example/tracers"
	opentracing "github.com/opentracing/opentracing-go"
	opentracing_log "github.com/opentracing/opentracing-go/log"
)

var (
	app *cli.App
)

func init() {
	// Initialise a CLI app
	app = cli.NewApp()
	app.Name = "machinery"
	app.Usage = "machinery worker and send example tasks with machinery send"
	app.Version = "0.0.0"
}

func main() {
	// Set the CLI app commands
	app.Commands = []cli.Command{
		{
			Name:  "worker",
			Usage: "launch machinery worker",
			Action: func(c *cli.Context) error {
				if err := worker(); err != nil {
					return cli.NewExitError(err.Error(), 1)
				}
				return nil
			},
		},
		{
			Name:  "send",
			Usage: "send example tasks ",
			Action: func(c *cli.Context) error {
				if err := send(); err != nil {
					return cli.NewExitError(err.Error(), 1)
				}
				return nil
			},
		},
	}

	// Run the CLI app
	app.Run(os.Args)
}

func startServer() (*machinery.Server, error) {
	cnf := &config.Config{
		DefaultQueue:    "machinery_tasks",
		ResultsExpireIn: 3600,
		Broker:          "redis://localhost:6379",
		ResultBackend:   "redis://localhost:6379",
		Redis: &config.RedisConfig{
			MaxIdle:                3,
			IdleTimeout:            240,
			ReadTimeout:            15,
			WriteTimeout:           15,
			ConnectTimeout:         15,
			NormalTasksPollPeriod:  1000,
			DelayedTasksPollPeriod: 500,
		},
	}

	server, err := machinery.NewServer(cnf)
	if err != nil {
		return nil, err
	}

	// Register tasks
	tasks := map[string]interface{}{
		"add":               exampletasks.Add,
		"multiply":          exampletasks.Multiply,
		"sum_ints":          exampletasks.SumInts,
		"sum_floats":        exampletasks.SumFloats,
		"concat":            exampletasks.Concat,
		"split":             exampletasks.Split,
		"panic_task":        exampletasks.PanicTask,
		"long_running_task": exampletasks.LongRunningTask,
	}

	return server, server.RegisterTasks(tasks)
}

func worker() error {
	consumerTag := "machinery_worker"

	cleanup, err := tracers.SetupTracer(consumerTag)
	if err != nil {
		log.FATAL.Fatalln("Unable to instantiate a tracer:", err)
	}
	defer cleanup()

	server, err := startServer()
	if err != nil {
		return err
	}

	// The second argument is a consumer tag
	// Ideally, each worker should have a unique tag (worker1, worker2 etc)
	worker := server.NewWorker(consumerTag, 0)

	// Here we inject some custom code for error handling,
	// start and end of task hooks, useful for metrics for example.
	errorhandler := func(err error) {
		log.ERROR.Println("I am an error handler:", err)
	}

	pretaskhandler := func(signature *tasks.Signature) {
		log.INFO.Println("I am a start of task handler for:", signature.Name)
	}

	posttaskhandler := func(signature *tasks.Signature) {
		log.INFO.Println("I am an end of task handler for:", signature.Name)
	}

	worker.SetPostTaskHandler(posttaskhandler)
	worker.SetErrorHandler(errorhandler)
	worker.SetPreTaskHandler(pretaskhandler)

	return worker.Launch()
}

func send() error {
	cleanup, err := tracers.SetupTracer("sender")
	if err != nil {
		log.FATAL.Fatalln("Unable to instantiate a tracer:", err)
	}
	defer cleanup()

	server, err := startServer()
	if err != nil {
		return err
	}

	var (
		addTask0, addTask1, addTask2                      tasks.Signature
		multiplyTask0, multiplyTask1                      tasks.Signature
		sumIntsTask, sumFloatsTask, concatTask, splitTask tasks.Signature
		panicTask                                         tasks.Signature
		longRunningTask                                   tasks.Signature
	)

	var initTasks = func() {
		addTask0 = tasks.Signature{
			Name: "add",
			Args: []tasks.Arg{
				{
					Type:  "int64",
					Value: 1,
				},
				{
					Type:  "int64",
					Value: 1,
				},
			},
		}

		addTask1 = tasks.Signature{
			Name: "add",
			Args: []tasks.Arg{
				{
					Type:  "int64",
					Value: 2,
				},
				{
					Type:  "int64",
					Value: 2,
				},
			},
		}

		addTask2 = tasks.Signature{
			Name: "add",
			Args: []tasks.Arg{
				{
					Type:  "int64",
					Value: 5,
				},
				{
					Type:  "int64",
					Value: 6,
				},
			},
		}

		multiplyTask0 = tasks.Signature{
			Name: "multiply",
			Args: []tasks.Arg{
				{
					Type:  "int64",
					Value: 4,
				},
			},
		}

		multiplyTask1 = tasks.Signature{
			Name: "multiply",
		}

		sumIntsTask = tasks.Signature{
			Name: "sum_ints",
			Args: []tasks.Arg{
				{
					Type:  "[]int64",
					Value: []int64{1, 2},
				},
			},
		}

		sumFloatsTask = tasks.Signature{
			Name: "sum_floats",
			Args: []tasks.Arg{
				{
					Type:  "[]float64",
					Value: []float64{1.5, 2.7},
				},
			},
		}

		concatTask = tasks.Signature{
			Name: "concat",
			Args: []tasks.Arg{
				{
					Type:  "[]string",
					Value: []string{"foo", "bar"},
				},
			},
		}

		splitTask = tasks.Signature{
			Name: "split",
			Args: []tasks.Arg{
				{
					Type:  "string",
					Value: "foo",
				},
			},
		}

		panicTask = tasks.Signature{
			Name: "panic_task",
		}

		longRunningTask = tasks.Signature{
			Name: "long_running_task",
		}
	}

	/*
	 * Lets start a span representing this run of the `send` command and
	 * set a batch id as baggage so it can travel all the way into
	 * the worker functions.
	 */
	span, ctx := opentracing.StartSpanFromContext(context.Background(), "send")
	defer span.Finish()

	batchID := uuid.New().String()
	span.SetBaggageItem("batch.id", batchID)
	span.LogFields(opentracing_log.String("batch.id", batchID))

	log.INFO.Println("Starting batch:", batchID)
	/*
	 * First, let's try sending a single task
	 */
	initTasks()

	log.INFO.Println("Single task:")

	asyncResult, err := server.SendTaskWithContext(ctx, &addTask0)
	if err != nil {
		return fmt.Errorf("Could not send task: %s", err.Error())
	}

	results, err := asyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		return fmt.Errorf("Getting task result failed with error: %s", err.Error())
	}
	log.INFO.Printf("1 + 1 = %v\n", tasks.HumanReadableResults(results))

	/*
	 * Try couple of tasks with a slice argument and slice return value
	 */
	asyncResult, err = server.SendTaskWithContext(ctx, &sumIntsTask)
	if err != nil {
		return fmt.Errorf("Could not send task: %s", err.Error())
	}

	results, err = asyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		return fmt.Errorf("Getting task result failed with error: %s", err.Error())
	}
	log.INFO.Printf("sum([1, 2]) = %v\n", tasks.HumanReadableResults(results))

	asyncResult, err = server.SendTaskWithContext(ctx, &sumFloatsTask)
	if err != nil {
		return fmt.Errorf("Could not send task: %s", err.Error())
	}

	results, err = asyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		return fmt.Errorf("Getting task result failed with error: %s", err.Error())
	}
	log.INFO.Printf("sum([1.5, 2.7]) = %v\n", tasks.HumanReadableResults(results))

	asyncResult, err = server.SendTaskWithContext(ctx, &concatTask)
	if err != nil {
		return fmt.Errorf("Could not send task: %s", err.Error())
	}

	results, err = asyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		return fmt.Errorf("Getting task result failed with error: %s", err.Error())
	}
	log.INFO.Printf("concat([\"foo\", \"bar\"]) = %v\n", tasks.HumanReadableResults(results))

	asyncResult, err = server.SendTaskWithContext(ctx, &splitTask)
	if err != nil {
		return fmt.Errorf("Could not send task: %s", err.Error())
	}

	results, err = asyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		return fmt.Errorf("Getting task result failed with error: %s", err.Error())
	}
	log.INFO.Printf("split([\"foo\"]) = %v\n", tasks.HumanReadableResults(results))

	/*
	 * Now let's explore ways of sending multiple tasks
	 */

	// Now let's try a parallel execution
	initTasks()
	log.INFO.Println("Group of tasks (parallel execution):")

	group, err := tasks.NewGroup(&addTask0, &addTask1, &addTask2)
	if err != nil {
		return fmt.Errorf("Error creating group: %s", err.Error())
	}

	asyncResults, err := server.SendGroupWithContext(ctx, group, 10)
	if err != nil {
		return fmt.Errorf("Could not send group: %s", err.Error())
	}

	for _, asyncResult := range asyncResults {
		results, err = asyncResult.Get(time.Duration(time.Millisecond * 5))
		if err != nil {
			return fmt.Errorf("Getting task result failed with error: %s", err.Error())
		}
		log.INFO.Printf(
			"%v + %v = %v\n",
			asyncResult.Signature.Args[0].Value,
			asyncResult.Signature.Args[1].Value,
			tasks.HumanReadableResults(results),
		)
	}

	// Now let's try a group with a chord
	initTasks()
	log.INFO.Println("Group of tasks with a callback (chord):")

	group, err = tasks.NewGroup(&addTask0, &addTask1, &addTask2)
	if err != nil {
		return fmt.Errorf("Error creating group: %s", err.Error())
	}

	chord, err := tasks.NewChord(group, &multiplyTask1)
	if err != nil {
		return fmt.Errorf("Error creating chord: %s", err)
	}

	chordAsyncResult, err := server.SendChordWithContext(ctx, chord, 10)
	if err != nil {
		return fmt.Errorf("Could not send chord: %s", err.Error())
	}

	results, err = chordAsyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		return fmt.Errorf("Getting chord result failed with error: %s", err.Error())
	}
	log.INFO.Printf("(1 + 1) * (2 + 2) * (5 + 6) = %v\n", tasks.HumanReadableResults(results))

	// Now let's try chaining task results
	initTasks()
	log.INFO.Println("Chain of tasks:")

	chain, err := tasks.NewChain(&addTask0, &addTask1, &addTask2, &multiplyTask0)
	if err != nil {
		return fmt.Errorf("Error creating chain: %s", err)
	}

	chainAsyncResult, err := server.SendChainWithContext(ctx, chain)
	if err != nil {
		return fmt.Errorf("Could not send chain: %s", err.Error())
	}

	results, err = chainAsyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		return fmt.Errorf("Getting chain result failed with error: %s", err.Error())
	}
	log.INFO.Printf("(((1 + 1) + (2 + 2)) + (5 + 6)) * 4 = %v\n", tasks.HumanReadableResults(results))

	// Let's try a task which throws panic to make sure stack trace is not lost
	initTasks()
	asyncResult, err = server.SendTaskWithContext(ctx, &panicTask)
	if err != nil {
		return fmt.Errorf("Could not send task: %s", err.Error())
	}

	_, err = asyncResult.Get(time.Duration(time.Millisecond * 5))
	if err == nil {
		return errors.New("Error should not be nil if task panicked")
	}
	log.INFO.Printf("Task panicked and returned error = %v\n", err.Error())

	// Let's try a long running task
	initTasks()
	asyncResult, err = server.SendTaskWithContext(ctx, &longRunningTask)
	if err != nil {
		return fmt.Errorf("Could not send task: %s", err.Error())
	}

	results, err = asyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		return fmt.Errorf("Getting long running task result failed with error: %s", err.Error())
	}
	log.INFO.Printf("Long running task returned = %v\n", tasks.HumanReadableResults(results))

	return nil
}


================================================
FILE: example/tasks/tasks.go
================================================
package exampletasks

import (
	"errors"
	"strings"
	"time"

	"github.com/RichardKnop/machinery/v1/log"
)

// Add ...
func Add(args ...int64) (int64, error) {
	sum := int64(0)
	for _, arg := range args {
		sum += arg
	}
	return sum, nil
}

// Multiply ...
func Multiply(args ...int64) (int64, error) {
	sum := int64(1)
	for _, arg := range args {
		sum *= arg
	}
	return sum, nil
}

// SumInts ...
func SumInts(numbers []int64) (int64, error) {
	var sum int64
	for _, num := range numbers {
		sum += num
	}
	return sum, nil
}

// SumFloats ...
func SumFloats(numbers []float64) (float64, error) {
	var sum float64
	for _, num := range numbers {
		sum += num
	}
	return sum, nil
}

// Concat ...
func Concat(strs []string) (string, error) {
	var res string
	for _, s := range strs {
		res += s
	}
	return res, nil
}

// Split ...
func Split(str string) ([]string, error) {
	return strings.Split(str, ""), nil
}

// PanicTask ...
func PanicTask() (string, error) {
	panic(errors.New("oops"))
}

// LongRunningTask ...
func LongRunningTask() error {
	log.INFO.Print("Long running task started")
	for i := 0; i < 10; i++ {
		log.INFO.Print(10 - i)
		time.Sleep(1 * time.Second)
	}
	log.INFO.Print("Long running task finished")
	return nil
}


================================================
FILE: example/tracers/jaeger.go
================================================
package tracers

// Uncomment the import statement for the jaeger tracer.
// make sure you run dep ensure to pull in the jaeger client
//
// import (
// 	jaeger "github.com/uber/jaeger-client-go"
// 	jaegercfg "github.com/uber/jaeger-client-go/config"
// )

// SetupTracer is the place where you'd setup your specific tracer.
// The jaeger tracer is given as an example.
// To capture the jaeger traces you should run the jaeger backend.
// This can be done using the following docker command:
//
// `docker run -ti --rm -p6831:6831/udp -p16686:16686 jaegertracing/all-in-one:latest`
//
// The collector will be listening on localhost:6831
// and the query UI is reachable on localhost:16686.
func SetupTracer(serviceName string) (func(), error) {

	// Jaeger setup code
	//
	// config := jaegercfg.Configuration{
	// 	Sampler: &jaegercfg.SamplerConfig{
	// 		Type:  jaeger.SamplerTypeConst,
	// 		Param: 1,
	// 	},
	// }

	// closer, err := config.InitGlobalTracer(serviceName)
	// if err != nil {
	// 	return nil, err
	// }

	cleanupFunc := func() {
		// closer.Close()
	}

	return cleanupFunc, nil
}


================================================
FILE: go.mod
================================================
module github.com/RichardKnop/machinery

go 1.22

toolchain go1.24.1

require (
	cloud.google.com/go/pubsub v1.10.0
	github.com/RichardKnop/logging v0.0.0-20190827224416-1a693bdd4fae
	github.com/aws/aws-sdk-go v1.55.6
	github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b
	github.com/go-redsync/redsync/v4 v4.8.1
	github.com/gomodule/redigo v1.9.2
	github.com/google/uuid v1.2.0
	github.com/kelseyhightower/envconfig v1.4.0
	github.com/opentracing/opentracing-go v1.2.0
	github.com/pkg/errors v0.9.1
	github.com/rabbitmq/amqp091-go v1.9.0
	github.com/redis/go-redis/v9 v9.0.5
	github.com/robfig/cron/v3 v3.0.1
	github.com/stretchr/testify v1.8.4
	github.com/urfave/cli v1.22.5
	go.mongodb.org/mongo-driver v1.17.0
	gopkg.in/yaml.v2 v2.4.0
)

require (
	cloud.google.com/go v0.76.0 // indirect
	github.com/cespare/xxhash/v2 v2.2.0 // indirect
	github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
	github.com/davecgh/go-spew v1.1.1 // indirect
	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
	github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
	github.com/golang/protobuf v1.5.2 // indirect
	github.com/golang/snappy v0.0.4 // indirect
	github.com/google/go-cmp v0.6.0 // indirect
	github.com/googleapis/gax-go/v2 v2.0.5 // indirect
	github.com/hashicorp/errwrap v1.1.0 // indirect
	github.com/hashicorp/go-multierror v1.1.1 // indirect
	github.com/jmespath/go-jmespath v0.4.0 // indirect
	github.com/jstemmer/go-junit-report v0.9.1 // indirect
	github.com/klauspost/compress v1.13.6 // indirect
	github.com/montanaflynn/stats v0.7.1 // indirect
	github.com/pmezard/go-difflib v1.0.0 // indirect
	github.com/russross/blackfriday/v2 v2.1.0 // indirect
	github.com/xdg-go/pbkdf2 v1.0.0 // indirect
	github.com/xdg-go/scram v1.1.2 // indirect
	github.com/xdg-go/stringprep v1.0.4 // indirect
	github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
	go.opencensus.io v0.22.6 // indirect
	golang.org/x/crypto v0.26.0 // indirect
	golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 // indirect
	golang.org/x/mod v0.17.0 // indirect
	golang.org/x/net v0.25.0 // indirect
	golang.org/x/oauth2 v0.0.0-20210201163806-010130855d6c // indirect
	golang.org/x/sync v0.8.0 // indirect
	golang.org/x/sys v0.23.0 // indirect
	golang.org/x/text v0.17.0 // indirect
	golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
	google.golang.org/api v0.39.0 // indirect
	google.golang.org/appengine v1.6.7 // indirect
	google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea // indirect
	google.golang.org/grpc v1.35.0 // indirect
	google.golang.org/protobuf v1.26.0 // indirect
	gopkg.in/yaml.v3 v3.0.1 // indirect
)

replace git.apache.org/thrift.git => github.com/apache/thrift v0.0.0-20180902110319-2566ecd5d999


================================================
FILE: go.sum
================================================
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
cloud.google.com/go v0.76.0 h1:Ckw+E/QYZgd/5bpI4wz4h6f+jmpvh9S9uSrKNnbicJI=
cloud.google.com/go v0.76.0/go.mod h1:r9EvIAvLrunusnetGdQ50M/gKui1x3zdGW/VELGkdpw=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/pubsub v1.10.0 h1:JK22g5uNpscGPthjJE/D0siWtA6UlU4Cb6pLcyJkzyQ=
cloud.google.com/go/pubsub v1.10.0/go.mod h1:eNpTrkOy7dCpkNyaSNetMa6udbgecJMd0ZsTJS/cuNo=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/RichardKnop/logging v0.0.0-20190827224416-1a693bdd4fae h1:DcFpTQBYQ9Ct2d6sC7ol0/ynxc2pO1cpGUM+f4t5adg=
github.com/RichardKnop/logging v0.0.0-20190827224416-1a693bdd4fae/go.mod h1:rJJ84PyA/Wlmw1hO+xTzV2wsSUon6J5ktg0g8BF2PuU=
github.com/aws/aws-sdk-go v1.55.6 h1:cSg4pvZ3m8dgYcgqB97MrcdjUmZ1BeMYKUxMMB89IPk=
github.com/aws/aws-sdk-go v1.55.6/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b h1:L/QXpzIa3pOvUGt1D1lA5KjYhPBAN/3iWdP7xeFS9F0=
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
github.com/bsm/ginkgo/v2 v2.5.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w=
github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao=
github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w=
github.com/bsm/gomega v1.20.0/go.mod h1:JifAceMQ4crZIWYUKrlGcmbN3bqHogVTADMD2ATsbwk=
github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y=
github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-redis/redis/v7 v7.4.0 h1:7obg6wUoj05T0EpY0o8B59S9w5yeMWql7sw2kwNW1x4=
github.com/go-redis/redis/v7 v7.4.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg=
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
github.com/go-redsync/redsync/v4 v4.8.1 h1:rq2RvdTI0obznMdxKUWGdmmulo7lS9yCzb8fgDKOlbM=
github.com/go-redsync/redsync/v4 v4.8.1/go.mod h1:LmUAsQuQxhzZAoGY7JS6+dNhNmZyonMZiiEDY9plotM=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
github.com/gomodule/redigo v1.9.2 h1:HrutZBLhSIU8abiSfW8pj8mPhOyMYjZT/wcA4/L9L9s=
github.com/gomodule/redigo v1.9.2/go.mod h1:KsU3hiK/Ay8U42qpaJk+kuNa3C+spxapWpM+ywhcgtw=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rabbitmq/amqp091-go v1.9.0 h1:qrQtyzB4H8BQgEuJwhmVQqVHB9O4+MNDJCCAcpc3Aoo=
github.com/rabbitmq/amqp091-go v1.9.0/go.mod h1:+jPrT9iY2eLjRaMSRHUhc3z14E/l85kv/f+6luSD3pc=
github.com/redis/go-redis/v9 v9.0.2/go.mod h1:/xDTe9EF1LM61hek62Poq2nzQSGj0xSrEtEHbBQevps=
github.com/redis/go-redis/v9 v9.0.5 h1:CuQcn5HIEeK7BgElubPP8CGtE0KakrnbBSTLjathl5o=
github.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203 h1:QVqDTf3h2WHt08YuiTGPZLls0Wq99X9bWd0Q5ZSBesM=
github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203/go.mod h1:oqN97ltKNihBbwlX8dLpwxCl3+HnXKV/R0e+sRLd9C8=
github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU=
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.mongodb.org/mongo-driver v1.17.0 h1:Hp4q2MCjvY19ViwimTs00wHi7G4yzxh4/2+nTx8r40k=
go.mongodb.org/mongo-driver v1.17.0/go.mod h1:wwWm/+BuOddhcq3n68LKRmgk2wXzmF6s0SFOa0GINL4=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.22.6 h1:BdkrbWrzDlV9dnbzoP7sfN+dHheJ4J9JOaYxcUDL+ok=
go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI=
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210113205817-d3ed898aa8a3/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210201163806-010130855d6c h1:HiAZXo96zOhVhtFHchj/ojzoxCFiPrp9/j0GtS38V3g=
golang.org/x/oauth2 v0.0.0-20210201163806-010130855d6c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
google.golang.org/api v0.38.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
google.golang.org/api v0.39.0 h1:zHCTXf0NeDdKTgcSQpT+ZflWAqHsEp1GmdpxW09f3YM=
google.golang.org/api v0.39.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210202153253-cf70463f6119/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea h1:N98SvVh7Hdle2lgUVFuIkf0B3u29CUakMUQa7Hwz8Wc=
google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.35.0 h1:TwIQcH3es+MojMVojxxfQ3l3OF2KzlRxML2xZq0kRo8=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=


================================================
FILE: instruction-notes/dynamodb.md
================================================
# Using DynamoDB as a result backend
## What is DynamoDB
Amazon DynamoDB is a fast and flexible NoSQL database service.
Check this [official website](https://aws.amazon.com/dynamodb/
) for details.

## How to use DynamoDB as a result backend in Machinery
### Create two tables first
There will be two tables required now(2018-01-12):
* group_metas: A table which saves group tasks' meta data. The primary key for this table is ```GroupUUID```, and it should be set properly when creating this table.
* task_states: A table which saves every task's states. The primary key for this table is ```TaskUUID```, and it should be set properly when creating this table.


### Add DynamoDB config to the config file
#### example config
```yaml
broker: 'https://sqs.us-west-1.amazonaws.com/123456789012'
default_queue: machinery-queue
result_backend: 'https://dynamodb.us-west-1.amazonaws.com/123456789012'
results_expire_in: 3600
dynamodb:
  task_states_table: 'task_states'
  group_metas_table: 'group_metas'
```
Then DynamoDB will be used as a result backend.

================================================
FILE: integration-tests/amqp_amqp_test.go
================================================
package integration_test

import (
	"os"
	"testing"

	"github.com/RichardKnop/machinery/v1"
	"github.com/RichardKnop/machinery/v1/config"
)

func TestAmqpAmqp(t *testing.T) {
	amqpURL := os.Getenv("AMQP_URL")
	if amqpURL == "" {
		t.Skip("AMQP_URL is not defined")
	}

	finalAmqpURL := amqpURL
	var finalSeparator string

	amqpURLs := os.Getenv("AMQP_URLS")
	if amqpURLs != "" {
		separator := os.Getenv("AMQP_URLS_SEPARATOR")
		if separator == "" {
			return
		}
		finalSeparator = separator
		finalAmqpURL = amqpURLs
	}

	// AMQP broker, AMQP result backend
	server := testSetup(&config.Config{
		Broker:                  finalAmqpURL,
		MultipleBrokerSeparator: finalSeparator,
		DefaultQueue:            "test_queue",
		ResultBackend:           amqpURL,
		Lock:                    "eager",
		AMQP: &config.AMQPConfig{
			Exchange:      "test_exchange",
			ExchangeType:  "direct",
			BindingKey:    "test_task",
			PrefetchCount: 1,
		},
	})

	worker := server.(*machinery.Server).NewWorker("test_worker", 0)
	defer worker.Quit()
	go worker.Launch()
	testAll(server, t)
}


================================================
FILE: integration-tests/amqp_get_pending_tasks_test.go
================================================
package integration_test

import (
	"fmt"
	"os"
	"testing"
	"time"

	"github.com/RichardKnop/machinery/v1"
	"github.com/RichardKnop/machinery/v1/backends/result"
	"github.com/RichardKnop/machinery/v1/config"
	"github.com/RichardKnop/machinery/v1/tasks"
)

func TestAmqpGetPendingTasks(t *testing.T) {
	amqpURL := os.Getenv("AMQP_URL")
	if amqpURL == "" {
		t.Skip("AMQP_URL is not defined")
	}

	finalAmqpURL := amqpURL
	var finalSeparator string

	amqpURLs := os.Getenv("AMQP_URLS")
	if amqpURLs != "" {
		separator := os.Getenv("AMQP_URLS_SEPARATOR")
		if separator == "" {
			return
		}
		finalSeparator = separator
		finalAmqpURL = amqpURLs
	}

	redisURL := os.Getenv("REDIS_URL")
	if redisURL == "" {
		t.Skip("REDIS_URL is not defined")
	}

	// AMQP broker, AMQP result backend
	server := testSetup(&config.Config{
		Broker:                  finalAmqpURL,
		MultipleBrokerSeparator: finalSeparator,
		DefaultQueue:            "test_queue",
		ResultBackend:           amqpURL,
		Lock:                    fmt.Sprintf("redis://%v", redisURL),
		AMQP: &config.AMQPConfig{
			Exchange:      "test_exchange",
			ExchangeType:  "direct",
			BindingKey:    "test_task",
			PrefetchCount: 1,
		},
	})

	var results []*result.AsyncResult
	signatures := []*tasks.Signature{newAddTask(1, 2), newAddTask(3, 5), newAddTask(6, 7)}
	for _, s := range signatures {
		ar, err := server.SendTask(s)
		if err != nil {
			t.Error(err)
		}
		results = append(results, ar)
	}
	pendingMessages, err := server.GetBroker().GetPendingTasks(server.GetConfig().DefaultQueue)
	if err != nil {
		t.Error(err)
	}

	if len(pendingMessages) != len(signatures) {
		t.Errorf(
			"%d pending messages, should be %d",
			len(pendingMessages),
			len(signatures),
		)
	}
	for i := 0; i < len(signatures); i++ {
		compareSigs(t, signatures[i], pendingMessages[i])
	}

	worker := server.(*machinery.Server).NewWorker("test_worker", 0)
	go worker.Launch()
	defer worker.Quit()
	for _, r := range results {
		r.Get(time.Duration(time.Millisecond * 5))
	}

	pendingMessages, err = server.GetBroker().GetPendingTasks(server.GetConfig().DefaultQueue)
	if err != nil {
		t.Error(err)
	}

	if len(pendingMessages) != 0 {
		t.Errorf(
			"%d pending messages, should be 0",
			len(pendingMessages),
		)
	}
}

func compareSigs(t *testing.T, a *tasks.Signature, b *tasks.Signature) {
	if a.UUID != b.UUID {
		t.Errorf("UUID mismatch, %v != %v", a.UUID, b.UUID)
	}
	if a.Name != b.Name {
		t.Errorf("UUID mismatch, %v != %v", a.Name, b.Name)
	}
	if len(a.Args) != len(b.Args) {
		t.Errorf("Arg length mismatch, %v != %v", len(a.Args), len(b.Args))
	}
}


================================================
FILE: integration-tests/amqp_memcache_test.go
================================================
package integration_test

import (
	"fmt"
	"os"
	"testing"

	"github.com/RichardKnop/machinery/v1"
	"github.com/RichardKnop/machinery/v1/config"
)

func TestAmqpMemcache(t *testing.T) {
	amqpURL := os.Getenv("AMQP_URL")
	memcacheURL := os.Getenv("MEMCACHE_URL")
	if amqpURL == "" {
		t.Skip("AMQP_URL is not defined")
	}
	if memcacheURL == "" {
		t.Skip("MEMCACHE_URL is not defined")
	}

	redisURL := os.Getenv("REDIS_URL")
	if redisURL == "" {
		t.Skip("REDIS_URL is not defined")
	}

	// AMQP broker, Memcache result backend
	server := testSetup(&config.Config{
		Broker:        amqpURL,
		DefaultQueue:  "test_queue",
		ResultBackend: fmt.Sprintf("memcache://%v", memcacheURL),
		Lock:          fmt.Sprintf("redis://%v", redisURL),
		AMQP: &config.AMQPConfig{
			Exchange:      "test_exchange",
			ExchangeType:  "direct",
			BindingKey:    "test_task",
			PrefetchCount: 1,
		},
	})

	worker := server.(*machinery.Server).NewWorker("test_worker", 0)
	defer worker.Quit()
	go worker.Launch()
	testAll(server, t)
}


================================================
FILE: integration-tests/amqp_mongodb_test.go
================================================
package integration_test

import (
	"fmt"
	"os"
	"testing"

	"github.com/RichardKnop/machinery/v1"
	"github.com/RichardKnop/machinery/v1/config"
)

func TestAmqpMongodb(t *testing.T) {
	amqpURL := os.Getenv("AMQP_URL")
	mongodbURL := os.Getenv("MONGODB_URL")
	if amqpURL == "" {
		t.Skip("AMQP_URL is not defined")
	}
	if mongodbURL == "" {
		t.Skip("MONGODB_URL is not defined")
	}

	// AMQP broker, MongoDB result backend
	server := testSetup(&config.Config{
		Broker:          amqpURL,
		DefaultQueue:    "test_queue",
		ResultsExpireIn: 30,
		ResultBackend:   fmt.Sprintf("mongodb://%v", mongodbURL),
		Lock:            "eager",
		AMQP: &config.AMQPConfig{
			Exchange:      "test_exchange",
			ExchangeType:  "direct",
			BindingKey:    "test_task",
			PrefetchCount: 1,
		},
	})

	worker := server.(*machinery.Server).NewWorker("test_worker", 0)
	defer worker.Quit()
	go worker.Launch()
	testAll(server, t)
}


================================================
FILE: integration-tests/amqp_redis_test.go
================================================
package integration_test

import (
	"fmt"
	"os"
	"testing"

	"github.com/RichardKnop/machinery/v1"
	"github.com/RichardKnop/machinery/v1/config"
)

func TestAmqpRedis(t *testing.T) {
	amqpURL := os.Getenv("AMQP_URL")
	redisURL := os.Getenv("REDIS_URL")
	if amqpURL == "" {
		t.Skip("AMQP_URL is not defined")
	}
	if redisURL == "" {
		t.Skip("REDIS_URL is not defined")
	}

	// AMQP broker, Redis result backend
	server := testSetup(&config.Config{
		Broker:        amqpURL,
		DefaultQueue:  "test_queue",
		ResultBackend: fmt.Sprintf("redis://%v", redisURL),
		Lock:          "eager",
		AMQP: &config.AMQPConfig{
			Exchange:      "test_exchange",
			ExchangeType:  "direct",
			BindingKey:    "test_task",
			PrefetchCount: 1,
		},
	})

	worker := server.(*machinery.Server).NewWorker("test_worker", 0)
	defer worker.Quit()
	go worker.Launch()
	testAll(server, t)
}


================================================
FILE: integration-tests/eager_eager_test.go
================================================
package integration_test

import (
	"reflect"
	"testing"
	"time"

	"github.com/RichardKnop/machinery/v1"
	"github.com/RichardKnop/machinery/v1/config"
	"github.com/RichardKnop/machinery/v1/tasks"
	"github.com/stretchr/testify/suite"
)

type EagerIntegrationTestSuite struct {
	suite.Suite

	srv    *machinery.Server
	called float64
}

func TestEagerIntegrationTestSuite(t *testing.T) {
	suite.Run(t, &EagerIntegrationTestSuite{})
}

func (s *EagerIntegrationTestSuite) SetupSuite() {
	var err error

	// init server
	cnf := config.Config{
		Broker:        "eager",
		ResultBackend: "eager",
		Lock:          "eager",
	}
	s.srv, err = machinery.NewServer(&cnf)
	s.Nil(err)
	s.NotNil(s.srv)

	// register task
	s.called = 0
	s.srv.RegisterTask("float_called", func(i float64) (float64, error) {
		s.called = i
		return s.called, nil
	})

	s.srv.RegisterTask("float_result", func(i float64) (float64, error) {
		return i + 100.0, nil
	})

	s.srv.RegisterTask("int_result", func(i int64) (int64, error) {
		return i + 100, nil
	})
}

func (s *EagerIntegrationTestSuite) TestCalled() {
	_, err := s.srv.SendTask(&tasks.Signature{
		Name: "float_called",
		Args: []tasks.Arg{
			{
				Type:  "float64",
				Value: 100.0,
			},
		},
	})

	s.Nil(err)
	s.Equal(100.0, s.called)
}

func (s *EagerIntegrationTestSuite) TestSuccessResult() {
	// float64
	{
		asyncResult, err := s.srv.SendTask(&tasks.Signature{
			Name: "float_result",
			Args: []tasks.Arg{
				{
					Type:  "float64",
					Value: 100.0,
				},
			},
		})

		s.NotNil(asyncResult)
		s.Nil(err)

		s.True(asyncResult.GetState().IsCompleted())
		s.True(asyncResult.GetState().IsSuccess())

		results, err := asyncResult.Get(time.Duration(time.Millisecond * 5))
		if s.NoError(err) {
			if len(results) != 1 {
				s.T().Errorf("Number of results returned = %d. Wanted %d", len(results), 1)
			}

			s.Equal(reflect.Float64, results[0].Kind())
			if results[0].Kind() == reflect.Float64 {
				s.Equal(200.0, results[0].Float())
			}
		}
	}

	// int
	{
		asyncResult, err := s.srv.SendTask(&tasks.Signature{
			Name: "int_result",
			Args: []tasks.Arg{
				{
					Type:  "int64",
					Value: 100,
				},
			},
		})

		s.NotNil(asyncResult)
		s.Nil(err)

		s.True(asyncResult.GetState().IsCompleted())
		s.True(asyncResult.GetState().IsSuccess())

		results, err := asyncResult.Get(time.Duration(time.Millisecond * 5))
		if s.NoError(err) {
			if len(results) != 1 {
				s.T().Errorf("Number of results returned = %d. Wanted %d", len(results), 1)
			}

			s.Equal(reflect.Int64, results[0].Kind())
			if results[0].Kind() == reflect.Int64 {
				s.Equal(int64(200), results[0].Int())
			}
		}
	}
}


================================================
FILE: integration-tests/gcppubsub_redis_test.go
================================================
package integration_test

import (
	"context"
	"fmt"
	"os"
	"testing"
	"time"

	"cloud.google.com/go/pubsub"

	"github.com/RichardKnop/machinery/v1"
	"github.com/RichardKnop/machinery/v1/config"
)

func createGCPPubSubTopicAndSubscription(cli *pubsub.Client, topicName, subscriptionName string) {
	ctx := context.Background()

	var topic *pubsub.Topic

	topic = cli.Topic(topicName)
	topicExists, err := topic.Exists(ctx)
	if err != nil {
		panic(err)
	}

	if !topicExists {
		topic, err = cli.CreateTopic(ctx, topicName)
		if err != nil {
			panic(err)
		}
	}

	var sub *pubsub.Subscription

	sub = cli.Subscription(subscriptionName)
	subExists, err := sub.Exists(ctx)
	if err != nil {
		panic(err)
	}

	if !subExists {
		_, err = cli.CreateSubscription(ctx, subscriptionName, pubsub.SubscriptionConfig{
			Topic:       topic,
			AckDeadline: 10 * time.Second,
		})
		if err != nil {
			panic(err)
		}
	}
}

func TestGCPPubSubRedis(t *testing.T) {
	// start Cloud Pub/Sub emulator
	// $ LANG=C gcloud beta emulators pubsub start
	// $ eval $(LANG=C gcloud beta emulators pubsub env-init)

	pubsubURL := os.Getenv("GCPPUBSUB_URL")
	if pubsubURL == "" {
		t.Skip("GCPPUBSUB_URL is not defined")
	}

	topicName := os.Getenv("GCPPUBSUB_TOPIC")
	if topicName == "" {
		t.Skip("GCPPUBSUB_TOPIC is not defined")
	}

	_, subscriptionName, err := machinery.ParseGCPPubSubURL(pubsubURL)
	if err != nil {
		t.Fatal(err)
	}

	redisURL := os.Getenv("REDIS_URL")
	if redisURL == "" {
		t.Skip("REDIS_URL is not defined")
	}

	pubsubClient, err := pubsub.NewClient(context.Background(), "")
	if err != nil {
		t.Fatal(err)
	}

	// Create Cloud Pub/Sub Topic and Subscription
	createGCPPubSubTopicAndSubscription(pubsubClient, topicName, subscriptionName)

	// Redis broker, Redis result backend
	server := testSetup(&config.Config{
		Broker:        pubsubURL,
		DefaultQueue:  topicName,
		ResultBackend: fmt.Sprintf("redis://%v", redisURL),
		Lock:          fmt.Sprintf("redis://%v", redisURL),
		GCPPubSub: &config.GCPPubSubConfig{
			Client: pubsubClient,
		},
	})

	worker := server.(*machinery.Server).NewWorker("test_worker", 0)
	defer worker.Quit()
	go worker.Launch()
	testAll(server, t)
}


================================================
FILE: integration-tests/redis_get_pending_tasks_test.go
================================================
package integration_test

import (
	"fmt"
	"os"
	"testing"

	"github.com/RichardKnop/machinery/v1/config"
)

func TestRedisGetPendingTasks(t *testing.T) {
	redisURL := os.Getenv("REDIS_URL")
	if redisURL == "" {
		t.Skip("REDIS_URL is not defined")
	}

	// Redis broker, Redis result backend
	server := testSetup(&config.Config{
		Broker:        fmt.Sprintf("redis://%v", redisURL),
		DefaultQueue:  "test_queue",
		ResultBackend: fmt.Sprintf("redis://%v", redisURL),
		Lock:          fmt.Sprintf("redis://%v", redisURL),
	})
	pendingMessages, err := server.GetBroker().GetPendingTasks(server.GetConfig().DefaultQueue)
	if err != nil {
		t.Error(err)
	}
	if len(pendingMessages) != 0 {
		t.Errorf(
			"%d pending messages, should be %d",
			len(pendingMessages),
			0,
		)
	}
}


================================================
FILE: integration-tests/redis_memcache_test.go
================================================
package integration_test

import (
	"fmt"
	"os"
	"testing"

	"github.com/RichardKnop/machinery/v1"
	"github.com/RichardKnop/machinery/v1/config"
)

func TestRedisMemcache(t *testing.T) {
	redisURL := os.Getenv("REDIS_URL")
	memcacheURL := os.Getenv("MEMCACHE_URL")
	if redisURL == "" {
		t.Skip("REDIS_URL is not defined")
	}
	if memcacheURL == "" {
		t.Skip("MEMCACHE_URL is not defined")
	}

	// Redis broker, Redis result backend
	server := testSetup(&config.Config{
		Broker:        fmt.Sprintf("redis://%v", redisURL),
		DefaultQueue:  "test_queue",
		ResultBackend: fmt.Sprintf("memcache://%v", memcacheURL),
		Lock:          fmt.Sprintf("redis://%v", redisURL),
	})

	worker := server.(*machinery.Server).NewWorker("test_worker", 0)
	defer worker.Quit()
	go worker.Launch()
	testAll(server, t)
}


================================================
FILE: integration-tests/redis_mongodb_test.go
================================================
package integration_test

import (
	"fmt"
	"os"
	"testing"

	"github.com/RichardKnop/machinery/v1"
	"github.com/RichardKnop/machinery/v1/config"
)

func TestRedisMongodb(t *testing.T) {
	redisURL := os.Getenv("REDIS_URL")
	mongodbURL := os.Getenv("MONGODB_URL")
	if redisURL == "" {
		t.Skip("REDIS_URL is not defined")
	}
	if mongodbURL == "" {
		t.Skip("MONGODB_URL is not defined")
	}

	// Redis broker, MongoDB result backend
	server := testSetup(&config.Config{
		Broker:          fmt.Sprintf("redis://%v", redisURL),
		DefaultQueue:    "test_queue",
		ResultsExpireIn: 30,
		ResultBackend:   fmt.Sprintf("mongodb://%v", mongodbURL),
		Lock:            fmt.Sprintf("redis://%v", redisURL),
	})

	worker := server.(*machinery.Server).NewWorker("test_worker", 0)
	defer worker.Quit()
	go worker.Launch()
	testAll(server, t)
}


================================================
FILE: integration-tests/redis_redis_test.go
================================================
package integration_test

import (
	"errors"
	"fmt"
	"os"
	"testing"
	"time"

	"github.com/RichardKnop/machinery/v1"
	"github.com/RichardKnop/machinery/v1/config"
)

func TestRedisRedis_Redigo(t *testing.T) {
	redisURL := os.Getenv("REDIS_URL")
	if redisURL == "" {
		t.Skip("REDIS_URL is not defined")
	}

	// Redis broker, Redis result backend
	server := testSetup(&config.Config{
		Broker:        fmt.Sprintf("redis://%v", redisURL),
		DefaultQueue:  "test_queue",
		ResultBackend: fmt.Sprintf("redis://%v", redisURL),
		Lock:          fmt.Sprintf("redis://%v", redisURL),
	})

	worker := server.(*machinery.Server).NewWorker("test_worker", 0)
	defer worker.Quit()
	go worker.Launch()
	testAll(server, t)
}

func TestRedisRedisNormalTaskPollPeriodLessThan1SecondShouldNotFailNextTask(t *testing.T) {
	redisURL := os.Getenv("REDIS_URL")
	if redisURL == "" {
		t.Skip("REDIS_URL is not defined")
	}

	// Redis broker, Redis result backend
	server := testSetup(&config.Config{
		Broker:        fmt.Sprintf("redis://%v", redisURL),
		DefaultQueue:  "test_queue",
		ResultBackend: fmt.Sprintf("redis://%v", redisURL),
		Lock:          fmt.Sprintf("redis://%v", redisURL),
		Redis: &config.RedisConfig{
			NormalTasksPollPeriod: 10, // 10 milliseconds
		},
	})

	worker := server.(*machinery.Server).NewWorker("test_worker", 0)
	go worker.Launch()
	defer worker.Quit()
	testSendTask(server, t)
}

func TestRedisRedisWorkerQuitRaceCondition(t *testing.T) {
	repeat := 3
	for i := 0; i < repeat; i++ {
		redisURL := os.Getenv("REDIS_URL")
		if redisURL == "" {
			t.Skip("REDIS_URL is not defined")
		}

		// Redis broker, Redis result backend
		cnf := &config.Config{
			Broker:        fmt.Sprintf("redis://%v", redisURL),
			DefaultQueue:  "test_queue",
			ResultBackend: fmt.Sprintf("redis://%v", redisURL),
			Lock:          fmt.Sprintf("redis://%v", redisURL),
		}

		server, _ := machinery.NewServer(cnf)
		worker := server.NewWorker("test_worker", 0)

		errorsChan := make(chan error, 1)

		// Check Quit() immediately after LaunchAsync() will shutdown gracefully
		// and not panic on close(b.stopChan)
		worker.LaunchAsync(errorsChan)
		worker.Quit()

		if err := <-errorsChan; err != nil {
			t.Errorf("Error shutting down machinery worker gracefully %+v", err)
			continue
		}
	}
}

func TestRedisRedisWorkerQuickQuit(t *testing.T) {
	redisURL := os.Getenv("REDIS_URL")
	if redisURL == "" {
		t.Skip("REDIS_URL is not defined")
	}

	// Redis broker, Redis result backend
	pollPeriod := 1
	cnf := &config.Config{
		Broker:        fmt.Sprintf("redis://%v", redisURL),
		DefaultQueue:  "test_queue",
		ResultBackend: fmt.Sprintf("redis://%v", redisURL),
		Lock:          fmt.Sprintf("redis://%v", redisURL),
		Redis: &config.RedisConfig{
			NormalTasksPollPeriod: pollPeriod, // default: 1000
		},
	}

	server, _ := machinery.NewServer(cnf)
	worker := server.NewWorker("test_worker", 0)

	errorsChan := make(chan error, 1)

	// Check Quit() immediately after LaunchAsync() will shutdown gracefully
	// and not panic
	worker.LaunchAsync(errorsChan)

	before := time.Now()
	worker.Quit()
	delta := time.Since(before)

	threshold := time.Duration(pollPeriod)*time.Millisecond + 1000 // add 1 second as buffer

	if delta.Nanoseconds() > threshold.Nanoseconds() {
		t.Error("Worker quit() exceeded timeout")
	}
}

func TestRedisRedisWorkerPreConsumeHandler(t *testing.T) {
	redisURL := os.Getenv("REDIS_URL")
	if redisURL == "" {
		t.Skip("REDIS_URL is not defined")
	}

	// Redis broker, Redis result backend
	pollPeriod := 1
	cnf := &config.Config{
		Broker:        fmt.Sprintf("redis://%v", redisURL),
		DefaultQueue:  "test_queue",
		ResultBackend: fmt.Sprintf("redis://%v", redisURL),
		Lock:          fmt.Sprintf("redis://%v", redisURL),
		Redis: &config.RedisConfig{
			NormalTasksPollPeriod: pollPeriod, // default: 1000
		},
	}

	server, _ := machinery.NewServer(cnf)
	worker := server.NewWorker("test_worker", 0)
	errorsChan := make(chan error)
	err := errors.New("PreConsumeHandler is invoked")
	worker.SetPreConsumeHandler(func(*machinery.Worker) bool {
		errorsChan <- err
		return true
	})

	worker.LaunchAsync(errorsChan)
	if err != <-errorsChan {
		t.Error("PreConsumeHandler was not invoked")
	}
}


================================================
FILE: integration-tests/redis_socket_test.go
================================================
package integration_test

import (
	"fmt"
	"os"
	"testing"

	"github.com/RichardKnop/machinery/v1"
	"github.com/RichardKnop/machinery/v1/config"
)

func TestRedisSocket(t *testing.T) {
	redisSocket := os.Getenv("REDIS_SOCKET")
	if redisSocket == "" {
		t.Skip("REDIS_SOCKET is not defined")
	}

	// Redis broker, Redis result backend
	server := testSetup(&config.Config{
		Broker:        fmt.Sprintf("redis+socket://%v", redisSocket),
		DefaultQueue:  "test_queue",
		ResultBackend: fmt.Sprintf("redis+socket://%v", redisSocket),
		Lock:          "eager",
	})

	worker := server.(*machinery.Server).NewWorker("test_worker", 0)
	defer worker.Quit()
	go worker.Launch()
	testAll(server, t)
}


================================================
FILE: integration-tests/sqs_amqp_test.go
================================================
package integration_test

import (
	"os"
	"testing"

	"github.com/RichardKnop/machinery/v1"
	"github.com/RichardKnop/machinery/v1/config"
)

func TestSQSAmqp(t *testing.T) {
	sqsURL := os.Getenv("SQS_URL")
	if sqsURL == "" {
		t.Skip("SQS_URL is not defined")
	}

	amqpURL := os.Getenv("AMQP_URL")
	if amqpURL == "" {
		t.Skip("AMQP_URL is not defined")
	}

	// AMQP broker, AMQP result backend
	server := testSetup(&config.Config{
		Broker:        sqsURL,
		DefaultQueue:  "test_queue",
		ResultBackend: amqpURL,
		Lock:          "eager",
		AMQP: &config.AMQPConfig{
			Exchange:      "test_exchange",
			ExchangeType:  "direct",
			BindingKey:    "test_task",
			PrefetchCount: 1,
		},
	})

	worker := server.(*machinery.Server).NewWorker("test_worker", 0)
	defer worker.Quit()
	go worker.Launch()
	testAll(server, t)
}


================================================
FILE: integration-tests/sqs_mongodb_test.go
================================================
package integration_test

import (
	"fmt"
	"os"
	"testing"

	"github.com/RichardKnop/machinery/v1"
	"github.com/RichardKnop/machinery/v1/config"
)

func TestSQSMongodb(t *testing.T) {
	sqsURL := os.Getenv("SQS_URL")
	mongodbURL := os.Getenv("MONGODB_URL")
	if sqsURL == "" {
		t.Skip("SQS_URL is not defined")
	}
	if mongodbURL == "" {
		t.Skip("MONGODB_URL is not defined")
	}

	// AMQP broker, MongoDB result backend
	server := testSetup(&config.Config{
		Broker:          sqsURL,
		DefaultQueue:    "test_queue",
		ResultsExpireIn: 30,
		ResultBackend:   fmt.Sprintf("mongodb://%v", mongodbURL),
		Lock:            "eager",
	})
	worker := server.(*machinery.Server).NewWorker("test_worker", 0)
	go worker.Launch()
	testAll(server, t)
	worker.Quit()
}


================================================
FILE: integration-tests/suite_test.go
================================================
package integration_test

import (
	"context"
	"errors"
	"log"
	"reflect"
	"sort"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"

	"github.com/RichardKnop/machinery/v1"
	"github.com/RichardKnop/machinery/v1/backends/result"
	"github.com/RichardKnop/machinery/v1/config"
	"github.com/RichardKnop/machinery/v1/tasks"

	brokersiface "github.com/RichardKnop/machinery/v1/brokers/iface"
)

type ascendingInt64s []int64

func (a ascendingInt64s) Len() int           { return len(a) }
func (a ascendingInt64s) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ascendingInt64s) Less(i, j int) bool { return a[i] < a[j] }

type Server interface {
	GetBroker() brokersiface.Broker
	GetConfig() *config.Config
	RegisterTasks(namedTaskFuncs map[string]interface{}) error
	SendTaskWithContext(ctx context.Context, signature *tasks.Signature) (*result.AsyncResult, error)
	SendTask(signature *tasks.Signature) (*result.AsyncResult, error)
	SendChainWithContext(ctx context.Context, chain *tasks.Chain) (*result.ChainAsyncResult, error)
	SendChain(chain *tasks.Chain) (*result.ChainAsyncResult, error)
	SendGroupWithContext(ctx context.Context, group *tasks.Group, sendConcurrency int) ([]*result.AsyncResult, error)
	SendGroup(group *tasks.Group, sendConcurrency int) ([]*result.AsyncResult, error)
	SendChordWithContext(ctx context.Context, chord *tasks.Chord, sendConcurrency int) (*result.ChordAsyncResult, error)
	SendChord(chord *tasks.Chord, sendConcurrency int) (*result.ChordAsyncResult, error)
}

func testAll(server Server, t *testing.T) {
	testSendTask(server, t)
	testSendGroup(server, t, 0) // with unlimited concurrency
	testSendGroup(server, t, 2) // with limited concurrency (2 parallel tasks at the most)
	testSendChord(server, t)
	testSendChain(server, t)
	testReturnJustError(server, t)
	testReturnMultipleValues(server, t)
	testPanic(server, t)
	testDelay(server, t)
}

func testSendTask(server Server, t *testing.T) {
	addTask := newAddTask(1, 1)

	asyncResult, err := server.SendTask(addTask)
	if err != nil {
		t.Error(err)
	}

	results, err := asyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		t.Error(err)
	}

	if len(results) != 1 {
		t.Errorf("Number of results returned = %d. Wanted %d", len(results), 1)
	}

	if results[0].Interface() != int64(2) {
		t.Errorf(
			"result = %v(%v), want int64(2)",
			results[0].Type().String(),
			results[0].Interface(),
		)
	}

	sumTask := newSumTask([]int64{1, 2})
	asyncResult, err = server.SendTask(sumTask)
	if err != nil {
		t.Error(err)
	}

	results, err = asyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		t.Error(err)
	}

	if len(results) != 1 {
		t.Errorf("Number of results returned = %d. Wanted %d", len(results), 1)
	}

	if results[0].Interface() != int64(3) {
		t.Errorf(
			"result = %v(%v), want int64(3)",
			results[0].Type().String(),
			results[0].Interface(),
		)
	}
}

func testSendGroup(server Server, t *testing.T, sendConcurrency int) {
	t1, t2, t3 := newAddTask(1, 1), newAddTask(2, 2), newAddTask(5, 6)

	group, err := tasks.NewGroup(t1, t2, t3)
	if err != nil {
		t.Fatal(err)
	}

	asyncResults, err := server.SendGroup(group, sendConcurrency)
	if err != nil {
		t.Error(err)
	}

	expectedResults := []int64{2, 4, 11}

	actualResults := make([]int64, 3)

	for i, asyncResult := range asyncResults {
		results, err := asyncResult.Get(time.Duration(time.Millisecond * 5))
		if err != nil {
			t.Error(err)
		}

		if len(results) != 1 {
			t.Errorf("Number of results returned = %d. Wanted %d", len(results), 1)
		}

		intResult, ok := results[0].Interface().(int64)
		if !ok {
			t.Errorf("Could not convert %v to int64", results[0].Interface())
		}
		actualResults[i] = intResult
	}

	sort.Sort(ascendingInt64s(actualResults))

	if !reflect.DeepEqual(expectedResults, actualResults) {
		t.Errorf(
			"expected results = %v, actual results = %v",
			expectedResults,
			actualResults,
		)
	}
}

func testSendChain(server Server, t *testing.T) {
	t1, t2, t3 := newAddTask(2, 2), newAddTask(5, 6), newMultipleTask(4)

	chain, err := tasks.NewChain(t1, t2, t3)
	if err != nil {
		t.Fatal(err)
	}

	chainAsyncResult, err := server.SendChain(chain)
	if err != nil {
		t.Error(err)
	}

	results, err := chainAsyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		t.Error(err)
	}

	if len(results) != 1 {
		t.Errorf("Number of results returned = %d. Wanted %d", len(results), 1)
	}

	if results[0].Interface() != int64(60) {
		t.Errorf(
			"result = %v(%v), want int64(60)",
			results[0].Type().String(),
			results[0].Interface(),
		)
	}
}

func testSendChord(server Server, t *testing.T) {
	t1, t2, t3, t4 := newAddTask(1, 1), newAddTask(2, 2), newAddTask(5, 6), newMultipleTask()

	group, err := tasks.NewGroup(t1, t2, t3)
	if err != nil {
		t.Fatal(err)
	}

	chord, err := tasks.NewChord(group, t4)
	if err != nil {
		t.Fatal(err)
	}

	chordAsyncResult, err := server.SendChord(chord, 10)
	if err != nil {
		t.Error(err)
	}

	results, err := chordAsyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		t.Error(err)
	}

	if len(results) != 1 {
		t.Errorf("Number of results returned = %d. Wanted %d", len(results), 1)
	}

	if results[0].Interface() != int64(88) {
		t.Errorf(
			"result = %v(%v), want int64(88)",
			results[0].Type().String(),
			results[0].Interface(),
		)
	}
}

func testReturnJustError(server Server, t *testing.T) {
	// Fails, returns error as the only value
	task := newErrorTask("Test error", true)
	asyncResult, err := server.SendTask(task)
	if err != nil {
		t.Error(err)
	}

	results, err := asyncResult.Get(time.Duration(time.Millisecond * 5))
	if len(results) != 0 {
		t.Errorf("Number of results returned = %d. Wanted %d", len(results), 0)
	}
	assert.Equal(t, "Test error", err.Error())

	// Successful, returns nil as the only value
	task = newErrorTask("", false)
	asyncResult, err = server.SendTask(task)
	if err != nil {
		t.Error(err)
	}

	results, err = asyncResult.Get(time.Duration(time.Millisecond * 5))
	if len(results) != 0 {
		t.Errorf("Number of results returned = %d. Wanted %d", len(results), 0)
	}
	assert.NoError(t, err)
}

func testReturnMultipleValues(server Server, t *testing.T) {
	// Successful task with multiple return values
	task := newMultipleReturnTask("foo", "bar", false)

	asyncResult, err := server.SendTask(task)
	if err != nil {
		t.Error(err)
	}

	results, err := asyncResult.Get(time.Duration(time.Millisecond * 5))
	if err != nil {
		t.Error(err)
	}

	if len(results) != 2 {
		t.Errorf("Number of results returned = %d. Wanted %d", len(results), 2)
	}

	if results[0].Interface() != "foo" {
		t.Errorf(
			"result = %v(%v), want string(\"foo\":)",
			results[0].Type().String(),
			results[0].Interface(),
		)
	}

	if results[1].Interface() != "bar" {
		t.Errorf(
			"result = %v(%v), want string(\"bar\":)",
			results[1].Type().String(),
			results[1].Interface(),
		)
	}

	// Failed task with multiple return values
	task = newMultipleReturnTask("", "", true)

	asyncResult, err = server.SendTask(task)
	if err != nil {
		t.Error(err)
	}

	results, err = asyncResult.Get(time.Duration(time.Millisecond * 5))
	if len(results) != 0 {
		t.Errorf("Number of results returned = %d. Wanted %d", len(results), 0)
	}
	assert.Error(t, err)
}

func testPanic(server Server, t *testing.T) {
	task := &tasks.Signature{Name: "panic"}
	asyncResult, err := server.SendTask(task)
	if err != nil {
		t.Error(err)
	}

	results, err := asyncResult.Get(time.Duration(time.Millisecond * 5))
	if len(results) != 0 {
		t.Errorf("Number of results returned = %d. Wanted %d", len(results), 0)
	}
	assert.Equal(t, "oops", err.Error())
}

func testDelay(server Server, t *testing.T) {
	now := time.Now().UTC()
	eta := now.Add(100 * time.Millisecond)
	task := newDelayTask(eta)
	asyncResult, err := server.SendTask(task)
	if err != nil {
		t.Error(err)
	}

	results, err := asyncResult.Get(time.Duration(5 * time.Millisecond))
	if err != nil {
		t.Error(err)
	}

	if len(results) != 1 {
		t.Errorf("Number of results returned = %d. Wanted %d", len(results), 1)
	}

	tm, ok := results[0].Interface().(int64)
	if !ok {
		t.Errorf(
			"Could not type assert = %v(%v) to int64",
			results[0].Type().String(),
			results[0].Interface(),
		)
	}

	if tm < eta.UnixNano() {
		t.Errorf(
			"result = %v(%v), want >= int64(%d)",
			results[0].Type().String(),
			results[0].Interface(),
			eta.UnixNano(),
		)
	}
}

func registerTestTasks(server Server) {

	tasks := map[string]interface{}{
		"add": func(args ...int64) (int64, error) {
			sum := int64(0)
			for _, arg := range args {
				sum += arg
			}
			return sum, nil
		},
		"multiply": func(args ...int64) (int64, error) {
			sum := int64(1)
			for _, arg := range args {
				sum *= arg
			}
			return sum, nil
		},
		"sum": func(numbers []int64) (int64, error) {
			var sum int64
			for _, num := range numbers {
				sum += num
			}
			return sum, nil
		},
		"return_just_error": func(msg string, fail bool) (err error) {
			if fail {
				err = errors.New(msg)
			}
			return err
		},
		"return_multiple_values": func(arg1, arg2 string, fail bool) (r1 string, r2 string, err error) {
			if fail {
				err = errors.New("some error")
			} else {
				r1 = arg1
				r2 = arg2
			}
			return r1, r2, err
		},
		"panic": func() (string, error) {
			panic(errors.New("oops"))
		},
		"delay_test": func() (int64, error) {
			return time.Now().UTC().UnixNano(), nil
		},
	}

	server.RegisterTasks(tasks)
}

func testSetup(cnf *config.Config) Server {

	server, err := machinery.NewServer(cnf)
	if err != nil {
		log.Fatal(err, "Could not initialize server")
	}

	registerTestTasks(server)

	return server
}

func newAddTask(a, b int) *tasks.Signature {
	return &tasks.Signature{
		Name: "add",
		Args: []tasks.Arg{
			{
				Type:  "int64",
				Value: a,
			},
			{
				Type:  "int64",
				Value: b,
			},
		},
	}
}

func newMultipleTask(nums ...int) *tasks.Signature {
	args := make([]tasks.Arg, len(nums))
	for i, n := range nums {
		args[i] = tasks.Arg{
			Type:  "int64",
			Value: n,
		}
	}
	return &tasks.Signature{
		Name: "multiply",
		Args: args,
	}
}

func newSumTask(nums []int64) *tasks.Signature {
	return &tasks.Signature{
		Name: "sum",
		Args: []tasks.Arg{
			{
				Type:  "[]int64",
				Value: nums,
			},
		},
	}
}

func newErrorTask(msg string, fail bool) *tasks.Signature {
	return &tasks.Signature{
		Name: "return_just_error",
		Args: []tasks.Arg{
			{
				Type:  "string",
				Value: msg,
			},
			{
				Type:  "bool",
				Value: fail,
			},
		},
	}
}

func newMultipleReturnTask(arg1, arg2 string, fail bool) *tasks.Signature {
	return &tasks.Signature{
		Name: "return_multiple_values",
		Args: []tasks.Arg{
			{
				Type:  "string",
				Value: arg1,
			},
			{
				Type:  "string",
				Value: arg2,
			},
			{
				Type:  "bool",
				Value: fail,
			},
		},
	}
}

func newDelayTask(eta time.Time) *tasks.Signature {
	return &tasks.Signature{
		Name: "delay_test",
		ETA:  &eta,
	}
}


================================================
FILE: integration-tests/worker_only_consumes_registered_tasks_test.go
================================================
package integration_test

import (
	"fmt"
	"os"
	"reflect"
	"sort"
	"testing"
	"time"

	"github.com/RichardKnop/machinery/v1"
	"github.com/RichardKnop/machinery/v1/config"
	"github.com/RichardKnop/machinery/v1/tasks"
)

func TestWorkerOnlyConsumesRegisteredTaskAMQP(t *testing.T) {
	amqpURL := os.Getenv("AMQP_URL")
	if amqpURL == "" {
		t.Skip("AMQP_URL is not defined")
	}

	cnf := config.Config{
		Broker:        amqpURL,
		DefaultQueue:  "test_queue",
		ResultBackend: amqpURL,
		Lock:          "eager",
		AMQP: &config.AMQPConfig{
			Exchange:      "test_exchange",
			ExchangeType:  "direct",
			BindingKey:    "test_task",
			PrefetchCount: 3,
		},
	}

	server1, err := machinery.NewServer(&cnf)
	if err != nil {
		t.Fatal(err, "Could not initialize server")
	}

	server1.RegisterTask("add", func(args ...int64) (int64, error) {
		sum := int64(0)
		for _, arg := range args {
			sum += arg
		}
		return sum, nil
	})

	server2, err := machinery.NewServer(&cnf)
	if err != nil {
		t.Fatal(err, "Could not initialize server")
	}

	server2.RegisterTask("multiply", func(args ...int64) (int64, error) {
		sum := int64(1)
		for _, arg := range args {
			sum *= arg
		}
		return sum, nil
	})

	task1 := tasks.Signature{
		Name: "add",
		Args: []tasks.Arg{
			{
				Type:  "int64",
				Value: 2,
			},
			{
				Type:  "int64",
				Value: 3,
			},
		},
	}

	task2 := tasks.Signature{
		Name: "multiply",
		Args: []tasks.Arg{
			{
				Type:  "int64",
				Value: 4,
			},
			{
				Type:  "int64",
				Value: 5,
			},
		},
	}

	worker1 := server1.NewWorker("test_worker", 0)
	worker2 := server2.NewWorker("test_worker2", 0)
	go worker1.Launch()
	go worker2.Launch()

	group, err := tasks.NewGroup(&task2, &task1)
	if err != nil {
		t.Fatal(err)
	}

	asyncResults, err := server1.SendGroup(group, 10)
	if err != nil {
		t.Error(err)
	}

	expectedResults := []int64{5, 20}
	actualResults := make([]int64, 2)

	for i, asyncResult := range asyncResults {
		results, err := asyncResult.Get(time.Duration(time.Millisecond * 5))
		if err != nil {
			t.Error(err)
		}

		if len(results) != 1 {
			t.Errorf("Number of results returned = %d. Wanted %d", len(results), 1)
		}

		intResult, ok := results[0].Interface().(int64)
		if !ok {
			t.Errorf("Could not convert %v to int64", results[0].Interface())
		}
		actualResults[i] = intResult
	}

	worker1.Quit()
	worker2.Quit()

	sort.Sort(ascendingInt64s(actualResults))

	if !reflect.DeepEqual(expectedResults, actualResults) {
		t.Errorf(
			"expected results = %v, actual results = %v",
			expectedResults,
			actualResults,
		)
	}
}

func TestWorkerOnlyConsumesRegisteredTaskRedis(t *testing.T) {
	redisURL := os.Getenv("REDIS_URL")
	if redisURL == "" {
		t.Skip("REDIS_URL is not defined")
	}

	cnf := config.Config{
		Broker:        fmt.Sprintf("redis://%v", redisURL),
		DefaultQueue:  "test_queue",
		ResultBackend: fmt.Sprintf("redis://%v", redisURL),
		Lock:          fmt.Sprintf("redis://%v", redisURL),
	}

	server1, err := machinery.NewServer(&cnf)
	if err != nil {
		t.Fatal(err)
	}

	server1.RegisterTask("add", func(args ...int64) (int64, error) {
		sum := int64(0)
		for _, arg := range args {
			sum += arg
		}
		return sum, nil
	})

	server2, err := machinery.NewServer(&cnf)
	if err != nil {
		t.Fatal(err)
	}

	server2.RegisterTask("multiply", func(args ...int64) (int64, error) {
		sum := int64(1)
		for _, arg := range args {
			sum *= arg
		}
		return sum, nil
	})

	task1 := tasks.Signature{
		Name: "add",
		Args: []tasks.Arg{
			{
				Type:  "int64",
				Value: 2,
			},
			{
				Type:  "int64",
				Value: 3,
			},
		},
	}

	task2 := tasks.Signature{
		Name: "multiply",
		Args: []tasks.Arg{
			{
				Type:  "int64",
				Value: 4,
			},
			{
				Type:  "int64",
				Value: 5,
			},
		},
	}

	worker1 := server1.NewWorker("test_worker", 0)
	worker2 := server2.NewWorker("test_worker2", 0)
	go worker1.Launch()
	go worker2.Launch()

	group, err := tasks.NewGroup(&task2, &task1)
	if err != nil {
		t.Fatal(err)
	}

	asyncResults, err := server1.SendGroup(group, 10)
	if err != nil {
		t.Error(err)
	}

	expectedResults := []int64{5, 20}
	actualResults := make([]int64, 2)

	for i, asyncResult := range asyncResults {
		results, err := asyncResult.Get(time.Duration(time.Millisecond * 5))
		if err != nil {
			t.Error(err)
		}

		if len(results) != 1 {
			t.Errorf("Number of results returned = %d. Wanted %d", len(results), 1)
		}

		intResult, ok := results[0].Interface().(int64)
		if !ok {
			t.Errorf("Could not convert %v to int64", results[0].Interface())
		}
		actualResults[i] = intResult
	}

	worker1.Quit()
	worker2.Quit()

	sort.Sort(ascendingInt64s(actualResults))

	if !reflect.DeepEqual(expectedResults, actualResults) {
		t.Errorf(
			"expected results = %v, actual results = %v",
			expectedResults,
			actualResults,
		)
	}
}


================================================
FILE: v1/backends/amqp/amqp.go
================================================
package amqp

// NOTE: Using AMQP as a result backend is quite tricky since every time we
// read a message from the queue keeping task states, the message is removed
// from the queue. This leads to problems with keeping a reliable state of a
// group of tasks since concurrent processes updating the group state cause
// race conditions and inconsistent state.
//
// This is avoided by a "clever" hack. A special queue identified by a group
// UUID is created and we store serialised TaskState objects of successfully
// completed tasks. By inspecting the queue we can then say:
// 1) If all group tasks finished (number of unacked messages = group task count)
// 2) If all group tasks finished AND succeeded (by consuming the queue)
//
// It is important to consume the queue exclusively to avoid race conditions.

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"

	"github.com/RichardKnop/machinery/v1/backends/iface"
	"github.com/RichardKnop/machinery/v1/common"
	"github.com/RichardKnop/machinery/v1/config"
	"github.com/RichardKnop/machinery/v1/log"
	"github.com/RichardKnop/machinery/v1/tasks"
	amqp "github.com/rabbitmq/amqp091-go"
)

// Backend represents an AMQP result backend
type Backend struct {
	common.Backend
	common.AMQPConnector
}

// New creates Backend instance
func New(cnf *config.Config) iface.Backend {
	return &Backend{Backend: common.NewBackend(cnf), AMQPConnector: common.AMQPConnector{}}
}

// InitGroup creates and saves a group meta data object
func (b *Backend) InitGroup(groupUUID string, taskUUIDs []string) error {
	return nil
}

// GroupCompleted returns true if all tasks in a group finished
// NOTE: Given AMQP limitation this will only return true if all finished
// tasks were successful as we do not keep track of completed failed tasks
func (b *Backend) GroupCompleted(groupUUID string, groupTaskCount int) (bool, error) {
	conn, channel, err := b.Open(b.GetConfig().ResultBackend, b.GetConfig().TLSConfig)
	if err != nil {
		return false, err
	}
	defer b.Close(channel, conn)

	queueState, err := b.InspectQueue(channel, groupUUID)
	if err != nil {
		return false, nil
	}

	return queueState.Messages == groupTaskCount, nil
}

// GroupTaskStates returns states of all tasks in the group
func (b *Backend) GroupTaskStates(groupUUID string, groupTaskCount int) ([]*tasks.TaskState, error) {
	conn, channel, err := b.Open(b.GetConfig().ResultBackend, b.GetConfig().TLSConfig)
	if err != nil {
		return nil, err
	}
	defer b.Close(channel, conn)

	queueState, err := b.InspectQueue(channel, groupUUID)
	if err != nil {
		return nil, err
	}

	if queueState.Messages != groupTaskCount {
		return nil, fmt.Errorf("Already consumed: %v", err)
	}

	deliveries, err := channel.Consume(
		groupUUID, // queue name
		"",        // consumer tag
		false,     // auto-ack
		true,      // exclusive
		false,     // no-local
		false,     // no-wait
		nil,       // arguments
	)
	if err != nil {
		return nil, fmt.Errorf("Queue consume error: %s", err)
	}

	states := make([]*tasks.TaskState, groupTaskCount)
	for i := 0; i < groupTaskCount; i++ {
		d := <-deliveries

		state := new(tasks.TaskState)
		decoder := json.NewDecoder(bytes.NewReader([]byte(d.Body)))
		decoder.UseNumber()
		if err := decoder.Decode(state); err != nil {
			d.Nack(false, false) // multiple, requeue
			return nil, err
		}

		d.Ack(false) // multiple

		states[i] = state
	}

	return states, nil
}

// TriggerChord flags chord as triggered in the backend storage to make sure
// chord is never trigerred multiple times. Returns a boolean flag to indicate
// whether the worker should trigger chord (true) or no if it has been triggered
// already (false)
func (b *Backend) TriggerChord(groupUUID string) (bool, error) {
	conn, channel, err := b.Open(b.GetConfig().ResultBackend, b.GetConfig().TLSConfig)
	if err != nil {
		return false, err
	}
	defer b.Close(channel, conn)

	_, err = b.InspectQueue(channel, amqmChordTriggeredQueue(groupUUID))
	if err != nil {
		return true, nil
	}

	return false, nil
}

// SetStatePending updates task state to PENDING
func (b *Backend) SetStatePending(signature *tasks.Signature) error {
	taskState := tasks.NewPendingTaskState(signature)
	return b.updateState(taskState)
}

// SetStateReceived updates task state to RECEIVED
func (b *Backend) SetStateReceived(signature *tasks.Signature) error {
	taskState := tasks.NewReceivedTaskState(signature)
	return b.updateState(taskState)
}

// SetStateStarted updates task state to STARTED
func (b *Backend) SetStateStarted(signature *tasks.Signature) error {
	taskState := tasks.NewStartedTaskState(signature)
	return b.updateState(taskState)
}

// SetStateRetry updates task state to RETRY
func (b *Backend) SetStateRetry(signature *tasks.Signature) error {
	state := tasks.NewRetryTaskState(signature)
	return b.updateState(state)
}

// SetStateSuccess updates task state to SUCCESS
func (b *Backend) SetStateSuccess(signature *tasks.Signature, results []*tasks.TaskResult) error {
	taskState := tasks.NewSuccessTaskState(signature, results)

	if err := b.updateState(taskState); err != nil {
		return err
	}

	if signature.GroupUUID == "" {
		return nil
	}

	return b.markTaskCompleted(signature, taskState)
}

// SetStateFailure updates task state to FAILURE
func (b *Backend) SetStateFailure(signature *tasks.Signature, err string) error {
	taskState := tasks.NewFailureTaskState(signature, err)

	if err := b.updateState(taskState); err != nil {
		return err
	}

	if signature.GroupUUID == "" {
		return nil
	}

	return b.markTaskCompleted(signature, taskState)
}

// GetState returns the latest task state. It will only return the status once
// as the message will get consumed and removed from the queue.
func (b *Backend) GetState(taskUUID string) (*tasks.TaskState, error) {
	declareQueueArgs := amqp.Table{
		// Time in milliseconds
		// after that message will expire
		"x-message-ttl": int32(b.getExpiresIn()),
		// Time after that the queue will be deleted.
		"x-expires": int32(b.getExpiresIn()),
	}
	conn, channel, _, _, _, err := b.Connect(
		b.GetConfig().ResultBackend,
		"",
		b.GetConfig().TLSConfig,
		b.GetConfig().AMQP.Exchange,     // exchange name
		b.GetConfig().AMQP.ExchangeType, // exchange type
		taskUUID,                        // queue name
		false,                           // queue durable
		true,                            // queue delete when unused
		taskUUID,                        // queue binding key
		nil,                             // exchange declare args
		declareQueueArgs,                // queue declare args
		nil,                             // queue binding args
	)
	if err != nil {
		return nil, err
	}
	defer b.Close(channel, conn)

	d, ok, err := channel.Get(
		taskUUID, // queue name
		false,    // multiple
	)
	if err != nil {
		return nil, err
	}
	if !ok {
		return nil, errors.New("No state ready")
	}

	d.Ack(false)

	state := new(tasks.TaskState)
	decoder := json.NewDecoder(bytes.NewReader([]byte(d.Body)))
	decoder.UseNumber()
	if err := decoder.Decode(state); err != nil {
		log.ERROR.Printf("Failed to unmarshal task state: %s", string(d.Body))
		log.ERROR.Print(err)
		return nil, err
	}

	return state, nil
}

// PurgeState deletes stored task state
func (b *Backend) PurgeState(taskUUID string) error {
	conn, channel, err := b.Open(b.GetConfig().ResultBackend, b.GetConfig().TLSConfig)
	if err != nil {
		return err
	}
	defer b.Close(channel, conn)

	return b.DeleteQueue(channel, taskUUID)
}

// PurgeGroupMeta deletes stored group meta data
func (b *Backend) PurgeGroupMeta(groupUUID string) error {
	conn, channel, err := b.Open(b.GetConfig().ResultBackend, b.GetConfig().TLSConfig)
	if err != nil {
		return err
	}
	defer b.Close(channel, conn)

	b.DeleteQueue(channel, amqmChordTriggeredQueue(groupUUID))

	return b.DeleteQueue(channel, groupUUID)
}

// updateState saves current task state
func (b *Backend) updateState(taskState *tasks.TaskState) error {
	message, err := json.Marshal(taskState)
	if err != nil {
		return fmt.Errorf("JSON marshal error: %s", err)
	}

	declareQueueArgs := amqp.Table{
		// Time in milliseconds
		// after that message will expire
		"x-message-ttl": int32(b.getExpiresIn()),
		// Time after that the queue will be deleted.
		"x-expires": int32(b.getExpiresIn()),
	}
	conn, channel, queue, confirmsChan, _, err := b.Connect(
		b.GetConfig().ResultBackend,
		"",
		b.GetConfig().TLSConfig,
		b.GetConfig().AMQP.Exchange,     // exchange name
		b.GetConfig().AMQP.ExchangeType, // exchange type
		taskState.TaskUUID,              // queue name
		false,                           // queue durable
		true,                            // queue delete when unused
		taskState.TaskUUID,              // queue binding key
		nil,                             // exchange declare args
		declareQueueArgs,                // queue declare args
		nil,                             // queue binding args
	)
	if err != nil {
		return err
	}
	defer b.Close(channel, conn)

	if err := channel.Publish(
		b.GetConfig().AMQP.Exchange, // exchange
		queue.Name,                  // routing key
		false,                       // mandatory
		false,                       // immediate
		amqp.Publishing{
			ContentType:  "application/json",
			Body:         message,
			DeliveryMode: amqp.Persistent, // Persistent // Transient
		},
	); err != nil {
		return err
	}

	confirmed := <-confirmsChan

	if confirmed.Ack {
		return nil
	}

	return fmt.Errorf("Failed delivery of delivery tag: %d", confirmed.DeliveryTag)
}

// getExpiresIn returns expiration time
func (b *Backend) getExpiresIn() int {
	resultsExpireIn := b.GetConfig().ResultsExpireIn * 1000
	if resultsExpireIn == 0 {
		// // expire results after 1 hour by default
		resultsExpireIn = config.DefaultResultsExpireIn * 1000
	}
	return resultsExpireIn
}

// markTaskCompleted marks task as completed in either groupdUUID_success
// or groupUUID_failure queue. This is important for GroupCompleted and
// GroupSuccessful methods
func (b *Backend) markTaskCompleted(signature *tasks.Signature, taskState *tasks.TaskState) error {
	if signature.GroupUUID == "" || signature.GroupTaskCount == 0 {
		return nil
	}

	message, err := json.Marshal(taskState)
	if err != nil {
		return fmt.Errorf("JSON marshal error: %s", err)
	}

	declareQueueArgs := amqp.Table{
		// Time in milliseconds
		// after that message will expire
		"x-message-ttl": int32(b.getExpiresIn()),
		// Time after that the queue will be deleted.
		"x-expires": int32(b.getExpiresIn()),
	}
	conn, channel, queue, confirmsChan, _, err := b.Connect(
		b.GetConfig().ResultBackend,
		"",
		b.GetConfig().TLSConfig,
		b.GetConfig().AMQP.Exchange,     // exchange name
		b.GetConfig().AMQP.ExchangeType, // exchange type
		signature.GroupUUID,             // queue name
		false,                           // queue durable
		true,                            // queue delete when unused
		signature.GroupUUID,             // queue binding key
		nil,                             // exchange declare args
		declareQueueArgs,                // queue declare args
		nil,                             // queue binding args
	)
	if err != nil {
		return err
	}
	defer b.Close(channel, conn)

	if err := channel.Publish(
		b.GetConfig().AMQP.Exchange, // exchange
		queue.Name,                  // routing key
		false,                       // mandatory
		false,                       // immediate
		amqp.Publishing{
			ContentType:  "application/json",
			Body:         message,
			DeliveryMode: amqp.Persistent, // Persistent // Transient
		},
	); err != nil {
		return err
	}

	confirmed := <-confirmsChan

	if !confirmed.Ack {
		return fmt.Errorf("Failed delivery of delivery tag: %v", confirmed.DeliveryTag)
	}

	return nil
}

func amqmChordTriggeredQueue(groupUUID string) string {
	return fmt.Sprintf("%s_chord_triggered", groupUUID)
}


================================================
FILE: v1/backends/amqp/amqp_test.go
================================================
package amqp_test

import (
	"os"
	"testing"
	"time"

	"github.com/RichardKnop/machinery/v1/backends/amqp"
	"github.com/RichardKnop/machinery/v1/config"
	"github.com/RichardKnop/machinery/v1/tasks"
	"github.com/stretchr/testify/assert"
)

var (
	amqpConfig *config.Config
)

func init() {
	amqpURL := os.Getenv("AMQP_URL")
	if amqpURL == "" {
		return
	}

	finalAmqpURL := amqpURL
	var finalSeparator string

	amqpURLs := os.Getenv("AMQP_URLS")
	if amqpURLs != "" {
		separator := os.Getenv("AMQP_URLS_SEPARATOR")
		if separator == "" {
			return
		}
		finalSeparator = separator
		finalAmqpURL = amqpURLs
	}

	amqp2URL := os.Getenv("AMQP2_URL")
	if amqp2URL == "" {
		amqp2URL = amqpURL
	}

	amqpConfig = &config.Config{
		Broker:                  finalAmqpURL,
		MultipleBrokerSeparator: finalSeparator,
		DefaultQueue:            "test_queue",
		ResultBackend:           amqp2URL,
		AMQP: &config.AMQPConfig{
			Exchange:      "test_exchange",
			ExchangeType:  "direct",
			BindingKey:    "test_task",
			PrefetchCount: 1,
		},
	}
}

func TestGroupCompleted(t *testing.T) {
	if os.Getenv("AMQP_URL") == "" {
		t.Skip("AMQP_URL is not defined")
	}

	groupUUID := "testGroupUUID"
	groupTaskCount := 2
	task1 := &tasks.Signature{
		UUID:           "testTaskUUID1",
		GroupUUID:      groupUUID,
		GroupTaskCount: groupTaskCount,
	}
	task2 := &tasks.Signature{
		UUID:           "testTaskUUID2",
		GroupUUID:      groupUUID,
		GroupTaskCount: groupTaskCount,
	}

	backend := amqp.New(amqpConfig)

	// Cleanup before the test
	backend.PurgeState(task1.UUID)
	backend.PurgeState(task2.UUID)
	backend.PurgeGroupMeta(groupUUID)

	groupCompleted, err := backend.GroupCompleted(groupUUID, groupTaskCount)
	if assert.NoError(t, err) {
		assert.False(t, groupCompleted)
	}

	backend.InitGroup(groupUUID, []string{task1.UUID, task2.UUID})

	groupCompleted, err = backend.GroupCompleted(groupUUID, groupTaskCount)
	if assert.NoError(t, err) {
		assert.False(t, groupCompleted)
	}

	backend.SetStatePending(task1)
	backend.SetStateStarted(task2)
	groupCompleted, err = backend.GroupCompleted(groupUUID, groupTaskCount)
	if assert.NoError(t, err) {
		assert.False(t, groupCompleted)
	}

	taskResults := []*tasks.TaskResult{new(tasks.TaskResult)}
	backend.SetStateSuccess(task1, taskResults)
	backend.SetStateSuccess(task2, taskResults)
	groupCompleted, err = backend.GroupCompleted(groupUUID, groupTaskCount)
	if assert.NoError(t, err) {
		assert.True(t, groupCompleted)
	}
}

func TestGetState(t *testing.T) {
	if os.Getenv("AMQP_URL") == "" {
		t.Skip("AMQP_URL is not defined")
	}

	signature := &tasks.Signature{
		UUID:      "testTaskUUID",
		GroupUUID: "testGroupUUID",
	}

	go func() {
		backend := amqp.New(amqpConfig)
		backend.SetStatePending(signature)
		time.Sleep(2 * time.Millisecond)
		backend.SetStateReceived(signature)
		time.Sleep(2 * time.Millisecond)
		backend.SetStateStarted(signature)
		time.Sleep(2 * time.Millisecond)

		taskResults := []*tasks.TaskResult{
			{
				Type:  "float64",
				Value: 2,
			},
		}
		backend.SetStateSuccess(signature, taskResults)
	}()

	backend := amqp.New(amqpConfig)

	var (
		taskState *tasks.TaskState
		err       error
	)
	for {
		taskState, err = backend.GetState(signature.UUID)
		if taskState == nil {
			assert.Equal(t, "No state ready", err.Error())
			continue
		}

		assert.NoError(t, err)
		if taskState.IsCompleted() {
			break
		}
	}
}

func TestPurgeState(t *testing.T) {
	if os.Getenv("AMQP_URL") == "" {
		t.Skip("AMQP_URL is not defined")
	}

	signature := &tasks.Signature{
		UUID:      "testTaskUUID",
		GroupUUID: "testGroupUUID",
	}

	backend := amqp.New(amqpConfig)

	backend.SetStatePending(signature)
	backend.SetStateReceived(signature)
	taskState, err := backend.GetState(signature.UUID)
	assert.NotNil(t, taskState)
	assert.NoError(t, err)

	backend.PurgeState(taskState.TaskUUID)
	taskState, err = backend.GetState(signature.UUID)
	assert.Nil(t, taskState)
	assert.Error(t, err)
}


================================================
FILE: v1/backends/dynamodb/dynamodb.go
================================================
package dynamodb

import (
	"errors"
	"fmt"
	"math"
	"time"

	"github.com/aws/aws-sdk-go/aws/session"

	"github.com/RichardKnop/machinery/v1/backends/iface"
	"github.com/RichardKnop/machinery/v1/common"
	"github.com/RichardKnop/machinery/v1/config"
	"github.com/RichardKnop/machinery/v1/log"
	"github.com/RichardKnop/machinery/v1/tasks"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/dynamodb"
	"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
	"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbiface"
)

const (
	BatchItemsLimit  = 99
	MaxFetchAttempts = 3
)

// Backend ...
type Backend struct {
	common.Backend
	cnf    *config.Config
	client dynamodbiface.DynamoDBAPI
}

// New creates a Backend instance
func New(cnf *config.Config) iface.Backend {
	backend := &Backend{Backend: common.NewBackend(cnf), cnf: cnf}

	if cnf.DynamoDB != nil && cnf.DynamoDB.Client != nil {
		backend.client = cnf.DynamoDB.Client
	} else {
		sess := session.Must(session.NewSessionWithOptions(session.Options{
			SharedConfigState: session.SharedConfigEnable,
		}))
		backend.client = dynamodb.New(sess)
	}

	// Check if needed tables exist
	err := backend.checkRequiredTablesIfExist()
	if err != nil {
		log.FATAL.Printf("Failed to prepare tables. Error: %v", err)
	}
	return backend
}

// InitGroup ...
func (b *Backend) InitGroup(groupUUID string, taskUUIDs []string) error {
	meta := tasks.GroupMeta{
		GroupUUID: groupUUID,
		TaskUUIDs: taskUUIDs,
		Created
Download .txt
gitextract_kvdc2vnc/

├── .deepsource.toml
├── .gitignore
├── .travis.yml
├── Dockerfile.gcppubsub
├── Dockerfile.test
├── LICENSE
├── Makefile
├── README.md
├── docker-compose.test.yml
├── example/
│   ├── amqp/
│   │   └── main.go
│   ├── redis/
│   │   └── main.go
│   ├── tasks/
│   │   └── tasks.go
│   └── tracers/
│       └── jaeger.go
├── go.mod
├── go.sum
├── instruction-notes/
│   └── dynamodb.md
├── integration-tests/
│   ├── amqp_amqp_test.go
│   ├── amqp_get_pending_tasks_test.go
│   ├── amqp_memcache_test.go
│   ├── amqp_mongodb_test.go
│   ├── amqp_redis_test.go
│   ├── eager_eager_test.go
│   ├── gcppubsub_redis_test.go
│   ├── redis_get_pending_tasks_test.go
│   ├── redis_memcache_test.go
│   ├── redis_mongodb_test.go
│   ├── redis_redis_test.go
│   ├── redis_socket_test.go
│   ├── sqs_amqp_test.go
│   ├── sqs_mongodb_test.go
│   ├── suite_test.go
│   └── worker_only_consumes_registered_tasks_test.go
├── v1/
│   ├── backends/
│   │   ├── amqp/
│   │   │   ├── amqp.go
│   │   │   └── amqp_test.go
│   │   ├── dynamodb/
│   │   │   ├── dynamodb.go
│   │   │   ├── dynamodb_export_test.go
│   │   │   └── dynamodb_test.go
│   │   ├── eager/
│   │   │   ├── eager.go
│   │   │   └── eager_test.go
│   │   ├── iface/
│   │   │   └── interfaces.go
│   │   ├── memcache/
│   │   │   ├── memcache.go
│   │   │   └── memcache_test.go
│   │   ├── mongo/
│   │   │   ├── mongodb.go
│   │   │   └── mongodb_test.go
│   │   ├── null/
│   │   │   └── null.go
│   │   ├── package.go
│   │   ├── redis/
│   │   │   ├── goredis.go
│   │   │   ├── goredis_test.go
│   │   │   ├── redis.go
│   │   │   └── redis_test.go
│   │   └── result/
│   │       └── async_result.go
│   ├── brokers/
│   │   ├── amqp/
│   │   │   ├── amqp.go
│   │   │   ├── amqp_concurrence_test.go
│   │   │   └── amqp_test.go
│   │   ├── eager/
│   │   │   └── eager.go
│   │   ├── errs/
│   │   │   └── errors.go
│   │   ├── gcppubsub/
│   │   │   └── gcp_pubsub.go
│   │   ├── iface/
│   │   │   └── interfaces.go
│   │   ├── package.go
│   │   ├── redis/
│   │   │   ├── goredis.go
│   │   │   └── redis.go
│   │   └── sqs/
│   │       ├── sqs.go
│   │       ├── sqs_export_test.go
│   │       └── sqs_test.go
│   ├── common/
│   │   ├── amqp.go
│   │   ├── backend.go
│   │   ├── broker.go
│   │   ├── broker_test.go
│   │   └── redis.go
│   ├── config/
│   │   ├── config.go
│   │   ├── env.go
│   │   ├── env_test.go
│   │   ├── file.go
│   │   ├── file_test.go
│   │   ├── test.env
│   │   └── testconfig.yml
│   ├── factories.go
│   ├── factories_test.go
│   ├── locks/
│   │   ├── eager/
│   │   │   ├── eager.go
│   │   │   └── eager_test.go
│   │   ├── iface/
│   │   │   └── interfaces.go
│   │   └── redis/
│   │       └── redis.go
│   ├── log/
│   │   ├── log.go
│   │   └── log_test.go
│   ├── package.go
│   ├── retry/
│   │   ├── fibonacci.go
│   │   ├── fibonacci_test.go
│   │   └── retry.go
│   ├── server.go
│   ├── server_test.go
│   ├── tasks/
│   │   ├── errors.go
│   │   ├── reflect.go
│   │   ├── reflect_test.go
│   │   ├── result.go
│   │   ├── result_test.go
│   │   ├── signature.go
│   │   ├── state.go
│   │   ├── state_test.go
│   │   ├── task.go
│   │   ├── task_test.go
│   │   ├── validate.go
│   │   ├── validate_test.go
│   │   ├── workflow.go
│   │   └── workflow_test.go
│   ├── tracing/
│   │   └── tracing.go
│   ├── utils/
│   │   ├── deepcopy.go
│   │   ├── deepcopy_test.go
│   │   ├── utils.go
│   │   ├── utils_test.go
│   │   ├── uuid.go
│   │   └── uuid_test.go
│   ├── worker.go
│   └── worker_test.go
├── v2/
│   ├── Dockerfile.test
│   ├── Makefile
│   ├── backends/
│   │   ├── amqp/
│   │   │   ├── amqp.go
│   │   │   └── amqp_test.go
│   │   ├── dynamodb/
│   │   │   ├── dynamodb.go
│   │   │   ├── dynamodb_export_test.go
│   │   │   └── dynamodb_test.go
│   │   ├── eager/
│   │   │   ├── eager.go
│   │   │   └── eager_test.go
│   │   ├── iface/
│   │   │   ├── dynamodb/
│   │   │   │   └── api.go
│   │   │   └── interfaces.go
│   │   ├── memcache/
│   │   │   ├── memcache.go
│   │   │   └── memcache_test.go
│   │   ├── mongo/
│   │   │   ├── mongodb.go
│   │   │   └── mongodb_test.go
│   │   ├── null/
│   │   │   └── null.go
│   │   ├── package.go
│   │   ├── redis/
│   │   │   ├── goredis.go
│   │   │   ├── goredis_test.go
│   │   │   ├── redis.go
│   │   │   └── redis_test.go
│   │   └── result/
│   │       └── async_result.go
│   ├── brokers/
│   │   ├── amqp/
│   │   │   ├── amqp.go
│   │   │   ├── amqp_concurrence_test.go
│   │   │   └── amqp_test.go
│   │   ├── eager/
│   │   │   └── eager.go
│   │   ├── errs/
│   │   │   └── errors.go
│   │   ├── gcppubsub/
│   │   │   └── gcp_pubsub.go
│   │   ├── iface/
│   │   │   ├── interfaces.go
│   │   │   └── sqs/
│   │   │       └── api.go
│   │   ├── package.go
│   │   ├── redis/
│   │   │   ├── goredis.go
│   │   │   └── redis.go
│   │   └── sqs/
│   │       ├── sqs.go
│   │       ├── sqs_export_test.go
│   │       └── sqs_test.go
│   ├── common/
│   │   ├── amqp.go
│   │   ├── backend.go
│   │   ├── broker.go
│   │   ├── broker_test.go
│   │   └── redis.go
│   ├── config/
│   │   ├── config.go
│   │   ├── env.go
│   │   ├── env_test.go
│   │   ├── file.go
│   │   ├── file_test.go
│   │   ├── test.env
│   │   └── testconfig.yml
│   ├── docker-compose.test.yml
│   ├── example/
│   │   ├── amqp/
│   │   │   └── main.go
│   │   ├── go-redis/
│   │   │   └── main.go
│   │   ├── redigo/
│   │   │   └── main.go
│   │   ├── tasks/
│   │   │   └── tasks.go
│   │   └── tracers/
│   │       └── jaeger.go
│   ├── go.mod
│   ├── go.sum
│   ├── integration-tests/
│   │   ├── amqp_amqp_test.go
│   │   ├── redis_redis_test.go
│   │   └── suite_test.go
│   ├── locks/
│   │   ├── eager/
│   │   │   ├── eager.go
│   │   │   └── eager_test.go
│   │   ├── iface/
│   │   │   └── interfaces.go
│   │   └── redis/
│   │       └── redis.go
│   ├── log/
│   │   ├── log.go
│   │   └── log_test.go
│   ├── package.go
│   ├── retry/
│   │   ├── fibonacci.go
│   │   ├── fibonacci_test.go
│   │   └── retry.go
│   ├── server.go
│   ├── server_test.go
│   ├── tasks/
│   │   ├── errors.go
│   │   ├── reflect.go
│   │   ├── reflect_test.go
│   │   ├── result.go
│   │   ├── result_test.go
│   │   ├── signature.go
│   │   ├── state.go
│   │   ├── state_test.go
│   │   ├── task.go
│   │   ├── task_test.go
│   │   ├── validate.go
│   │   ├── validate_test.go
│   │   ├── workflow.go
│   │   └── workflow_test.go
│   ├── tracing/
│   │   └── tracing.go
│   ├── utils/
│   │   ├── deepcopy.go
│   │   ├── deepcopy_test.go
│   │   ├── utils.go
│   │   ├── utils_test.go
│   │   ├── uuid.go
│   │   └── uuid_test.go
│   ├── wait-for-it.sh
│   ├── worker.go
│   └── worker_test.go
└── wait-for-it.sh
Download .txt
SYMBOL INDEX (1445 symbols across 178 files)

FILE: example/amqp/main.go
  function init (line 28) | func init() {
  function main (line 36) | func main() {
  function startServer (line 65) | func startServer() (*machinery.Server, error) {
  function worker (line 99) | func worker() error {
  function send (line 138) | func send() error {

FILE: example/redis/main.go
  function init (line 28) | func init() {
  function main (line 36) | func main() {
  function startServer (line 65) | func startServer() (*machinery.Server, error) {
  function worker (line 102) | func worker() error {
  function send (line 141) | func send() error {

FILE: example/tasks/tasks.go
  function Add (line 12) | func Add(args ...int64) (int64, error) {
  function Multiply (line 21) | func Multiply(args ...int64) (int64, error) {
  function SumInts (line 30) | func SumInts(numbers []int64) (int64, error) {
  function SumFloats (line 39) | func SumFloats(numbers []float64) (float64, error) {
  function Concat (line 48) | func Concat(strs []string) (string, error) {
  function Split (line 57) | func Split(str string) ([]string, error) {
  function PanicTask (line 62) | func PanicTask() (string, error) {
  function LongRunningTask (line 67) | func LongRunningTask() error {

FILE: example/tracers/jaeger.go
  function SetupTracer (line 20) | func SetupTracer(serviceName string) (func(), error) {

FILE: integration-tests/amqp_amqp_test.go
  function TestAmqpAmqp (line 11) | func TestAmqpAmqp(t *testing.T) {

FILE: integration-tests/amqp_get_pending_tasks_test.go
  function TestAmqpGetPendingTasks (line 15) | func TestAmqpGetPendingTasks(t *testing.T) {
  function compareSigs (line 99) | func compareSigs(t *testing.T, a *tasks.Signature, b *tasks.Signature) {

FILE: integration-tests/amqp_memcache_test.go
  function TestAmqpMemcache (line 12) | func TestAmqpMemcache(t *testing.T) {

FILE: integration-tests/amqp_mongodb_test.go
  function TestAmqpMongodb (line 12) | func TestAmqpMongodb(t *testing.T) {

FILE: integration-tests/amqp_redis_test.go
  function TestAmqpRedis (line 12) | func TestAmqpRedis(t *testing.T) {

FILE: integration-tests/eager_eager_test.go
  type EagerIntegrationTestSuite (line 14) | type EagerIntegrationTestSuite struct
    method SetupSuite (line 25) | func (s *EagerIntegrationTestSuite) SetupSuite() {
    method TestCalled (line 54) | func (s *EagerIntegrationTestSuite) TestCalled() {
    method TestSuccessResult (line 69) | func (s *EagerIntegrationTestSuite) TestSuccessResult() {
  function TestEagerIntegrationTestSuite (line 21) | func TestEagerIntegrationTestSuite(t *testing.T) {

FILE: integration-tests/gcppubsub_redis_test.go
  function createGCPPubSubTopicAndSubscription (line 16) | func createGCPPubSubTopicAndSubscription(cli *pubsub.Client, topicName, ...
  function TestGCPPubSubRedis (line 53) | func TestGCPPubSubRedis(t *testing.T) {

FILE: integration-tests/redis_get_pending_tasks_test.go
  function TestRedisGetPendingTasks (line 11) | func TestRedisGetPendingTasks(t *testing.T) {

FILE: integration-tests/redis_memcache_test.go
  function TestRedisMemcache (line 12) | func TestRedisMemcache(t *testing.T) {

FILE: integration-tests/redis_mongodb_test.go
  function TestRedisMongodb (line 12) | func TestRedisMongodb(t *testing.T) {

FILE: integration-tests/redis_redis_test.go
  function TestRedisRedis_Redigo (line 14) | func TestRedisRedis_Redigo(t *testing.T) {
  function TestRedisRedisNormalTaskPollPeriodLessThan1SecondShouldNotFailNextTask (line 34) | func TestRedisRedisNormalTaskPollPeriodLessThan1SecondShouldNotFailNextT...
  function TestRedisRedisWorkerQuitRaceCondition (line 57) | func TestRedisRedisWorkerQuitRaceCondition(t *testing.T) {
  function TestRedisRedisWorkerQuickQuit (line 90) | func TestRedisRedisWorkerQuickQuit(t *testing.T) {
  function TestRedisRedisWorkerPreConsumeHandler (line 128) | func TestRedisRedisWorkerPreConsumeHandler(t *testing.T) {

FILE: integration-tests/redis_socket_test.go
  function TestRedisSocket (line 12) | func TestRedisSocket(t *testing.T) {

FILE: integration-tests/sqs_amqp_test.go
  function TestSQSAmqp (line 11) | func TestSQSAmqp(t *testing.T) {

FILE: integration-tests/sqs_mongodb_test.go
  function TestSQSMongodb (line 12) | func TestSQSMongodb(t *testing.T) {

FILE: integration-tests/suite_test.go
  type ascendingInt64s (line 22) | type ascendingInt64s
    method Len (line 24) | func (a ascendingInt64s) Len() int           { return len(a) }
    method Swap (line 25) | func (a ascendingInt64s) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
    method Less (line 26) | func (a ascendingInt64s) Less(i, j int) bool { return a[i] < a[j] }
  type Server (line 28) | type Server interface
  function testAll (line 42) | func testAll(server Server, t *testing.T) {
  function testSendTask (line 54) | func testSendTask(server Server, t *testing.T) {
  function testSendGroup (line 103) | func testSendGroup(server Server, t *testing.T, sendConcurrency int) {
  function testSendChain (line 148) | func testSendChain(server Server, t *testing.T) {
  function testSendChord (line 179) | func testSendChord(server Server, t *testing.T) {
  function testReturnJustError (line 215) | func testReturnJustError(server Server, t *testing.T) {
  function testReturnMultipleValues (line 243) | func testReturnMultipleValues(server Server, t *testing.T) {
  function testPanic (line 292) | func testPanic(server Server, t *testing.T) {
  function testDelay (line 306) | func testDelay(server Server, t *testing.T) {
  function registerTestTasks (line 343) | func registerTestTasks(server Server) {
  function testSetup (line 393) | func testSetup(cnf *config.Config) Server {
  function newAddTask (line 405) | func newAddTask(a, b int) *tasks.Signature {
  function newMultipleTask (line 421) | func newMultipleTask(nums ...int) *tasks.Signature {
  function newSumTask (line 435) | func newSumTask(nums []int64) *tasks.Signature {
  function newErrorTask (line 447) | func newErrorTask(msg string, fail bool) *tasks.Signature {
  function newMultipleReturnTask (line 463) | func newMultipleReturnTask(arg1, arg2 string, fail bool) *tasks.Signature {
  function newDelayTask (line 483) | func newDelayTask(eta time.Time) *tasks.Signature {

FILE: integration-tests/worker_only_consumes_registered_tasks_test.go
  function TestWorkerOnlyConsumesRegisteredTaskAMQP (line 16) | func TestWorkerOnlyConsumesRegisteredTaskAMQP(t *testing.T) {
  function TestWorkerOnlyConsumesRegisteredTaskRedis (line 138) | func TestWorkerOnlyConsumesRegisteredTaskRedis(t *testing.T) {

FILE: v1/backends/amqp/amqp.go
  type Backend (line 32) | type Backend struct
    method InitGroup (line 43) | func (b *Backend) InitGroup(groupUUID string, taskUUIDs []string) error {
    method GroupCompleted (line 50) | func (b *Backend) GroupCompleted(groupUUID string, groupTaskCount int)...
    method GroupTaskStates (line 66) | func (b *Backend) GroupTaskStates(groupUUID string, groupTaskCount int...
    method TriggerChord (line 119) | func (b *Backend) TriggerChord(groupUUID string) (bool, error) {
    method SetStatePending (line 135) | func (b *Backend) SetStatePending(signature *tasks.Signature) error {
    method SetStateReceived (line 141) | func (b *Backend) SetStateReceived(signature *tasks.Signature) error {
    method SetStateStarted (line 147) | func (b *Backend) SetStateStarted(signature *tasks.Signature) error {
    method SetStateRetry (line 153) | func (b *Backend) SetStateRetry(signature *tasks.Signature) error {
    method SetStateSuccess (line 159) | func (b *Backend) SetStateSuccess(signature *tasks.Signature, results ...
    method SetStateFailure (line 174) | func (b *Backend) SetStateFailure(signature *tasks.Signature, err stri...
    method GetState (line 190) | func (b *Backend) GetState(taskUUID string) (*tasks.TaskState, error) {
    method PurgeState (line 243) | func (b *Backend) PurgeState(taskUUID string) error {
    method PurgeGroupMeta (line 254) | func (b *Backend) PurgeGroupMeta(groupUUID string) error {
    method updateState (line 267) | func (b *Backend) updateState(taskState *tasks.TaskState) error {
    method getExpiresIn (line 323) | func (b *Backend) getExpiresIn() int {
    method markTaskCompleted (line 335) | func (b *Backend) markTaskCompleted(signature *tasks.Signature, taskSt...
  function New (line 38) | func New(cnf *config.Config) iface.Backend {
  function amqmChordTriggeredQueue (line 394) | func amqmChordTriggeredQueue(groupUUID string) string {

FILE: v1/backends/amqp/amqp_test.go
  function init (line 18) | func init() {
  function TestGroupCompleted (line 56) | func TestGroupCompleted(t *testing.T) {
  function TestGetState (line 109) | func TestGetState(t *testing.T) {
  function TestPurgeState (line 157) | func TestPurgeState(t *testing.T) {

FILE: v1/backends/dynamodb/dynamodb.go
  constant BatchItemsLimit (line 23) | BatchItemsLimit  = 99
  constant MaxFetchAttempts (line 24) | MaxFetchAttempts = 3
  type Backend (line 28) | type Backend struct
    method InitGroup (line 56) | func (b *Backend) InitGroup(groupUUID string, taskUUIDs []string) error {
    method GroupCompleted (line 82) | func (b *Backend) GroupCompleted(groupUUID string, groupTaskCount int)...
    method GroupTaskStates (line 103) | func (b *Backend) GroupTaskStates(groupUUID string, groupTaskCount int...
    method TriggerChord (line 113) | func (b *Backend) TriggerChord(groupUUID string) (bool, error) {
    method SetStatePending (line 148) | func (b *Backend) SetStatePending(signature *tasks.Signature) error {
    method SetStateReceived (line 155) | func (b *Backend) SetStateReceived(signature *tasks.Signature) error {
    method SetStateStarted (line 161) | func (b *Backend) SetStateStarted(signature *tasks.Signature) error {
    method SetStateRetry (line 167) | func (b *Backend) SetStateRetry(signature *tasks.Signature) error {
    method SetStateSuccess (line 173) | func (b *Backend) SetStateSuccess(signature *tasks.Signature, results ...
    method SetStateFailure (line 180) | func (b *Backend) SetStateFailure(signature *tasks.Signature, err stri...
    method GetState (line 187) | func (b *Backend) GetState(taskUUID string) (*tasks.TaskState, error) {
    method getStates (line 205) | func (b *Backend) getStates(tasksToFetch []string) ([]*tasks.TaskState...
    method batchFetchTaskStates (line 241) | func (b *Backend) batchFetchTaskStates(taskUUIDs []string) ([]*tasks.T...
    method PurgeState (line 289) | func (b *Backend) PurgeState(taskUUID string) error {
    method PurgeGroupMeta (line 307) | func (b *Backend) PurgeGroupMeta(groupUUID string) error {
    method getGroupMeta (line 324) | func (b *Backend) getGroupMeta(groupUUID string) (*tasks.GroupMeta, er...
    method lockGroupMeta (line 346) | func (b *Backend) lockGroupMeta(groupUUID string) error {
    method unlockGroupMeta (line 354) | func (b *Backend) unlockGroupMeta(groupUUID string) error {
    method updateGroupMetaLock (line 362) | func (b *Backend) updateGroupMetaLock(groupUUID string, status bool) e...
    method chordTriggered (line 390) | func (b *Backend) chordTriggered(groupUUID string) error {
    method setTaskState (line 418) | func (b *Backend) setTaskState(taskState *tasks.TaskState) error {
    method initTaskState (line 486) | func (b *Backend) initTaskState(taskState *tasks.TaskState) error {
    method updateToFailureStateWithError (line 503) | func (b *Backend) updateToFailureStateWithError(taskState *tasks.TaskS...
    method unmarshalGroupMetaGetItemResult (line 543) | func (b *Backend) unmarshalGroupMetaGetItemResult(result *dynamodb.Get...
    method unmarshalTaskStateGetItemResult (line 558) | func (b *Backend) unmarshalTaskStateGetItemResult(result *dynamodb.Get...
    method checkRequiredTablesIfExist (line 573) | func (b *Backend) checkRequiredTablesIfExist() error {
    method tableExists (line 603) | func (b *Backend) tableExists(tableName string, tableNames []*string) ...
    method getExpirationTime (line 612) | func (b *Backend) getExpirationTime() int64 {
  function New (line 35) | func New(cnf *config.Config) iface.Backend {
  function getUnfetchedKeys (line 622) | func getUnfetchedKeys(unprocessed *dynamodb.KeysAndAttributes) ([]string...
  function chunkTasks (line 635) | func chunkTasks(array []string, chunkSize int) [][]string {
  function min (line 646) | func min(a, b int) int {

FILE: v1/backends/dynamodb/dynamodb_export_test.go
  type TestDynamoDBClient (line 26) | type TestDynamoDBClient struct
    method ResetOverrides (line 34) | func (t *TestDynamoDBClient) ResetOverrides() {
    method PutItem (line 40) | func (t *TestDynamoDBClient) PutItem(input *dynamodb.PutItemInput) (*d...
    method BatchGetItem (line 46) | func (t *TestDynamoDBClient) BatchGetItem(input *dynamodb.BatchGetItem...
    method GetItem (line 53) | func (t *TestDynamoDBClient) GetItem(input *dynamodb.GetItemInput) (*d...
    method DeleteItem (line 125) | func (t *TestDynamoDBClient) DeleteItem(*dynamodb.DeleteItemInput) (*d...
    method UpdateItem (line 129) | func (t *TestDynamoDBClient) UpdateItem(input *dynamodb.UpdateItemInpu...
    method ListTables (line 136) | func (t *TestDynamoDBClient) ListTables(*dynamodb.ListTablesInput) (*d...
  type TestErrDynamoDBClient (line 146) | type TestErrDynamoDBClient struct
    method PutItem (line 150) | func (t *TestErrDynamoDBClient) PutItem(*dynamodb.PutItemInput) (*dyna...
    method GetItem (line 154) | func (t *TestErrDynamoDBClient) GetItem(*dynamodb.GetItemInput) (*dyna...
    method DeleteItem (line 158) | func (t *TestErrDynamoDBClient) DeleteItem(*dynamodb.DeleteItemInput) ...
    method Scan (line 162) | func (t *TestErrDynamoDBClient) Scan(*dynamodb.ScanInput) (*dynamodb.S...
    method UpdateItem (line 166) | func (t *TestErrDynamoDBClient) UpdateItem(*dynamodb.UpdateItemInput) ...
    method ListTables (line 170) | func (t *TestErrDynamoDBClient) ListTables(*dynamodb.ListTablesInput) ...
  function init (line 174) | func init() {
  method GetConfig (line 195) | func (b *Backend) GetConfig() *config.Config {
  method GetClient (line 199) | func (b *Backend) GetClient() dynamodbiface.DynamoDBAPI {
  method GetGroupMetaForTest (line 203) | func (b *Backend) GetGroupMetaForTest(groupUUID string) (*tasks.GroupMet...
  method UnmarshalGroupMetaGetItemResultForTest (line 207) | func (b *Backend) UnmarshalGroupMetaGetItemResultForTest(result *dynamod...
  method UnmarshalTaskStateGetItemResultForTest (line 211) | func (b *Backend) UnmarshalTaskStateGetItemResultForTest(result *dynamod...
  method SetTaskStateForTest (line 215) | func (b *Backend) SetTaskStateForTest(taskState *tasks.TaskState) error {
  method ChordTriggeredForTest (line 219) | func (b *Backend) ChordTriggeredForTest(groupUUID string) error {
  method UpdateGroupMetaLockForTest (line 223) | func (b *Backend) UpdateGroupMetaLockForTest(groupUUID string, status bo...
  method UnlockGroupMetaForTest (line 227) | func (b *Backend) UnlockGroupMetaForTest(groupUUID string) error {
  method LockGroupMetaForTest (line 231) | func (b *Backend) LockGroupMetaForTest(groupUUID string) error {
  method GetStatesForTest (line 235) | func (b *Backend) GetStatesForTest(taskUUIDs ...string) ([]*tasks.TaskSt...
  method UpdateToFailureStateWithErrorForTest (line 239) | func (b *Backend) UpdateToFailureStateWithErrorForTest(taskState *tasks....
  method TableExistsForTest (line 243) | func (b *Backend) TableExistsForTest(tableName string, tableNames []*str...
  method CheckRequiredTablesIfExistForTest (line 247) | func (b *Backend) CheckRequiredTablesIfExistForTest() error {

FILE: v1/backends/dynamodb/dynamodb_test.go
  function TestNew (line 18) | func TestNew(t *testing.T) {
  function TestInitGroup (line 24) | func TestInitGroup(t *testing.T) {
  function assertTTLValue (line 56) | func assertTTLValue(t *testing.T, expectedTTLTime time.Time, actualEncod...
  function TestGroupCompleted (line 63) | func TestGroupCompleted(t *testing.T) {
  function TestGroupCompletedReturnsError (line 90) | func TestGroupCompletedReturnsError(t *testing.T) {
  function TestGroupCompletedReturnsFalse (line 102) | func TestGroupCompletedReturnsFalse(t *testing.T) {
  function TestGroupCompletedRetries (line 124) | func TestGroupCompletedRetries(t *testing.T) {
  function TestGroupCompletedRetrieSuccess (line 155) | func TestGroupCompletedRetrieSuccess(t *testing.T) {
  function TestPrivateFuncGetGroupMeta (line 200) | func TestPrivateFuncGetGroupMeta(t *testing.T) {
  function TestPrivateFuncUnmarshalTaskStateGetItemResult (line 219) | func TestPrivateFuncUnmarshalTaskStateGetItemResult(t *testing.T) {
  function TestPrivateFuncUnmarshalGroupMetaGetItemResult (line 272) | func TestPrivateFuncUnmarshalGroupMetaGetItemResult(t *testing.T) {
  function TestPrivateFuncSetTaskState (line 348) | func TestPrivateFuncSetTaskState(t *testing.T) {
  function verifyUpdateInput (line 366) | func verifyUpdateInput(t *testing.T, input *awsdynamodb.UpdateItemInput,...
  function TestSetStateSuccess (line 382) | func TestSetStateSuccess(t *testing.T) {
  function TestSetStateFailure (line 402) | func TestSetStateFailure(t *testing.T) {
  function TestSetStateReceived (line 422) | func TestSetStateReceived(t *testing.T) {
  function TestSetStateStarted (line 441) | func TestSetStateStarted(t *testing.T) {
  function TestSetStateRetry (line 460) | func TestSetStateRetry(t *testing.T) {
  function TestGroupTaskStates (line 479) | func TestGroupTaskStates(t *testing.T) {
  function TestTriggerChord (line 538) | func TestTriggerChord(t *testing.T) {
  function TestGetState (line 545) | func TestGetState(t *testing.T) {
  function TestPurgeState (line 571) | func TestPurgeState(t *testing.T) {
  function TestPurgeGroupMeta (line 580) | func TestPurgeGroupMeta(t *testing.T) {
  function TestPrivateFuncLockGroupMeta (line 589) | func TestPrivateFuncLockGroupMeta(t *testing.T) {
  function TestPrivateFuncUnLockGroupMeta (line 597) | func TestPrivateFuncUnLockGroupMeta(t *testing.T) {
  function TestPrivateFuncChordTriggered (line 605) | func TestPrivateFuncChordTriggered(t *testing.T) {
  function TestDynamoDBPrivateFuncUpdateGroupMetaLock (line 613) | func TestDynamoDBPrivateFuncUpdateGroupMetaLock(t *testing.T) {
  function TestPrivateFuncUpdateToFailureStateWithError (line 621) | func TestPrivateFuncUpdateToFailureStateWithError(t *testing.T) {
  function TestPrivateFuncTableExistsForTest (line 637) | func TestPrivateFuncTableExistsForTest(t *testing.T) {
  function TestPrivateFuncCheckRequiredTablesIfExistForTest (line 643) | func TestPrivateFuncCheckRequiredTablesIfExistForTest(t *testing.T) {

FILE: v1/backends/eager/eager.go
  type ErrGroupNotFound (line 16) | type ErrGroupNotFound struct
    method Error (line 26) | func (e ErrGroupNotFound) Error() string {
  function NewErrGroupNotFound (line 21) | func NewErrGroupNotFound(groupUUID string) ErrGroupNotFound {
  type ErrTasknotFound (line 31) | type ErrTasknotFound struct
    method Error (line 41) | func (e ErrTasknotFound) Error() string {
  function NewErrTasknotFound (line 36) | func NewErrTasknotFound(taskUUID string) ErrTasknotFound {
  type Backend (line 46) | type Backend struct
    method InitGroup (line 63) | func (b *Backend) InitGroup(groupUUID string, taskUUIDs []string) error {
    method GroupCompleted (line 73) | func (b *Backend) GroupCompleted(groupUUID string, groupTaskCount int)...
    method GroupTaskStates (line 95) | func (b *Backend) GroupTaskStates(groupUUID string, groupTaskCount int...
    method TriggerChord (line 118) | func (b *Backend) TriggerChord(groupUUID string) (bool, error) {
    method SetStatePending (line 123) | func (b *Backend) SetStatePending(signature *tasks.Signature) error {
    method SetStateReceived (line 129) | func (b *Backend) SetStateReceived(signature *tasks.Signature) error {
    method SetStateStarted (line 135) | func (b *Backend) SetStateStarted(signature *tasks.Signature) error {
    method SetStateRetry (line 141) | func (b *Backend) SetStateRetry(signature *tasks.Signature) error {
    method SetStateSuccess (line 147) | func (b *Backend) SetStateSuccess(signature *tasks.Signature, results ...
    method SetStateFailure (line 153) | func (b *Backend) SetStateFailure(signature *tasks.Signature, err stri...
    method GetState (line 159) | func (b *Backend) GetState(taskUUID string) (*tasks.TaskState, error) {
    method PurgeState (line 176) | func (b *Backend) PurgeState(taskUUID string) error {
    method PurgeGroupMeta (line 187) | func (b *Backend) PurgeGroupMeta(groupUUID string) error {
    method updateState (line 197) | func (b *Backend) updateState(s *tasks.TaskState) error {
  function New (line 54) | func New() iface.Backend {

FILE: v1/backends/eager/eager_test.go
  type EagerBackendTestSuite (line 13) | type EagerBackendTestSuite struct
    method SetupSuite (line 24) | func (s *EagerBackendTestSuite) SetupSuite() {
    method TestInitGroup (line 78) | func (s *EagerBackendTestSuite) TestInitGroup() {
    method TestGroupCompleted (line 92) | func (s *EagerBackendTestSuite) TestGroupCompleted() {
    method TestGroupTaskStates (line 149) | func (s *EagerBackendTestSuite) TestGroupTaskStates() {
    method TestSetStatePending (line 182) | func (s *EagerBackendTestSuite) TestSetStatePending() {
    method TestSetStateReceived (line 201) | func (s *EagerBackendTestSuite) TestSetStateReceived() {
    method TestSetStateStarted (line 214) | func (s *EagerBackendTestSuite) TestSetStateStarted() {
    method TestSetStateSuccess (line 227) | func (s *EagerBackendTestSuite) TestSetStateSuccess() {
    method TestSetStateFailure (line 247) | func (s *EagerBackendTestSuite) TestSetStateFailure() {
    method TestSetStateRetry (line 261) | func (s *EagerBackendTestSuite) TestSetStateRetry() {
    method TestGetState (line 274) | func (s *EagerBackendTestSuite) TestGetState() {
    method TestPurgeState (line 281) | func (s *EagerBackendTestSuite) TestPurgeState() {
    method TestPurgeGroupMeta (line 304) | func (s *EagerBackendTestSuite) TestPurgeGroupMeta() {
    method getTaskSignature (line 330) | func (s *EagerBackendTestSuite) getTaskSignature(taskUUID string) *tas...
  function TestEagerBackendMain (line 340) | func TestEagerBackendMain(t *testing.T) {

FILE: v1/backends/iface/interfaces.go
  type Backend (line 8) | type Backend interface

FILE: v1/backends/memcache/memcache.go
  type Backend (line 18) | type Backend struct
    method InitGroup (line 33) | func (b *Backend) InitGroup(groupUUID string, taskUUIDs []string) error {
    method GroupCompleted (line 53) | func (b *Backend) GroupCompleted(groupUUID string, groupTaskCount int)...
    method GroupTaskStates (line 75) | func (b *Backend) GroupTaskStates(groupUUID string, groupTaskCount int...
    method TriggerChord (line 88) | func (b *Backend) TriggerChord(groupUUID string) (bool, error) {
    method SetStatePending (line 130) | func (b *Backend) SetStatePending(signature *tasks.Signature) error {
    method SetStateReceived (line 136) | func (b *Backend) SetStateReceived(signature *tasks.Signature) error {
    method SetStateStarted (line 142) | func (b *Backend) SetStateStarted(signature *tasks.Signature) error {
    method SetStateRetry (line 148) | func (b *Backend) SetStateRetry(signature *tasks.Signature) error {
    method SetStateSuccess (line 154) | func (b *Backend) SetStateSuccess(signature *tasks.Signature, results ...
    method SetStateFailure (line 160) | func (b *Backend) SetStateFailure(signature *tasks.Signature, err stri...
    method GetState (line 166) | func (b *Backend) GetState(taskUUID string) (*tasks.TaskState, error) {
    method PurgeState (line 183) | func (b *Backend) PurgeState(taskUUID string) error {
    method PurgeGroupMeta (line 188) | func (b *Backend) PurgeGroupMeta(groupUUID string) error {
    method updateState (line 193) | func (b *Backend) updateState(taskState *tasks.TaskState) error {
    method lockGroupMeta (line 207) | func (b *Backend) lockGroupMeta(groupMeta *tasks.GroupMeta) error {
    method unlockGroupMeta (line 222) | func (b *Backend) unlockGroupMeta(groupMeta *tasks.GroupMeta) error {
    method getGroupMeta (line 237) | func (b *Backend) getGroupMeta(groupUUID string) (*tasks.GroupMeta, er...
    method getStates (line 254) | func (b *Backend) getStates(taskUUIDs ...string) ([]*tasks.TaskState, ...
    method getExpirationTimestamp (line 277) | func (b *Backend) getExpirationTimestamp() int32 {
    method getClient (line 287) | func (b *Backend) getClient() *gomemcache.Client {
  function New (line 25) | func New(cnf *config.Config, servers []string) iface.Backend {

FILE: v1/backends/memcache/memcache_test.go
  function TestGroupCompleted (line 14) | func TestGroupCompleted(t *testing.T) {
  function TestGetState (line 73) | func TestGetState(t *testing.T) {
  function TestPurgeState (line 120) | func TestPurgeState(t *testing.T) {

FILE: v1/backends/mongo/mongodb.go
  type Backend (line 24) | type Backend struct
    method InitGroup (line 43) | func (b *Backend) InitGroup(groupUUID string, taskUUIDs []string) error {
    method GroupCompleted (line 54) | func (b *Backend) GroupCompleted(groupUUID string, groupTaskCount int)...
    method GroupTaskStates (line 76) | func (b *Backend) GroupTaskStates(groupUUID string, groupTaskCount int...
    method TriggerChord (line 89) | func (b *Backend) TriggerChord(groupUUID string) (bool, error) {
    method SetStatePending (line 113) | func (b *Backend) SetStatePending(signature *tasks.Signature) error {
    method SetStateReceived (line 123) | func (b *Backend) SetStateReceived(signature *tasks.Signature) error {
    method SetStateStarted (line 129) | func (b *Backend) SetStateStarted(signature *tasks.Signature) error {
    method SetStateRetry (line 135) | func (b *Backend) SetStateRetry(signature *tasks.Signature) error {
    method SetStateSuccess (line 141) | func (b *Backend) SetStateSuccess(signature *tasks.Signature, results ...
    method decodeResults (line 151) | func (b *Backend) decodeResults(results []*tasks.TaskResult) []*tasks....
    method SetStateFailure (line 173) | func (b *Backend) SetStateFailure(signature *tasks.Signature, err stri...
    method GetState (line 179) | func (b *Backend) GetState(taskUUID string) (*tasks.TaskState, error) {
    method PurgeState (line 190) | func (b *Backend) PurgeState(taskUUID string) error {
    method PurgeGroupMeta (line 196) | func (b *Backend) PurgeGroupMeta(groupUUID string) error {
    method lockGroupMeta (line 202) | func (b *Backend) lockGroupMeta(groupUUID string) error {
    method unlockGroupMeta (line 219) | func (b *Backend) unlockGroupMeta(groupUUID string) error {
    method getGroupMeta (line 226) | func (b *Backend) getGroupMeta(groupUUID string) (*tasks.GroupMeta, er...
    method getStates (line 238) | func (b *Backend) getStates(taskUUIDs ...string) ([]*tasks.TaskState, ...
    method updateState (line 260) | func (b *Backend) updateState(signature *tasks.Signature, update bson....
    method tasksCollection (line 266) | func (b *Backend) tasksCollection() *mongo.Collection {
    method groupMetasCollection (line 274) | func (b *Backend) groupMetasCollection() *mongo.Collection {
    method connect (line 284) | func (b *Backend) connect() error {
    method dial (line 309) | func (b *Backend) dial() (*mongo.Client, error) {
    method createMongoIndexes (line 337) | func (b *Backend) createMongoIndexes(database string) error {
  function New (line 33) | func New(cnf *config.Config) (iface.Backend, error) {

FILE: v1/backends/mongo/mongodb_test.go
  function newBackend (line 19) | func newBackend() (iface.Backend, error) {
  function TestNew (line 40) | func TestNew(t *testing.T) {
  function TestSetStatePending (line 51) | func TestSetStatePending(t *testing.T) {
  function TestSetStateReceived (line 72) | func TestSetStateReceived(t *testing.T) {
  function TestSetStateStarted (line 93) | func TestSetStateStarted(t *testing.T) {
  function TestSetStateSuccess (line 114) | func TestSetStateSuccess(t *testing.T) {
  function TestSetStateFailure (line 146) | func TestSetStateFailure(t *testing.T) {
  function TestGroupCompleted (line 170) | func TestGroupCompleted(t *testing.T) {
  function TestGroupStates (line 232) | func TestGroupStates(t *testing.T) {

FILE: v1/backends/null/null.go
  type ErrGroupNotFound (line 13) | type ErrGroupNotFound struct
    method Error (line 23) | func (e ErrGroupNotFound) Error() string {
  function NewErrGroupNotFound (line 18) | func NewErrGroupNotFound(groupUUID string) ErrGroupNotFound {
  type ErrTasknotFound (line 28) | type ErrTasknotFound struct
    method Error (line 38) | func (e ErrTasknotFound) Error() string {
  function NewErrTasknotFound (line 33) | func NewErrTasknotFound(taskUUID string) ErrTasknotFound {
  type Backend (line 43) | type Backend struct
    method InitGroup (line 57) | func (b *Backend) InitGroup(groupUUID string, taskUUIDs []string) error {
    method GroupCompleted (line 63) | func (b *Backend) GroupCompleted(groupUUID string, groupTaskCount int)...
    method GroupTaskStates (line 73) | func (b *Backend) GroupTaskStates(groupUUID string, groupTaskCount int...
    method TriggerChord (line 84) | func (b *Backend) TriggerChord(groupUUID string) (bool, error) {
    method SetStatePending (line 89) | func (b *Backend) SetStatePending(signature *tasks.Signature) error {
    method SetStateReceived (line 95) | func (b *Backend) SetStateReceived(signature *tasks.Signature) error {
    method SetStateStarted (line 101) | func (b *Backend) SetStateStarted(signature *tasks.Signature) error {
    method SetStateRetry (line 107) | func (b *Backend) SetStateRetry(signature *tasks.Signature) error {
    method SetStateSuccess (line 113) | func (b *Backend) SetStateSuccess(signature *tasks.Signature, results ...
    method SetStateFailure (line 119) | func (b *Backend) SetStateFailure(signature *tasks.Signature, err stri...
    method GetState (line 125) | func (b *Backend) GetState(taskUUID string) (*tasks.TaskState, error) {
    method PurgeState (line 130) | func (b *Backend) PurgeState(taskUUID string) error {
    method PurgeGroupMeta (line 135) | func (b *Backend) PurgeGroupMeta(groupUUID string) error {
    method updateState (line 144) | func (b *Backend) updateState(s *tasks.TaskState) error {
  function New (line 49) | func New() iface.Backend {

FILE: v1/backends/redis/goredis.go
  type BackendGR (line 23) | type BackendGR struct
    method InitGroup (line 77) | func (b *BackendGR) InitGroup(groupUUID string, taskUUIDs []string) er...
    method GroupCompleted (line 99) | func (b *BackendGR) GroupCompleted(groupUUID string, groupTaskCount in...
    method GroupTaskStates (line 121) | func (b *BackendGR) GroupTaskStates(groupUUID string, groupTaskCount i...
    method TriggerChord (line 134) | func (b *BackendGR) TriggerChord(groupUUID string) (bool, error) {
    method mergeNewTaskState (line 169) | func (b *BackendGR) mergeNewTaskState(newState *tasks.TaskState) {
    method SetStatePending (line 178) | func (b *BackendGR) SetStatePending(signature *tasks.Signature) error {
    method SetStateReceived (line 184) | func (b *BackendGR) SetStateReceived(signature *tasks.Signature) error {
    method SetStateStarted (line 191) | func (b *BackendGR) SetStateStarted(signature *tasks.Signature) error {
    method SetStateRetry (line 198) | func (b *BackendGR) SetStateRetry(signature *tasks.Signature) error {
    method SetStateSuccess (line 205) | func (b *BackendGR) SetStateSuccess(signature *tasks.Signature, result...
    method SetStateFailure (line 212) | func (b *BackendGR) SetStateFailure(signature *tasks.Signature, err st...
    method GetState (line 219) | func (b *BackendGR) GetState(taskUUID string) (*tasks.TaskState, error) {
    method PurgeState (line 236) | func (b *BackendGR) PurgeState(taskUUID string) error {
    method PurgeGroupMeta (line 246) | func (b *BackendGR) PurgeGroupMeta(groupUUID string) error {
    method getGroupMeta (line 256) | func (b *BackendGR) getGroupMeta(groupUUID string) (*tasks.GroupMeta, ...
    method getStates (line 273) | func (b *BackendGR) getStates(taskUUIDs ...string) ([]*tasks.TaskState...
    method updateState (line 304) | func (b *BackendGR) updateState(taskState *tasks.TaskState) error {
    method getExpiration (line 320) | func (b *BackendGR) getExpiration() time.Duration {
  function NewGR (line 36) | func NewGR(cnf *config.Config, addrs []string, db int) iface.Backend {

FILE: v1/backends/redis/goredis_test.go
  function getRedisG (line 15) | func getRedisG() iface.Backend {
  function TestGroupCompletedGR (line 26) | func TestGroupCompletedGR(t *testing.T) {
  function TestGetStateGR (line 83) | func TestGetStateGR(t *testing.T) {
  function TestPurgeStateGR (line 141) | func TestPurgeStateGR(t *testing.T) {

FILE: v1/backends/redis/redis.go
  type Backend (line 22) | type Backend struct
    method InitGroup (line 49) | func (b *Backend) InitGroup(groupUUID string, taskUUIDs []string) error {
    method GroupCompleted (line 74) | func (b *Backend) GroupCompleted(groupUUID string, groupTaskCount int)...
    method GroupTaskStates (line 99) | func (b *Backend) GroupTaskStates(groupUUID string, groupTaskCount int...
    method TriggerChord (line 115) | func (b *Backend) TriggerChord(groupUUID string) (bool, error) {
    method mergeNewTaskState (line 153) | func (b *Backend) mergeNewTaskState(conn redis.Conn, newState *tasks.T...
    method SetStatePending (line 162) | func (b *Backend) SetStatePending(signature *tasks.Signature) error {
    method SetStateReceived (line 171) | func (b *Backend) SetStateReceived(signature *tasks.Signature) error {
    method SetStateStarted (line 181) | func (b *Backend) SetStateStarted(signature *tasks.Signature) error {
    method SetStateRetry (line 191) | func (b *Backend) SetStateRetry(signature *tasks.Signature) error {
    method SetStateSuccess (line 201) | func (b *Backend) SetStateSuccess(signature *tasks.Signature, results ...
    method SetStateFailure (line 211) | func (b *Backend) SetStateFailure(signature *tasks.Signature, err stri...
    method GetState (line 221) | func (b *Backend) GetState(taskUUID string) (*tasks.TaskState, error) {
    method getState (line 228) | func (b *Backend) getState(conn redis.Conn, taskUUID string) (*tasks.T...
    method PurgeState (line 244) | func (b *Backend) PurgeState(taskUUID string) error {
    method PurgeGroupMeta (line 257) | func (b *Backend) PurgeGroupMeta(groupUUID string) error {
    method getGroupMeta (line 270) | func (b *Backend) getGroupMeta(conn redis.Conn, groupUUID string) (*ta...
    method getStates (line 288) | func (b *Backend) getStates(conn redis.Conn, taskUUIDs ...string) ([]*...
    method updateState (line 323) | func (b *Backend) updateState(conn redis.Conn, taskState *tasks.TaskSt...
    method getExpiration (line 339) | func (b *Backend) getExpiration() time.Duration {
    method open (line 350) | func (b *Backend) open() redis.Conn {
  function New (line 37) | func New(cnf *config.Config, host, username, password, socketPath string...

FILE: v1/backends/redis/redis_test.go
  function TestGroupCompleted (line 13) | func TestGroupCompleted(t *testing.T) {
  function TestGetState (line 73) | func TestGetState(t *testing.T) {
  function TestPurgeState (line 134) | func TestPurgeState(t *testing.T) {

FILE: v1/backends/result/async_result.go
  type AsyncResult (line 20) | type AsyncResult struct
    method Touch (line 74) | func (asyncResult *AsyncResult) Touch() ([]reflect.Value, error) {
    method Get (line 98) | func (asyncResult *AsyncResult) Get(sleepDuration time.Duration) ([]re...
    method GetWithTimeout (line 111) | func (asyncResult *AsyncResult) GetWithTimeout(timeoutDuration, sleepD...
    method GetState (line 131) | func (asyncResult *AsyncResult) GetState() *tasks.TaskState {
  type ChordAsyncResult (line 27) | type ChordAsyncResult struct
    method Get (line 166) | func (chordAsyncResult *ChordAsyncResult) Get(sleepDuration time.Durat...
    method GetWithTimeout (line 223) | func (chordAsyncResult *ChordAsyncResult) GetWithTimeout(timeoutDurati...
  type ChainAsyncResult (line 34) | type ChainAsyncResult struct
    method Get (line 145) | func (chainAsyncResult *ChainAsyncResult) Get(sleepDuration time.Durat...
    method GetWithTimeout (line 183) | func (chainAsyncResult *ChainAsyncResult) GetWithTimeout(timeoutDurati...
  function NewAsyncResult (line 40) | func NewAsyncResult(signature *tasks.Signature, backend iface.Backend) *...
  function NewChordAsyncResult (line 49) | func NewChordAsyncResult(groupTasks []*tasks.Signature, chordCallback *t...
  function NewChainAsyncResult (line 62) | func NewChainAsyncResult(tasks []*tasks.Signature, backend iface.Backend...

FILE: v1/brokers/amqp/amqp.go
  type AMQPConnection (line 21) | type AMQPConnection struct
  type Broker (line 32) | type Broker struct
    method StartConsuming (line 47) | func (b *Broker) StartConsuming(consumerTag string, concurrency int, t...
    method StopConsuming (line 109) | func (b *Broker) StopConsuming() {
    method GetOrOpenConnection (line 118) | func (b *Broker) GetOrOpenConnection(queueName string, queueBindingKey...
    method CloseConnections (line 169) | func (b *Broker) CloseConnections() error {
    method Publish (line 185) | func (b *Broker) Publish(ctx context.Context, signature *tasks.Signatu...
    method consume (line 254) | func (b *Broker) consume(deliveries <-chan amqp.Delivery, concurrency ...
    method consumeOne (line 304) | func (b *Broker) consumeOne(delivery amqp.Delivery, taskProcessor ifac...
    method delay (line 345) | func (b *Broker) delay(signature *tasks.Signature, delayMs int64) error {
    method isDirectExchange (line 429) | func (b *Broker) isDirectExchange() bool {
    method AdjustRoutingKey (line 437) | func (b *Broker) AdjustRoutingKey(s *tasks.Signature) {
    method GetPendingTasks (line 471) | func (b *Broker) GetPendingTasks(queue string) ([]*tasks.Signature, er...
  function New (line 42) | func New(cnf *config.Config) iface.Broker {
  type sigDumper (line 453) | type sigDumper struct
    method Process (line 458) | func (s *sigDumper) Process(sig *tasks.Signature) error {
    method CustomQueue (line 463) | func (s *sigDumper) CustomQueue() string {
    method PreConsumeHandler (line 467) | func (_ *sigDumper) PreConsumeHandler() bool {

FILE: v1/brokers/amqp/amqp_concurrence_test.go
  type doNothingProcessor (line 13) | type doNothingProcessor struct
    method Process (line 15) | func (_ doNothingProcessor) Process(signature *tasks.Signature) error {
    method CustomQueue (line 19) | func (_ doNothingProcessor) CustomQueue() string {
    method PreConsumeHandler (line 23) | func (_ doNothingProcessor) PreConsumeHandler() bool {
  function TestConsume (line 27) | func TestConsume(t *testing.T) {

FILE: v1/brokers/amqp/amqp_test.go
  function TestAdjustRoutingKey (line 13) | func TestAdjustRoutingKey(t *testing.T) {

FILE: v1/brokers/eager/eager.go
  type Broker (line 16) | type Broker struct
    method StartConsuming (line 32) | func (eagerBroker *Broker) StartConsuming(consumerTag string, concurre...
    method StopConsuming (line 37) | func (eagerBroker *Broker) StopConsuming() {
    method Publish (line 42) | func (eagerBroker *Broker) Publish(ctx context.Context, task *tasks.Si...
    method AssignWorker (line 66) | func (eagerBroker *Broker) AssignWorker(w iface.TaskProcessor) {
  function New (line 22) | func New() iface.Broker {
  type Mode (line 27) | type Mode interface

FILE: v1/brokers/errs/errors.go
  type ErrCouldNotUnmarshalTaskSignature (line 9) | type ErrCouldNotUnmarshalTaskSignature struct
    method Error (line 15) | func (e ErrCouldNotUnmarshalTaskSignature) Error() string {
  function NewErrCouldNotUnmarshalTaskSignature (line 20) | func NewErrCouldNotUnmarshalTaskSignature(msg []byte, err error) ErrCoul...

FILE: v1/brokers/gcppubsub/gcp_pubsub.go
  type Broker (line 19) | type Broker struct
    method StartConsuming (line 85) | func (b *Broker) StartConsuming(consumerTag string, concurrency int, t...
    method StopConsuming (line 122) | func (b *Broker) StopConsuming() {
    method Publish (line 131) | func (b *Broker) Publish(ctx context.Context, signature *tasks.Signatu...
    method consumeOne (line 168) | func (b *Broker) consumeOne(delivery *pubsub.Message, taskProcessor if...
  function New (line 30) | func New(cnf *config.Config, projectID, subscriptionName string) (iface....

FILE: v1/brokers/iface/interfaces.go
  type Broker (line 11) | type Broker interface
  type TaskProcessor (line 25) | type TaskProcessor interface

FILE: v1/brokers/redis/goredis.go
  type BrokerGR (line 26) | type BrokerGR struct
    method StartConsuming (line 84) | func (b *BrokerGR) StartConsuming(consumerTag string, concurrency int,...
    method StopConsuming (line 185) | func (b *BrokerGR) StopConsuming() {
    method Publish (line 196) | func (b *BrokerGR) Publish(ctx context.Context, signature *tasks.Signa...
    method GetPendingTasks (line 222) | func (b *BrokerGR) GetPendingTasks(queue string) ([]*tasks.Signature, ...
    method GetDelayedTasks (line 246) | func (b *BrokerGR) GetDelayedTasks() ([]*tasks.Signature, error) {
    method consume (line 267) | func (b *BrokerGR) consume(deliveries <-chan []byte, concurrency int, ...
    method consumeOne (line 312) | func (b *BrokerGR) consumeOne(delivery []byte, taskProcessor iface.Tas...
    method nextTask (line 338) | func (b *BrokerGR) nextTask(queue string) (result []byte, err error) {
    method nextDelayedTask (line 366) | func (b *BrokerGR) nextDelayedTask(key string) (result []byte, err err...
  function NewGR (line 40) | func NewGR(cnf *config.Config, addrs []string, db int) iface.Broker {
  function getQueueGR (line 433) | func getQueueGR(config *config.Config, taskProcessor iface.TaskProcessor...

FILE: v1/brokers/redis/redis.go
  constant defaultRedisDelayedTasksKey (line 25) | defaultRedisDelayedTasksKey = "delayed_tasks"
  type Broker (line 28) | type Broker struct
    method StartConsuming (line 65) | func (b *Broker) StartConsuming(consumerTag string, concurrency int, t...
    method StopConsuming (line 184) | func (b *Broker) StopConsuming() {
    method Publish (line 199) | func (b *Broker) Publish(ctx context.Context, signature *tasks.Signatu...
    method GetPendingTasks (line 228) | func (b *Broker) GetPendingTasks(queue string) ([]*tasks.Signature, er...
    method GetDelayedTasks (line 258) | func (b *Broker) GetDelayedTasks() ([]*tasks.Signature, error) {
    method consume (line 286) | func (b *Broker) consume(deliveries <-chan []byte, concurrency int, ta...
    method consumeOne (line 340) | func (b *Broker) consumeOne(delivery []byte, taskProcessor iface.TaskP...
    method nextTask (line 365) | func (b *Broker) nextTask(queue string) (result []byte, err error) {
    method nextDelayedTask (line 403) | func (b *Broker) nextDelayedTask(key string) (result []byte, err error) {
    method open (line 478) | func (b *Broker) open() redis.Conn {
    method requeueMessage (line 495) | func (b *Broker) requeueMessage(delivery []byte, taskProcessor iface.T...
  function New (line 47) | func New(cnf *config.Config, host, username, password, socketPath string...
  function getQueue (line 487) | func getQueue(config *config.Config, taskProcessor iface.TaskProcessor) ...

FILE: v1/brokers/sqs/sqs.go
  constant maxAWSSQSDelay (line 26) | maxAWSSQSDelay = time.Minute * 15
  type Broker (line 31) | type Broker struct
    method StartConsuming (line 61) | func (b *Broker) StartConsuming(consumerTag string, concurrency int, t...
    method StopConsuming (line 114) | func (b *Broker) StopConsuming() {
    method Publish (line 127) | func (b *Broker) Publish(ctx context.Context, signature *tasks.Signatu...
    method consume (line 181) | func (b *Broker) consume(deliveries <-chan *awssqs.ReceiveMessageOutpu...
    method consumeOne (line 197) | func (b *Broker) consumeOne(delivery *awssqs.ReceiveMessageOutput, tas...
    method deleteOne (line 243) | func (b *Broker) deleteOne(delivery *awssqs.ReceiveMessageOutput) error {
    method defaultQueueURL (line 257) | func (b *Broker) defaultQueueURL() *string {
    method receiveMessage (line 267) | func (b *Broker) receiveMessage(qURL *string) (*awssqs.ReceiveMessageO...
    method initializePool (line 298) | func (b *Broker) initializePool(pool chan struct{}, concurrency int) {
    method consumeDeliveries (line 305) | func (b *Broker) consumeDeliveries(deliveries <-chan *awssqs.ReceiveMe...
    method continueReceivingMessages (line 335) | func (b *Broker) continueReceivingMessages(qURL *string, deliveries ch...
    method stopReceiving (line 354) | func (b *Broker) stopReceiving() {
    method getQueueURL (line 361) | func (b *Broker) getQueueURL(taskProcessor iface.TaskProcessor) *string {
  function New (line 42) | func New(cnf *config.Config) iface.Broker {

FILE: v1/brokers/sqs/sqs_export_test.go
  type FakeSQS (line 25) | type FakeSQS struct
    method SendMessage (line 29) | func (f *FakeSQS) SendMessage(*awssqs.SendMessageInput) (*awssqs.SendM...
    method ReceiveMessage (line 38) | func (f *FakeSQS) ReceiveMessage(*awssqs.ReceiveMessageInput) (*awssqs...
    method DeleteMessage (line 42) | func (f *FakeSQS) DeleteMessage(*awssqs.DeleteMessageInput) (*awssqs.D...
  type ErrorSQS (line 46) | type ErrorSQS struct
    method SendMessage (line 50) | func (e *ErrorSQS) SendMessage(*awssqs.SendMessageInput) (*awssqs.Send...
    method ReceiveMessage (line 55) | func (e *ErrorSQS) ReceiveMessage(*awssqs.ReceiveMessageInput) (*awssq...
    method DeleteMessage (line 60) | func (e *ErrorSQS) DeleteMessage(*awssqs.DeleteMessageInput) (*awssqs....
  function init (line 65) | func init() {
  function NewTestConfig (line 98) | func NewTestConfig() *config.Config {
  function NewTestBroker (line 113) | func NewTestBroker() *Broker {
  function NewTestErrorBroker (line 131) | func NewTestErrorBroker() *Broker {
  method ConsumeForTest (line 149) | func (b *Broker) ConsumeForTest(deliveries <-chan *awssqs.ReceiveMessage...
  method ConsumeOneForTest (line 153) | func (b *Broker) ConsumeOneForTest(delivery *awssqs.ReceiveMessageOutput...
  method DeleteOneForTest (line 157) | func (b *Broker) DeleteOneForTest(delivery *awssqs.ReceiveMessageOutput)...
  method DefaultQueueURLForTest (line 161) | func (b *Broker) DefaultQueueURLForTest() *string {
  method ReceiveMessageForTest (line 165) | func (b *Broker) ReceiveMessageForTest(qURL *string) (*awssqs.ReceiveMes...
  method InitializePoolForTest (line 169) | func (b *Broker) InitializePoolForTest(pool chan struct{}, concurrency i...
  method ConsumeDeliveriesForTest (line 173) | func (b *Broker) ConsumeDeliveriesForTest(deliveries <-chan *awssqs.Rece...
  method ContinueReceivingMessagesForTest (line 177) | func (b *Broker) ContinueReceivingMessagesForTest(qURL *string, deliveri...
  method StopReceivingForTest (line 181) | func (b *Broker) StopReceivingForTest() {
  method GetStopReceivingChanForTest (line 185) | func (b *Broker) GetStopReceivingChanForTest() chan int {
  method StartConsumingForTest (line 189) | func (b *Broker) StartConsumingForTest(consumerTag string, concurrency i...
  method GetRetryFuncForTest (line 193) | func (b *Broker) GetRetryFuncForTest() func(chan int) {
  method GetStopChanForTest (line 197) | func (b *Broker) GetStopChanForTest() chan int {
  method GetRetryStopChanForTest (line 201) | func (b *Broker) GetRetryStopChanForTest() chan int {
  method GetQueueURLForTest (line 205) | func (b *Broker) GetQueueURLForTest(taskProcessor iface.TaskProcessor) *...
  method GetCustomQueueURL (line 209) | func (b *Broker) GetCustomQueueURL(customQueue string) *string {

FILE: v1/brokers/sqs/sqs_test.go
  function init (line 26) | func init() {
  function TestNewAWSSQSBroker (line 31) | func TestNewAWSSQSBroker(t *testing.T) {
  function TestPrivateFunc_continueReceivingMessages (line 39) | func TestPrivateFunc_continueReceivingMessages(t *testing.T) {
  function TestPrivateFunc_consume (line 88) | func TestPrivateFunc_consume(t *testing.T) {
  function TestPrivateFunc_consumeOne (line 108) | func TestPrivateFunc_consumeOne(t *testing.T) {
  function TestPrivateFunc_initializePool (line 134) | func TestPrivateFunc_initializePool(t *testing.T) {
  function TestPrivateFunc_startConsuming (line 144) | func TestPrivateFunc_startConsuming(t *testing.T) {
  function TestPrivateFuncDefaultQueueURL (line 165) | func TestPrivateFuncDefaultQueueURL(t *testing.T) {
  function TestPrivateFunc_stopReceiving (line 174) | func TestPrivateFunc_stopReceiving(t *testing.T) {
  function TestPrivateFunc_receiveMessage (line 184) | func TestPrivateFunc_receiveMessage(t *testing.T) {
  function TestPrivateFunc_consumeDeliveries (line 194) | func TestPrivateFunc_consumeDeliveries(t *testing.T) {
  function TestPrivateFunc_deleteOne (line 254) | func TestPrivateFunc_deleteOne(t *testing.T) {
  function Test_CustomQueueName (line 266) | func Test_CustomQueueName(t *testing.T) {
  function TestPrivateFunc_consumeWithConcurrency (line 284) | func TestPrivateFunc_consumeWithConcurrency(t *testing.T) {

FILE: v1/common/amqp.go
  type AMQPConnector (line 12) | type AMQPConnector struct
    method Connect (line 16) | func (ac *AMQPConnector) Connect(urls string, urlSeparator string, tls...
    method DeleteQueue (line 91) | func (ac *AMQPConnector) DeleteQueue(channel *amqp.Channel, queueName ...
    method InspectQueue (line 104) | func (*AMQPConnector) InspectQueue(channel *amqp.Channel, queueName st...
    method Open (line 114) | func (ac *AMQPConnector) Open(url string, tlsConfig *tls.Config) (*amq...
    method Close (line 133) | func (ac *AMQPConnector) Close(channel *amqp.Channel, conn *amqp.Conne...

FILE: v1/common/backend.go
  type Backend (line 8) | type Backend struct
    method GetConfig (line 18) | func (b *Backend) GetConfig() *config.Config {
    method IsAMQP (line 23) | func (b *Backend) IsAMQP() bool {
  function NewBackend (line 13) | func NewBackend(cnf *config.Config) Backend {

FILE: v1/common/broker.go
  type registeredTaskNames (line 14) | type registeredTaskNames struct
  type Broker (line 20) | type Broker struct
    method GetConfig (line 40) | func (b *Broker) GetConfig() *config.Config {
    method GetRetry (line 45) | func (b *Broker) GetRetry() bool {
    method GetRetryFunc (line 50) | func (b *Broker) GetRetryFunc() func(chan int) {
    method GetRetryStopChan (line 55) | func (b *Broker) GetRetryStopChan() chan int {
    method GetStopChan (line 60) | func (b *Broker) GetStopChan() chan int {
    method Publish (line 65) | func (b *Broker) Publish(signature *tasks.Signature) error {
    method SetRegisteredTaskNames (line 70) | func (b *Broker) SetRegisteredTaskNames(names []string) {
    method IsTaskRegistered (line 77) | func (b *Broker) IsTaskRegistered(name string) bool {
    method GetPendingTasks (line 89) | func (b *Broker) GetPendingTasks(queue string) ([]*tasks.Signature, er...
    method GetDelayedTasks (line 94) | func (b *Broker) GetDelayedTasks() ([]*tasks.Signature, error) {
    method StartConsuming (line 99) | func (b *Broker) StartConsuming(consumerTag string, concurrency int, t...
    method StopConsuming (line 107) | func (b *Broker) StopConsuming() {
    method GetRegisteredTaskNames (line 122) | func (b *Broker) GetRegisteredTaskNames() []string {
    method AdjustRoutingKey (line 133) | func (b *Broker) AdjustRoutingKey(s *tasks.Signature) {
  function NewBroker (line 30) | func NewBroker(cnf *config.Config) Broker {

FILE: v1/common/broker_test.go
  function TestIsTaskRegistered (line 13) | func TestIsTaskRegistered(t *testing.T) {
  function TestAdjustRoutingKey (line 23) | func TestAdjustRoutingKey(t *testing.T) {
  function TestGetRegisteredTaskNames (line 50) | func TestGetRegisteredTaskNames(t *testing.T) {
  function TestStopConsuming (line 59) | func TestStopConsuming(t *testing.T) {

FILE: v1/common/redis.go
  type RedisConnector (line 27) | type RedisConnector struct
    method NewPool (line 30) | func (rc *RedisConnector) NewPool(socketPath, host, username, password...
    method open (line 66) | func (rc *RedisConnector) open(socketPath, host, username string, pass...

FILE: v1/config/config.go
  constant DefaultResultsExpireIn (line 17) | DefaultResultsExpireIn = 3600
  type Config (line 55) | type Config struct
  type QueueBindingArgs (line 74) | type QueueBindingArgs
    method Decode (line 174) | func (args *QueueBindingArgs) Decode(value string) error {
  type QueueDeclareArgs (line 77) | type QueueDeclareArgs
  type AMQPConfig (line 80) | type AMQPConfig struct
  type DynamoDBConfig (line 92) | type DynamoDBConfig struct
  type SQSConfig (line 99) | type SQSConfig struct
  type RedisConfig (line 108) | type RedisConfig struct
  type GCPPubSubConfig (line 161) | type GCPPubSubConfig struct
  type MongoDBConfig (line 167) | type MongoDBConfig struct

FILE: v1/config/env.go
  function NewFromEnvironment (line 10) | func NewFromEnvironment() (*Config, error) {
  function fromEnvironment (line 21) | func fromEnvironment() (*Config, error) {

FILE: v1/config/env_test.go
  function TestNewFromEnvironment (line 13) | func TestNewFromEnvironment(t *testing.T) {

FILE: v1/config/file.go
  function NewFromYaml (line 13) | func NewFromYaml(cnfPath string, keepReloading bool) (*Config, error) {
  function ReadFromFile (line 44) | func ReadFromFile(cnfPath string) ([]byte, error) {
  function fromFile (line 63) | func fromFile(cnfPath string) (*Config, error) {

FILE: v1/config/file_test.go
  function TestReadFromFile (line 46) | func TestReadFromFile(t *testing.T) {
  function TestNewFromYaml (line 57) | func TestNewFromYaml(t *testing.T) {

FILE: v1/factories.go
  function BrokerFactory (line 37) | func BrokerFactory(cnf *config.Config) (brokeriface.Broker, error) {
  function BackendFactory (line 113) | func BackendFactory(cnf *config.Config) (backendiface.Backend, error) {
  function ParseRedisURL (line 188) | func ParseRedisURL(url string) (host, username, password string, db int,...
  function ParseBrokers (line 227) | func ParseBrokers(brokers []string) (int, []string) {
  function LockFactory (line 245) | func LockFactory(cnf *config.Config) (lockiface.Lock, error) {
  function ParseRedisSocketURL (line 269) | func ParseRedisSocketURL(url string) (path, username, password string, d...
  function ParseGCPPubSubURL (line 322) | func ParseGCPPubSubURL(url string) (string, string, error) {

FILE: v1/factories_test.go
  function TestBrokerFactory (line 94) | func TestBrokerFactory(t *testing.T) {
  function brokerEqual (line 233) | func brokerEqual(x, y brokeriface.Broker) bool {
  function TestBrokerFactoryError (line 255) | func TestBrokerFactoryError(t *testing.T) {
  function TestBackendFactory (line 295) | func TestBackendFactory(t *testing.T) {
  function TestBackendFactoryError (line 397) | func TestBackendFactoryError(t *testing.T) {
  function TestParseRedisURL (line 415) | func TestParseRedisURL(t *testing.T) {
  function TestParseRedisSocketURL (line 439) | func TestParseRedisSocketURL(t *testing.T) {

FILE: v1/locks/eager/eager.go
  type Lock (line 13) | type Lock struct
    method LockWithRetries (line 35) | func (e *Lock) LockWithRetries(key string, value int64) error {
    method Lock (line 48) | func (e *Lock) Lock(key string, value int64) error {
  function New (line 22) | func New() *Lock {

FILE: v1/locks/eager/eager_test.go
  function TestLock_Lock (line 11) | func TestLock_Lock(t *testing.T) {
  function TestLock_LockWithRetries (line 25) | func TestLock_LockWithRetries(t *testing.T) {
  function TestNew (line 39) | func TestNew(t *testing.T) {

FILE: v1/locks/iface/interfaces.go
  type Lock (line 3) | type Lock interface

FILE: v1/locks/redis/redis.go
  type Lock (line 18) | type Lock struct
    method LockWithRetries (line 52) | func (r Lock) LockWithRetries(key string, unixTsToExpireNs int64) error {
    method Lock (line 65) | func (r Lock) Lock(key string, unixTsToExpireNs int64) error {
  function New (line 24) | func New(cnf *config.Config, addrs []string, db, retries int) Lock {

FILE: v1/log/log.go
  function Set (line 23) | func Set(l logging.LoggerInterface) {
  function SetDebug (line 32) | func SetDebug(l logging.LoggerInterface) {
  function SetInfo (line 37) | func SetInfo(l logging.LoggerInterface) {
  function SetWarning (line 42) | func SetWarning(l logging.LoggerInterface) {
  function SetError (line 47) | func SetError(l logging.LoggerInterface) {
  function SetFatal (line 52) | func SetFatal(l logging.LoggerInterface) {

FILE: v1/log/log_test.go
  function TestDefaultLogger (line 9) | func TestDefaultLogger(t *testing.T) {

FILE: v1/retry/fibonacci.go
  function Fibonacci (line 4) | func Fibonacci() func() int {
  function FibonacciNext (line 13) | func FibonacciNext(start int) int {

FILE: v1/retry/fibonacci_test.go
  function TestFibonacci (line 10) | func TestFibonacci(t *testing.T) {
  function TestFibonacciNext (line 25) | func TestFibonacciNext(t *testing.T) {

FILE: v1/server.go
  type Server (line 29) | type Server struct
    method NewWorker (line 85) | func (server *Server) NewWorker(consumerTag string, concurrency int) *...
    method NewCustomQueueWorker (line 95) | func (server *Server) NewCustomQueueWorker(consumerTag string, concurr...
    method GetBroker (line 105) | func (server *Server) GetBroker() brokersiface.Broker {
    method SetBroker (line 110) | func (server *Server) SetBroker(broker brokersiface.Broker) {
    method GetBackend (line 115) | func (server *Server) GetBackend() backendsiface.Backend {
    method SetBackend (line 120) | func (server *Server) SetBackend(backend backendsiface.Backend) {
    method GetConfig (line 125) | func (server *Server) GetConfig() *config.Config {
    method SetConfig (line 130) | func (server *Server) SetConfig(cnf *config.Config) {
    method SetPreTaskHandler (line 135) | func (server *Server) SetPreTaskHandler(handler func(*tasks.Signature)) {
    method RegisterTasks (line 140) | func (server *Server) RegisterTasks(namedTaskFuncs map[string]interfac...
    method RegisterTask (line 156) | func (server *Server) RegisterTask(name string, taskFunc interface{}) ...
    method IsTaskRegistered (line 166) | func (server *Server) IsTaskRegistered(name string) bool {
    method GetRegisteredTask (line 172) | func (server *Server) GetRegisteredTask(name string) (interface{}, err...
    method SendTaskWithContext (line 181) | func (server *Server) SendTaskWithContext(ctx context.Context, signatu...
    method SendTask (line 216) | func (server *Server) SendTask(signature *tasks.Signature) (*result.As...
    method SendChainWithContext (line 221) | func (server *Server) SendChainWithContext(ctx context.Context, chain ...
    method SendChain (line 231) | func (server *Server) SendChain(chain *tasks.Chain) (*result.ChainAsyn...
    method SendGroupWithContext (line 241) | func (server *Server) SendGroupWithContext(ctx context.Context, group ...
    method SendGroup (line 317) | func (server *Server) SendGroup(group *tasks.Group, sendConcurrency in...
    method SendChordWithContext (line 322) | func (server *Server) SendChordWithContext(ctx context.Context, chord ...
    method SendChord (line 341) | func (server *Server) SendChord(chord *tasks.Chord, sendConcurrency in...
    method GetRegisteredTaskNames (line 346) | func (server *Server) GetRegisteredTaskNames() []string {
    method RegisterPeriodicTask (line 357) | func (server *Server) RegisterPeriodicTask(spec, name string, signatur...
    method RegisterPeriodicChain (line 383) | func (server *Server) RegisterPeriodicChain(spec, name string, signatu...
    method RegisterPeriodicGroup (line 412) | func (server *Server) RegisterPeriodicGroup(spec, name string, sendCon...
    method RegisterPeriodicChord (line 441) | func (server *Server) RegisterPeriodicChord(spec, name string, sendCon...
  function NewServerWithBrokerBackendLock (line 40) | func NewServerWithBrokerBackendLock(cnf *config.Config, brokerServer bro...
  function NewServer (line 57) | func NewServer(cnf *config.Config) (*Server, error) {

FILE: v1/server_test.go
  function TestRegisterTasks (line 12) | func TestRegisterTasks(t *testing.T) {
  function TestRegisterTask (line 25) | func TestRegisterTask(t *testing.T) {
  function TestRegisterTaskInRaceCondition (line 36) | func TestRegisterTaskInRaceCondition(t *testing.T) {
  function TestGetRegisteredTask (line 50) | func TestGetRegisteredTask(t *testing.T) {
  function TestGetRegisteredTaskNames (line 58) | func TestGetRegisteredTaskNames(t *testing.T) {
  function TestNewWorker (line 72) | func TestNewWorker(t *testing.T) {
  function TestNewCustomQueueWorker (line 81) | func TestNewCustomQueueWorker(t *testing.T) {
  function getTestServer (line 90) | func getTestServer(t *testing.T) *machinery.Server {

FILE: v1/tasks/errors.go
  type ErrRetryTaskLater (line 9) | type ErrRetryTaskLater struct
    method RetryIn (line 15) | func (e ErrRetryTaskLater) RetryIn() time.Duration {
    method Error (line 20) | func (e ErrRetryTaskLater) Error() string {
  function NewErrRetryTaskLater (line 25) | func NewErrRetryTaskLater(msg string, retryIn time.Duration) ErrRetryTas...
  type Retriable (line 30) | type Retriable interface

FILE: v1/tasks/reflect.go
  type ErrUnsupportedType (line 56) | type ErrUnsupportedType struct
    method Error (line 66) | func (e ErrUnsupportedType) Error() string {
  function NewErrUnsupportedType (line 61) | func NewErrUnsupportedType(valueType string) ErrUnsupportedType {
  function ReflectValue (line 71) | func ReflectValue(valueType string, value interface{}) (reflect.Value, e...
  function reflectValue (line 81) | func reflectValue(valueType string, value interface{}) (reflect.Value, e...
  function reflectValues (line 148) | func reflectValues(valueType string, value interface{}) (reflect.Value, ...
  function getBoolValue (line 261) | func getBoolValue(theType string, value interface{}) (bool, error) {
  function getIntValue (line 270) | func getIntValue(theType string, value interface{}) (int64, error) {
  function getUintValue (line 291) | func getUintValue(theType string, value interface{}) (uint64, error) {
  function getFloatValue (line 321) | func getFloatValue(theType string, value interface{}) (float64, error) {
  function getStringValue (line 341) | func getStringValue(theType string, value interface{}) (string, error) {
  function IsContextType (line 351) | func IsContextType(t reflect.Type) bool {

FILE: v1/tasks/reflect_test.go
  function TestReflectValue (line 227) | func TestReflectValue(t *testing.T) {

FILE: v1/tasks/result.go
  type TaskResult (line 10) | type TaskResult struct
  function ReflectTaskResults (line 16) | func ReflectTaskResults(taskResults []*TaskResult) ([]reflect.Value, err...
  function HumanReadableResults (line 29) | func HumanReadableResults(results []reflect.Value) string {

FILE: v1/tasks/result_test.go
  function TestReflectTaskResults (line 10) | func TestReflectTaskResults(t *testing.T) {

FILE: v1/tasks/signature.go
  type Arg (line 12) | type Arg struct
  type Headers (line 19) | type Headers
    method Set (line 22) | func (h Headers) Set(key, val string) {
    method ForeachKey (line 29) | func (h Headers) ForeachKey(handler func(key, val string) error) error {
  type Signature (line 46) | type Signature struct
  function NewSignature (line 75) | func NewSignature(name string, args []Arg) (*Signature, error) {
  function CopySignatures (line 84) | func CopySignatures(signatures ...*Signature) []*Signature {
  function CopySignature (line 92) | func CopySignature(signature *Signature) *Signature {

FILE: v1/tasks/state.go
  constant StatePending (line 7) | StatePending = "PENDING"
  constant StateReceived (line 9) | StateReceived = "RECEIVED"
  constant StateStarted (line 11) | StateStarted = "STARTED"
  constant StateRetry (line 13) | StateRetry = "RETRY"
  constant StateSuccess (line 15) | StateSuccess = "SUCCESS"
  constant StateFailure (line 17) | StateFailure = "FAILURE"
  type TaskState (line 21) | type TaskState struct
    method IsCompleted (line 97) | func (taskState *TaskState) IsCompleted() bool {
    method IsSuccess (line 102) | func (taskState *TaskState) IsSuccess() bool {
    method IsFailure (line 107) | func (taskState *TaskState) IsFailure() bool {
  type GroupMeta (line 34) | type GroupMeta struct
  function NewPendingTaskState (line 44) | func NewPendingTaskState(signature *Signature) *TaskState {
  function NewReceivedTaskState (line 54) | func NewReceivedTaskState(signature *Signature) *TaskState {
  function NewStartedTaskState (line 62) | func NewStartedTaskState(signature *Signature) *TaskState {
  function NewSuccessTaskState (line 70) | func NewSuccessTaskState(signature *Signature, results []*TaskResult) *T...
  function NewFailureTaskState (line 79) | func NewFailureTaskState(signature *Signature, err string) *TaskState {
  function NewRetryTaskState (line 88) | func NewRetryTaskState(signature *Signature) *TaskState {

FILE: v1/tasks/state_test.go
  function TestTaskStateIsCompleted (line 10) | func TestTaskStateIsCompleted(t *testing.T) {

FILE: v1/tasks/task.go
  type Task (line 22) | type Task struct
    method Call (line 102) | func (t *Task) Call() (taskResults []*TaskResult, err error) {
    method ReflectArgs (line 188) | func (t *Task) ReflectArgs(args []Arg) error {
  type signatureCtxType (line 29) | type signatureCtxType struct
  function SignatureFromContext (line 34) | func SignatureFromContext(ctx context.Context) *Signature {
  function NewWithSignature (line 49) | func NewWithSignature(taskFunc interface{}, signature *Signature) (*Task...
  function New (line 75) | func New(taskFunc interface{}, args []Arg) (*Task, error) {

FILE: v1/tasks/task_test.go
  function TestTaskCallErrorTest (line 14) | func TestTaskCallErrorTest(t *testing.T) {
  function TestTaskReflectArgs (line 43) | func TestTaskReflectArgs(t *testing.T) {
  function TestTaskCallInvalidArgRobustnessError (line 60) | func TestTaskCallInvalidArgRobustnessError(t *testing.T) {
  function TestTaskCallInterfaceValuedResult (line 80) | func TestTaskCallInterfaceValuedResult(t *testing.T) {
  function TestTaskCallWithContext (line 95) | func TestTaskCallWithContext(t *testing.T) {
  function TestTaskCallWithSignatureInContext (line 111) | func TestTaskCallWithSignatureInContext(t *testing.T) {

FILE: v1/tasks/validate.go
  function ValidateTask (line 20) | func ValidateTask(task interface{}) error {

FILE: v1/tasks/validate_test.go
  function TestValidateTask (line 10) | func TestValidateTask(t *testing.T) {

FILE: v1/tasks/workflow.go
  type Chain (line 10) | type Chain struct
  type Group (line 15) | type Group struct
    method GetUUIDs (line 28) | func (group *Group) GetUUIDs() []string {
  type Chord (line 22) | type Chord struct
  function NewChain (line 38) | func NewChain(signatures ...*Signature) (*Chain, error) {
  function NewGroup (line 59) | func NewGroup(signatures ...*Signature) (*Group, error) {
  function NewChord (line 82) | func NewChord(group *Group, callback *Signature) (*Chord, error) {

FILE: v1/tasks/workflow_test.go
  function TestNewChain (line 10) | func TestNewChain(t *testing.T) {

FILE: v1/tracing/tracing.go
  function StartSpanFromHeaders (line 23) | func StartSpanFromHeaders(headers tasks.Headers, operationName string) o...
  function HeadersWithSpan (line 44) | func HeadersWithSpan(headers tasks.Headers, span opentracing.Span) tasks...
  type consumerOption (line 57) | type consumerOption struct
    method Apply (line 61) | func (c consumerOption) Apply(o *opentracing.StartSpanOptions) {
  function ConsumerOption (line 69) | func ConsumerOption(producer opentracing.SpanContext) opentracing.StartS...
  type producerOption (line 73) | type producerOption struct
    method Apply (line 75) | func (p producerOption) Apply(o *opentracing.StartSpanOptions) {
  function ProducerOption (line 80) | func ProducerOption() opentracing.StartSpanOption {
  function AnnotateSpanWithSignatureInfo (line 85) | func AnnotateSpanWithSignatureInfo(span opentracing.Span, signature *tas...
  function AnnotateSpanWithChainInfo (line 101) | func AnnotateSpanWithChainInfo(span opentracing.Span, chain *tasks.Chain) {
  function AnnotateSpanWithGroupInfo (line 112) | func AnnotateSpanWithGroupInfo(span opentracing.Span, group *tasks.Group...
  function AnnotateSpanWithChordInfo (line 132) | func AnnotateSpanWithChordInfo(span opentracing.Span, chord *tasks.Chord...

FILE: v1/utils/deepcopy.go
  function deepCopy (line 14) | func deepCopy(dst, src reflect.Value) {
  function DeepCopy (line 59) | func DeepCopy(dst, src interface{}) error {
  function DeepClone (line 79) | func DeepClone(v interface{}) interface{} {

FILE: v1/utils/deepcopy_test.go
  function TestDeepCopy (line 9) | func TestDeepCopy(t *testing.T) {

FILE: v1/utils/utils.go
  constant LockKeyPrefix (line 9) | LockKeyPrefix = "machinery_lock_"
  function GetLockName (line 12) | func GetLockName(name, spec string) string {

FILE: v1/utils/utils_test.go
  function TestGetLockName (line 9) | func TestGetLockName(t *testing.T) {

FILE: v1/utils/uuid.go
  function GetPureUUID (line 8) | func GetPureUUID() string {

FILE: v1/utils/uuid_test.go
  function TestGetPureUUID (line 9) | func TestGetPureUUID(t *testing.T) {

FILE: v1/worker.go
  type Worker (line 24) | type Worker struct
    method Launch (line 44) | func (worker *Worker) Launch() error {
    method LaunchAsync (line 53) | func (worker *Worker) LaunchAsync(errorsChan chan<- error) {
    method CustomQueue (line 123) | func (worker *Worker) CustomQueue() string {
    method Quit (line 128) | func (worker *Worker) Quit() {
    method Process (line 133) | func (worker *Worker) Process(signature *tasks.Signature) error {
    method taskRetry (line 204) | func (worker *Worker) taskRetry(signature *tasks.Signature) error {
    method retryTaskIn (line 228) | func (worker *Worker) retryTaskIn(signature *tasks.Signature, retryIn ...
    method taskSucceeded (line 247) | func (worker *Worker) taskSucceeded(signature *tasks.Signature, taskRe...
    method taskFailed (line 361) | func (worker *Worker) taskFailed(signature *tasks.Signature, taskErr e...
    method hasAMQPBackend (line 392) | func (worker *Worker) hasAMQPBackend() bool {
    method SetErrorHandler (line 399) | func (worker *Worker) SetErrorHandler(handler func(err error)) {
    method SetPreTaskHandler (line 404) | func (worker *Worker) SetPreTaskHandler(handler func(*tasks.Signature)) {
    method SetPostTaskHandler (line 409) | func (worker *Worker) SetPostTaskHandler(handler func(*tasks.Signature...
    method SetPreConsumeHandler (line 414) | func (worker *Worker) SetPreConsumeHandler(handler func(*Worker) bool) {
    method GetServer (line 419) | func (worker *Worker) GetServer() *Server {
    method PreConsumeHandler (line 424) | func (worker *Worker) PreConsumeHandler() bool {
  function RedactURL (line 432) | func RedactURL(urlString string) string {

FILE: v1/worker_test.go
  function TestRedactURL (line 11) | func TestRedactURL(t *testing.T) {
  function TestPreConsumeHandler (line 19) | func TestPreConsumeHandler(t *testing.T) {
  function SamplePreConsumeHandler (line 28) | func SamplePreConsumeHandler(w *machinery.Worker) bool {

FILE: v2/backends/amqp/amqp.go
  type Backend (line 32) | type Backend struct
    method InitGroup (line 43) | func (b *Backend) InitGroup(groupUUID string, taskUUIDs []string) error {
    method GroupCompleted (line 50) | func (b *Backend) GroupCompleted(groupUUID string, groupTaskCount int)...
    method GroupTaskStates (line 66) | func (b *Backend) GroupTaskStates(groupUUID string, groupTaskCount int...
    method TriggerChord (line 119) | func (b *Backend) TriggerChord(groupUUID string) (bool, error) {
    method SetStatePending (line 135) | func (b *Backend) SetStatePending(signature *tasks.Signature) error {
    method SetStateReceived (line 141) | func (b *Backend) SetStateReceived(signature *tasks.Signature) error {
    method SetStateStarted (line 147) | func (b *Backend) SetStateStarted(signature *tasks.Signature) error {
    method SetStateRetry (line 153) | func (b *Backend) SetStateRetry(signature *tasks.Signature) error {
    method SetStateSuccess (line 159) | func (b *Backend) SetStateSuccess(signature *tasks.Signature, results ...
    method SetStateFailure (line 174) | func (b *Backend) SetStateFailure(signature *tasks.Signature, err stri...
    method GetState (line 190) | func (b *Backend) GetState(taskUUID string) (*tasks.TaskState, error) {
    method PurgeState (line 243) | func (b *Backend) PurgeState(taskUUID string) error {
    method PurgeGroupMeta (line 254) | func (b *Backend) PurgeGroupMeta(groupUUID string) error {
    method updateState (line 267) | func (b *Backend) updateState(taskState *tasks.TaskState) error {
    method getExpiresIn (line 323) | func (b *Backend) getExpiresIn() int {
    method markTaskCompleted (line 335) | func (b *Backend) markTaskCompleted(signature *tasks.Signature, taskSt...
  function New (line 38) | func New(cnf *config.Config) iface.Backend {
  function amqmChordTriggeredQueue (line 394) | func amqmChordTriggeredQueue(groupUUID string) string {

FILE: v2/backends/amqp/amqp_test.go
  function init (line 18) | func init() {
  function TestGroupCompleted (line 56) | func TestGroupCompleted(t *testing.T) {
  function TestGetState (line 109) | func TestGetState(t *testing.T) {
  function TestPurgeState (line 157) | func TestPurgeState(t *testing.T) {

FILE: v2/backends/dynamodb/dynamodb.go
  constant BatchItemsLimit (line 24) | BatchItemsLimit  = 99
  constant MaxFetchAttempts (line 25) | MaxFetchAttempts = 3
  type Backend (line 29) | type Backend struct
    method InitGroup (line 60) | func (b *Backend) InitGroup(groupUUID string, taskUUIDs []string) error {
    method GroupCompleted (line 86) | func (b *Backend) GroupCompleted(groupUUID string, groupTaskCount int)...
    method GroupTaskStates (line 107) | func (b *Backend) GroupTaskStates(groupUUID string, groupTaskCount int...
    method TriggerChord (line 117) | func (b *Backend) TriggerChord(groupUUID string) (bool, error) {
    method SetStatePending (line 152) | func (b *Backend) SetStatePending(signature *tasks.Signature) error {
    method SetStateReceived (line 159) | func (b *Backend) SetStateReceived(signature *tasks.Signature) error {
    method SetStateStarted (line 165) | func (b *Backend) SetStateStarted(signature *tasks.Signature) error {
    method SetStateRetry (line 171) | func (b *Backend) SetStateRetry(signature *tasks.Signature) error {
    method SetStateSuccess (line 177) | func (b *Backend) SetStateSuccess(signature *tasks.Signature, results ...
    method SetStateFailure (line 184) | func (b *Backend) SetStateFailure(signature *tasks.Signature, err stri...
    method GetState (line 191) | func (b *Backend) GetState(taskUUID string) (*tasks.TaskState, error) {
    method getStates (line 209) | func (b *Backend) getStates(tasksToFetch []string) ([]*tasks.TaskState...
    method batchFetchTaskStates (line 245) | func (b *Backend) batchFetchTaskStates(taskUUIDs []string) ([]*tasks.T...
    method PurgeState (line 293) | func (b *Backend) PurgeState(taskUUID string) error {
    method PurgeGroupMeta (line 311) | func (b *Backend) PurgeGroupMeta(groupUUID string) error {
    method getGroupMeta (line 328) | func (b *Backend) getGroupMeta(groupUUID string) (*tasks.GroupMeta, er...
    method lockGroupMeta (line 350) | func (b *Backend) lockGroupMeta(groupUUID string) error {
    method unlockGroupMeta (line 358) | func (b *Backend) unlockGroupMeta(groupUUID string) error {
    method updateGroupMetaLock (line 366) | func (b *Backend) updateGroupMetaLock(groupUUID string, status bool) e...
    method chordTriggered (line 394) | func (b *Backend) chordTriggered(groupUUID string) error {
    method setTaskState (line 422) | func (b *Backend) setTaskState(taskState *tasks.TaskState) error {
    method initTaskState (line 490) | func (b *Backend) initTaskState(taskState *tasks.TaskState) error {
    method updateToFailureStateWithError (line 507) | func (b *Backend) updateToFailureStateWithError(taskState *tasks.TaskS...
    method unmarshalGroupMetaGetItemResult (line 547) | func (b *Backend) unmarshalGroupMetaGetItemResult(result *dynamodb.Get...
    method unmarshalTaskStateGetItemResult (line 562) | func (b *Backend) unmarshalTaskStateGetItemResult(result *dynamodb.Get...
    method checkRequiredTablesIfExist (line 577) | func (b *Backend) checkRequiredTablesIfExist() error {
    method tableExists (line 607) | func (b *Backend) tableExists(tableName string, tableNames []string) b...
    method getExpirationTime (line 616) | func (b *Backend) getExpirationTime() int64 {
  function New (line 36) | func New(cnf *config.Config) (iface.Backend, error) {
  function getUnfetchedKeys (line 626) | func getUnfetchedKeys(unprocessed types.KeysAndAttributes) ([]string, er...
  function chunkTasks (line 639) | func chunkTasks(array []string, chunkSize int) [][]string {
  function min (line 650) | func min(a, b int) int {

FILE: v2/backends/dynamodb/dynamodb_export_test.go
  type TestDynamoDBClient (line 27) | type TestDynamoDBClient struct
    method ResetOverrides (line 35) | func (t *TestDynamoDBClient) ResetOverrides() {
    method PutItem (line 41) | func (t *TestDynamoDBClient) PutItem(ctx context.Context, input *dynam...
    method BatchGetItem (line 47) | func (t *TestDynamoDBClient) BatchGetItem(ctx context.Context, input *...
    method GetItem (line 54) | func (t *TestDynamoDBClient) GetItem(ctx context.Context, input *dynam...
    method DeleteItem (line 126) | func (t *TestDynamoDBClient) DeleteItem(ctx context.Context, input *dy...
    method UpdateItem (line 130) | func (t *TestDynamoDBClient) UpdateItem(ctx context.Context, input *dy...
    method ListTables (line 137) | func (t *TestDynamoDBClient) ListTables(ctx context.Context, input *dy...
  type TestErrDynamoDBClient (line 147) | type TestErrDynamoDBClient struct
    method PutItem (line 151) | func (t *TestErrDynamoDBClient) PutItem(context.Context, *dynamodb.Put...
    method GetItem (line 155) | func (t *TestErrDynamoDBClient) GetItem(context.Context, *dynamodb.Get...
    method DeleteItem (line 159) | func (t *TestErrDynamoDBClient) DeleteItem(context.Context, *dynamodb....
    method Scan (line 163) | func (t *TestErrDynamoDBClient) Scan(context.Context, *dynamodb.ScanIn...
    method UpdateItem (line 167) | func (t *TestErrDynamoDBClient) UpdateItem(context.Context, *dynamodb....
    method ListTables (line 171) | func (t *TestErrDynamoDBClient) ListTables(context.Context, *dynamodb....
  function init (line 175) | func init() {
  method GetConfig (line 196) | func (b *Backend) GetConfig() *config.Config {
  method GetClient (line 200) | func (b *Backend) GetClient() dynamodbiface.API {
  method GetGroupMetaForTest (line 204) | func (b *Backend) GetGroupMetaForTest(groupUUID string) (*tasks.GroupMet...
  method UnmarshalGroupMetaGetItemResultForTest (line 208) | func (b *Backend) UnmarshalGroupMetaGetItemResultForTest(result *dynamod...
  method UnmarshalTaskStateGetItemResultForTest (line 212) | func (b *Backend) UnmarshalTaskStateGetItemResultForTest(result *dynamod...
  method SetTaskStateForTest (line 216) | func (b *Backend) SetTaskStateForTest(taskState *tasks.TaskState) error {
  method ChordTriggeredForTest (line 220) | func (b *Backend) ChordTriggeredForTest(groupUUID string) error {
  method UpdateGroupMetaLockForTest (line 224) | func (b *Backend) UpdateGroupMetaLockForTest(groupUUID string, status bo...
  method UnlockGroupMetaForTest (line 228) | func (b *Backend) UnlockGroupMetaForTest(groupUUID string) error {
  method LockGroupMetaForTest (line 232) | func (b *Backend) LockGroupMetaForTest(groupUUID string) error {
  method GetStatesForTest (line 236) | func (b *Backend) GetStatesForTest(taskUUIDs ...string) ([]*tasks.TaskSt...
  method UpdateToFailureStateWithErrorForTest (line 240) | func (b *Backend) UpdateToFailureStateWithErrorForTest(taskState *tasks....
  method TableExistsForTest (line 244) | func (b *Backend) TableExistsForTest(tableName string, tableNames []stri...
  method CheckRequiredTablesIfExistForTest (line 248) | func (b *Backend) CheckRequiredTablesIfExistForTest() error {

FILE: v2/backends/dynamodb/dynamodb_test.go
  function TestNew (line 19) | func TestNew(t *testing.T) {
  function TestInitGroup (line 26) | func TestInitGroup(t *testing.T) {
  function assertTTLValue (line 58) | func assertTTLValue(t *testing.T, expectedTTLTime time.Time, actualEncod...
  function TestGroupCompleted (line 65) | func TestGroupCompleted(t *testing.T) {
  function TestGroupCompletedReturnsError (line 92) | func TestGroupCompletedReturnsError(t *testing.T) {
  function TestGroupCompletedReturnsFalse (line 104) | func TestGroupCompletedReturnsFalse(t *testing.T) {
  function TestGroupCompletedRetries (line 126) | func TestGroupCompletedRetries(t *testing.T) {
  function TestGroupCompletedRetrieSuccess (line 157) | func TestGroupCompletedRetrieSuccess(t *testing.T) {
  function TestPrivateFuncGetGroupMeta (line 202) | func TestPrivateFuncGetGroupMeta(t *testing.T) {
  function TestPrivateFuncUnmarshalTaskStateGetItemResult (line 221) | func TestPrivateFuncUnmarshalTaskStateGetItemResult(t *testing.T) {
  function TestPrivateFuncUnmarshalGroupMetaGetItemResult (line 274) | func TestPrivateFuncUnmarshalGroupMetaGetItemResult(t *testing.T) {
  function TestPrivateFuncSetTaskState (line 350) | func TestPrivateFuncSetTaskState(t *testing.T) {
  function verifyUpdateInput (line 368) | func verifyUpdateInput(t *testing.T, input *awsdynamodb.UpdateItemInput,...
  function TestSetStateSuccess (line 384) | func TestSetStateSuccess(t *testing.T) {
  function TestSetStateFailure (line 404) | func TestSetStateFailure(t *testing.T) {
  function TestSetStateReceived (line 424) | func TestSetStateReceived(t *testing.T) {
  function TestSetStateStarted (line 443) | func TestSetStateStarted(t *testing.T) {
  function TestSetStateRetry (line 462) | func TestSetStateRetry(t *testing.T) {
  function TestGroupTaskStates (line 481) | func TestGroupTaskStates(t *testing.T) {
  function TestTriggerChord (line 541) | func TestTriggerChord(t *testing.T) {
  function TestGetState (line 548) | func TestGetState(t *testing.T) {
  function TestPurgeState (line 574) | func TestPurgeState(t *testing.T) {
  function TestPurgeGroupMeta (line 583) | func TestPurgeGroupMeta(t *testing.T) {
  function TestPrivateFuncLockGroupMeta (line 592) | func TestPrivateFuncLockGroupMeta(t *testing.T) {
  function TestPrivateFuncUnLockGroupMeta (line 600) | func TestPrivateFuncUnLockGroupMeta(t *testing.T) {
  function TestPrivateFuncChordTriggered (line 608) | func TestPrivateFuncChordTriggered(t *testing.T) {
  function TestDynamoDBPrivateFuncUpdateGroupMetaLock (line 616) | func TestDynamoDBPrivateFuncUpdateGroupMetaLock(t *testing.T) {
  function TestPrivateFuncUpdateToFailureStateWithError (line 624) | func TestPrivateFuncUpdateToFailureStateWithError(t *testing.T) {
  function TestPrivateFuncTableExistsForTest (line 640) | func TestPrivateFuncTableExistsForTest(t *testing.T) {
  function TestPrivateFuncCheckRequiredTablesIfExistForTest (line 646) | func TestPrivateFuncCheckRequiredTablesIfExistForTest(t *testing.T) {
  function validateBatchGetItemInput (line 663) | func validateBatchGetItemInput(input *awsdynamodb.BatchGetItemInput) err...

FILE: v2/backends/eager/eager.go
  type ErrGroupNotFound (line 16) | type ErrGroupNotFound struct
    method Error (line 26) | func (e ErrGroupNotFound) Error() string {
  function NewErrGroupNotFound (line 21) | func NewErrGroupNotFound(groupUUID string) ErrGroupNotFound {
  type ErrTasknotFound (line 31) | type ErrTasknotFound struct
    method Error (line 41) | func (e ErrTasknotFound) Error() string {
  function NewErrTasknotFound (line 36) | func NewErrTasknotFound(taskUUID string) ErrTasknotFound {
  type Backend (line 46) | type Backend struct
    method InitGroup (line 63) | func (b *Backend) InitGroup(groupUUID string, taskUUIDs []string) error {
    method GroupCompleted (line 73) | func (b *Backend) GroupCompleted(groupUUID string, groupTaskCount int)...
    method GroupTaskStates (line 95) | func (b *Backend) GroupTaskStates(groupUUID string, groupTaskCount int...
    method TriggerChord (line 118) | func (b *Backend) TriggerChord(groupUUID string) (bool, error) {
    method SetStatePending (line 123) | func (b *Backend) SetStatePending(signature *tasks.Signature) error {
    method SetStateReceived (line 129) | func (b *Backend) SetStateReceived(signature *tasks.Signature) error {
    method SetStateStarted (line 135) | func (b *Backend) SetStateStarted(signature *tasks.Signature) error {
    method SetStateRetry (line 141) | func (b *Backend) SetStateRetry(signature *tasks.Signature) error {
    method SetStateSuccess (line 147) | func (b *Backend) SetStateSuccess(signature *tasks.Signature, results ...
    method SetStateFailure (line 153) | func (b *Backend) SetStateFailure(signature *tasks.Signature, err stri...
    method GetState (line 159) | func (b *Backend) GetState(taskUUID string) (*tasks.TaskState, error) {
    method PurgeState (line 176) | func (b *Backend) PurgeState(taskUUID string) error {
    method PurgeGroupMeta (line 187) | func (b *Backend) PurgeGroupMeta(groupUUID string) error {
    method updateState (line 197) | func (b *Backend) updateState(s *tasks.TaskState) error {
  function New (line 54) | func New() iface.Backend {

FILE: v2/backends/eager/eager_test.go
  type EagerBackendTestSuite (line 13) | type EagerBackendTestSuite struct
    method SetupSuite (line 24) | func (s *EagerBackendTestSuite) SetupSuite() {
    method TestInitGroup (line 78) | func (s *EagerBackendTestSuite) TestInitGroup() {
    method TestGroupCompleted (line 92) | func (s *EagerBackendTestSuite) TestGroupCompleted() {
    method TestGroupTaskStates (line 149) | func (s *EagerBackendTestSuite) TestGroupTaskStates() {
    method TestSetStatePending (line 182) | func (s *EagerBackendTestSuite) TestSetStatePending() {
    method TestSetStateReceived (line 201) | func (s *EagerBackendTestSuite) TestSetStateReceived() {
    method TestSetStateStarted (line 214) | func (s *EagerBackendTestSuite) TestSetStateStarted() {
    method TestSetStateSuccess (line 227) | func (s *EagerBackendTestSuite) TestSetStateSuccess() {
    method TestSetStateFailure (line 247) | func (s *EagerBackendTestSuite) TestSetStateFailure() {
    method TestSetStateRetry (line 261) | func (s *EagerBackendTestSuite) TestSetStateRetry() {
    method TestGetState (line 274) | func (s *EagerBackendTestSuite) TestGetState() {
    method TestPurgeState (line 281) | func (s *EagerBackendTestSuite) TestPurgeState() {
    method TestPurgeGroupMeta (line 304) | func (s *EagerBackendTestSuite) TestPurgeGroupMeta() {
    method getTaskSignature (line 330) | func (s *EagerBackendTestSuite) getTaskSignature(taskUUID string) *tas...
  function TestEagerBackendMain (line 340) | func TestEagerBackendMain(t *testing.T) {

FILE: v2/backends/iface/dynamodb/api.go
  type API (line 10) | type API interface

FILE: v2/backends/iface/interfaces.go
  type Backend (line 8) | type Backend interface

FILE: v2/backends/memcache/memcache.go
  type Backend (line 18) | type Backend struct
    method InitGroup (line 33) | func (b *Backend) InitGroup(groupUUID string, taskUUIDs []string) error {
    method GroupCompleted (line 53) | func (b *Backend) GroupCompleted(groupUUID string, groupTaskCount int)...
    method GroupTaskStates (line 75) | func (b *Backend) GroupTaskStates(groupUUID string, groupTaskCount int...
    method TriggerChord (line 88) | func (b *Backend) TriggerChord(groupUUID string) (bool, error) {
    method SetStatePending (line 130) | func (b *Backend) SetStatePending(signature *tasks.Signature) error {
    method SetStateReceived (line 136) | func (b *Backend) SetStateReceived(signature *tasks.Signature) error {
    method SetStateStarted (line 142) | func (b *Backend) SetStateStarted(signature *tasks.Signature) error {
    method SetStateRetry (line 148) | func (b *Backend) SetStateRetry(signature *tasks.Signature) error {
    method SetStateSuccess (line 154) | func (b *Backend) SetStateSuccess(signature *tasks.Signature, results ...
    method SetStateFailure (line 160) | func (b *Backend) SetStateFailure(signature *tasks.Signature, err stri...
    method GetState (line 166) | func (b *Backend) GetState(taskUUID string) (*tasks.TaskState, error) {
    method PurgeState (line 183) | func (b *Backend) PurgeState(taskUUID string) error {
    method PurgeGroupMeta (line 188) | func (b *Backend) PurgeGroupMeta(groupUUID string) error {
    method updateState (line 193) | func (b *Backend) updateState(taskState *tasks.TaskState) error {
    method lockGroupMeta (line 207) | func (b *Backend) lockGroupMeta(groupMeta *tasks.GroupMeta) error {
    method unlockGroupMeta (line 222) | func (b *Backend) unlockGroupMeta(groupMeta *tasks.GroupMeta) error {
    method getGroupMeta (line 237) | func (b *Backend) getGroupMeta(groupUUID string) (*tasks.GroupMeta, er...
    method getStates (line 254) | func (b *Backend) getStates(taskUUIDs ...string) ([]*tasks.TaskState, ...
    method getExpirationTimestamp (line 277) | func (b *Backend) getExpirationTimestamp() int32 {
    method getClient (line 287) | func (b *Backend) getClient() *gomemcache.Client {
  function New (line 25) | func New(cnf *config.Config, servers []string) iface.Backend {

FILE: v2/backends/memcache/memcache_test.go
  function TestGroupCompleted (line 14) | func TestGroupCompleted(t *testing.T) {
  function TestGetState (line 73) | func TestGetState(t *testing.T) {
  function TestPurgeState (line 120) | func TestPurgeState(t *testing.T) {

FILE: v2/backends/mongo/mongodb.go
  type Backend (line 24) | type Backend struct
    method InitGroup (line 43) | func (b *Backend) InitGroup(groupUUID string, taskUUIDs []string) error {
    method GroupCompleted (line 54) | func (b *Backend) GroupCompleted(groupUUID string, groupTaskCount int)...
    method GroupTaskStates (line 76) | func (b *Backend) GroupTaskStates(groupUUID string, groupTaskCount int...
    method TriggerChord (line 89) | func (b *Backend) TriggerChord(groupUUID string) (bool, error) {
    method SetStatePending (line 113) | func (b *Backend) SetStatePending(signature *tasks.Signature) error {
    method SetStateReceived (line 123) | func (b *Backend) SetStateReceived(signature *tasks.Signature) error {
    method SetStateStarted (line 129) | func (b *Backend) SetStateStarted(signature *tasks.Signature) error {
    method SetStateRetry (line 135) | func (b *Backend) SetStateRetry(signature *tasks.Signature) error {
    method SetStateSuccess (line 141) | func (b *Backend) SetStateSuccess(signature *tasks.Signature, results ...
    method decodeResults (line 152) | func (b *Backend) decodeResults(results []*tasks.TaskResult) []*tasks....
    method SetStateFailure (line 174) | func (b *Backend) SetStateFailure(signature *tasks.Signature, err stri...
    method GetState (line 184) | func (b *Backend) GetState(taskUUID string) (*tasks.TaskState, error) {
    method PurgeState (line 195) | func (b *Backend) PurgeState(taskUUID string) error {
    method PurgeGroupMeta (line 201) | func (b *Backend) PurgeGroupMeta(groupUUID string) error {
    method lockGroupMeta (line 207) | func (b *Backend) lockGroupMeta(groupUUID string) error {
    method unlockGroupMeta (line 224) | func (b *Backend) unlockGroupMeta(groupUUID string) error {
    method getGroupMeta (line 231) | func (b *Backend) getGroupMeta(groupUUID string) (*tasks.GroupMeta, er...
    method getStates (line 243) | func (b *Backend) getStates(taskUUIDs ...string) ([]*tasks.TaskState, ...
    method updateState (line 265) | func (b *Backend) updateState(signature *tasks.Signature, update bson....
    method tasksCollection (line 271) | func (b *Backend) tasksCollection() *mongo.Collection {
    method groupMetasCollection (line 279) | func (b *Backend) groupMetasCollection() *mongo.Collection {
    method connect (line 289) | func (b *Backend) connect() error {
    method dial (line 314) | func (b *Backend) dial() (*mongo.Client, error) {
    method createMongoIndexes (line 342) | func (b *Backend) createMongoIndexes(database string) error {
  function New (line 33) | func New(cnf *config.Config) (iface.Backend, error) {

FILE: v2/backends/mongo/mongodb_test.go
  function newBackend (line 19) | func newBackend() (iface.Backend, error) {
  function TestNew (line 40) | func TestNew(t *testing.T) {
  function TestSetStatePending (line 51) | func TestSetStatePending(t *testing.T) {
  function TestSetStateReceived (line 72) | func TestSetStateReceived(t *testing.T) {
  function TestSetStateStarted (line 93) | func TestSetStateStarted(t *testing.T) {
  function TestSetStateSuccess (line 114) | func TestSetStateSuccess(t *testing.T) {
  function TestSetStateFailure (line 146) | func TestSetStateFailure(t *testing.T) {
  function TestGroupCompleted (line 170) | func TestGroupCompleted(t *testing.T) {
  function TestGroupStates (line 232) | func TestGroupStates(t *testing.T) {

FILE: v2/backends/null/null.go
  type ErrGroupNotFound (line 13) | type ErrGroupNotFound struct
    method Error (line 23) | func (e ErrGroupNotFound) Error() string {
  function NewErrGroupNotFound (line 18) | func NewErrGroupNotFound(groupUUID string) ErrGroupNotFound {
  type ErrTasknotFound (line 28) | type ErrTasknotFound struct
    method Error (line 38) | func (e ErrTasknotFound) Error() string {
  function NewErrTasknotFound (line 33) | func NewErrTasknotFound(taskUUID string) ErrTasknotFound {
  type Backend (line 43) | type Backend struct
    method InitGroup (line 57) | func (b *Backend) InitGroup(groupUUID string, taskUUIDs []string) error {
    method GroupCompleted (line 63) | func (b *Backend) GroupCompleted(groupUUID string, groupTaskCount int)...
    method GroupTaskStates (line 73) | func (b *Backend) GroupTaskStates(groupUUID string, groupTaskCount int...
    method TriggerChord (line 84) | func (b *Backend) TriggerChord(groupUUID string) (bool, error) {
    method SetStatePending (line 89) | func (b *Backend) SetStatePending(signature *tasks.Signature) error {
    method SetStateReceived (line 95) | func (b *Backend) SetStateReceived(signature *tasks.Signature) error {
    method SetStateStarted (line 101) | func (b *Backend) SetStateStarted(signature *tasks.Signature) error {
    method SetStateRetry (line 107) | func (b *Backend) SetStateRetry(signature *tasks.Signature) error {
    method SetStateSuccess (line 113) | func (b *Backend) SetStateSuccess(signature *tasks.Signature, results ...
    method SetStateFailure (line 119) | func (b *Backend) SetStateFailure(signature *tasks.Signature, err stri...
    method GetState (line 125) | func (b *Backend) GetState(taskUUID string) (*tasks.TaskState, error) {
    method PurgeState (line 130) | func (b *Backend) PurgeState(taskUUID string) error {
    method PurgeGroupMeta (line 135) | func (b *Backend) PurgeGroupMeta(groupUUID string) error {
    method updateState (line 144) | func (b *Backend) updateState(s *tasks.TaskState) error {
  function New (line 49) | func New() iface.Backend {

FILE: v2/backends/redis/goredis.go
  type BackendGR (line 23) | type BackendGR struct
    method InitGroup (line 83) | func (b *BackendGR) InitGroup(groupUUID string, taskUUIDs []string) er...
    method GroupCompleted (line 105) | func (b *BackendGR) GroupCompleted(groupUUID string, groupTaskCount in...
    method GroupTaskStates (line 127) | func (b *BackendGR) GroupTaskStates(groupUUID string, groupTaskCount i...
    method TriggerChord (line 140) | func (b *BackendGR) TriggerChord(groupUUID string) (bool, error) {
    method mergeNewTaskState (line 175) | func (b *BackendGR) mergeNewTaskState(newState *tasks.TaskState) {
    method SetStatePending (line 184) | func (b *BackendGR) SetStatePending(signature *tasks.Signature) error {
    method SetStateReceived (line 190) | func (b *BackendGR) SetStateReceived(signature *tasks.Signature) error {
    method SetStateStarted (line 197) | func (b *BackendGR) SetStateStarted(signature *tasks.Signature) error {
    method SetStateRetry (line 204) | func (b *BackendGR) SetStateRetry(signature *tasks.Signature) error {
    method SetStateSuccess (line 211) | func (b *BackendGR) SetStateSuccess(signature *tasks.Signature, result...
    method SetStateFailure (line 218) | func (b *BackendGR) SetStateFailure(signature *tasks.Signature, err st...
    method GetState (line 225) | func (b *BackendGR) GetState(taskUUID string) (*tasks.TaskState, error) {
    method PurgeState (line 242) | func (b *BackendGR) PurgeState(taskUUID string) error {
    method PurgeGroupMeta (line 252) | func (b *BackendGR) PurgeGroupMeta(groupUUID string) error {
    method getGroupMeta (line 262) | func (b *BackendGR) getGroupMeta(groupUUID string) (*tasks.GroupMeta, ...
    method getStates (line 279) | func (b *BackendGR) getStates(taskUUIDs ...string) ([]*tasks.TaskState...
    method updateState (line 310) | func (b *BackendGR) updateState(taskState *tasks.TaskState) error {
    method getExpiration (line 326) | func (b *BackendGR) getExpiration() time.Duration {
  function NewGR (line 36) | func NewGR(cnf *config.Config, addrs []string, db int) iface.Backend {

FILE: v2/backends/redis/goredis_test.go
  function getRedisG (line 15) | func getRedisG() iface.Backend {
  function TestGroupCompletedGR (line 26) | func TestGroupCompletedGR(t *testing.T) {
  function TestGetStateGR (line 83) | func TestGetStateGR(t *testing.T) {
  function TestPurgeStateGR (line 141) | func TestPurgeStateGR(t *testing.T) {

FILE: v2/backends/redis/redis.go
  type Backend (line 22) | type Backend struct
    method InitGroup (line 49) | func (b *Backend) InitGroup(groupUUID string, taskUUIDs []string) error {
    method GroupCompleted (line 74) | func (b *Backend) GroupCompleted(groupUUID string, groupTaskCount int)...
    method GroupTaskStates (line 99) | func (b *Backend) GroupTaskStates(groupUUID string, groupTaskCount int...
    method TriggerChord (line 115) | func (b *Backend) TriggerChord(groupUUID string) (bool, error) {
    method mergeNewTaskState (line 153) | func (b *Backend) mergeNewTaskState(conn redis.Conn, newState *tasks.T...
    method SetStatePending (line 162) | func (b *Backend) SetStatePending(signature *tasks.Signature) error {
    method SetStateReceived (line 171) | func (b *Backend) SetStateReceived(signature *tasks.Signature) error {
    method SetStateStarted (line 181) | func (b *Backend) SetStateStarted(signature *tasks.Signature) error {
    method SetStateRetry (line 191) | func (b *Backend) SetStateRetry(signature *tasks.Signature) error {
    method SetStateSuccess (line 201) | func (b *Backend) SetStateSuccess(signature *tasks.Signature, results ...
    method SetStateFailure (line 211) | func (b *Backend) SetStateFailure(signature *tasks.Signature, err stri...
    method GetState (line 221) | func (b *Backend) GetState(taskUUID string) (*tasks.TaskState, error) {
    method getState (line 228) | func (b *Backend) getState(conn redis.Conn, taskUUID string) (*tasks.T...
    method PurgeState (line 244) | func (b *Backend) PurgeState(taskUUID string) error {
    method PurgeGroupMeta (line 257) | func (b *Backend) PurgeGroupMeta(groupUUID string) error {
    method getGroupMeta (line 270) | func (b *Backend) getGroupMeta(conn redis.Conn, groupUUID string) (*ta...
    method getStates (line 288) | func (b *Backend) getStates(conn redis.Conn, taskUUIDs ...string) ([]*...
    method updateState (line 323) | func (b *Backend) updateState(conn redis.Conn, taskState *tasks.TaskSt...
    method getExpiration (line 339) | func (b *Backend) getExpiration() time.Duration {
    method open (line 350) | func (b *Backend) open() redis.Conn {
  function New (line 37) | func New(cnf *config.Config, host, username, password, socketPath string...

FILE: v2/backends/redis/redis_test.go
  function TestGroupCompleted (line 13) | func TestGroupCompleted(t *testing.T) {
  function TestGetState (line 74) | func TestGetState(t *testing.T) {
  function TestPurgeState (line 136) | func TestPurgeState(t *testing.T) {

FILE: v2/backends/result/async_result.go
  type AsyncResult (line 20) | type AsyncResult struct
    method Touch (line 74) | func (asyncResult *AsyncResult) Touch() ([]reflect.Value, error) {
    method Get (line 98) | func (asyncResult *AsyncResult) Get(sleepDuration time.Duration) ([]re...
    method GetWithTimeout (line 111) | func (asyncResult *AsyncResult) GetWithTimeout(timeoutDuration, sleepD...
    method GetState (line 131) | func (asyncResult *AsyncResult) GetState() *tasks.TaskState {
  type ChordAsyncResult (line 27) | type ChordAsyncResult struct
    method Get (line 166) | func (chordAsyncResult *ChordAsyncResult) Get(sleepDuration time.Durat...
    method GetWithTimeout (line 223) | func (chordAsyncResult *ChordAsyncResult) GetWithTimeout(timeoutDurati...
  type ChainAsyncResult (line 34) | type ChainAsyncResult struct
    method Get (line 145) | func (chainAsyncResult *ChainAsyncResult) Get(sleepDuration time.Durat...
    method GetWithTimeout (line 183) | func (chainAsyncResult *ChainAsyncResult) GetWithTimeout(timeoutDurati...
  function NewAsyncResult (line 40) | func NewAsyncResult(signature *tasks.Signature, backend iface.Backend) *...
  function NewChordAsyncResult (line 49) | func NewChordAsyncResult(groupTasks []*tasks.Signature, chordCallback *t...
  function NewChainAsyncResult (line 62) | func NewChainAsyncResult(tasks []*tasks.Signature, backend iface.Backend...

FILE: v2/brokers/amqp/amqp.go
  type AMQPConnection (line 21) | type AMQPConnection struct
  type Broker (line 32) | type Broker struct
    method StartConsuming (line 47) | func (b *Broker) StartConsuming(consumerTag string, concurrency int, t...
    method StopConsuming (line 109) | func (b *Broker) StopConsuming() {
    method GetOrOpenConnection (line 118) | func (b *Broker) GetOrOpenConnection(queueName string, queueBindingKey...
    method CloseConnections (line 169) | func (b *Broker) CloseConnections() error {
    method Publish (line 185) | func (b *Broker) Publish(ctx context.Context, signature *tasks.Signatu...
    method consume (line 254) | func (b *Broker) consume(deliveries <-chan amqp.Delivery, concurrency ...
    method consumeOne (line 304) | func (b *Broker) consumeOne(delivery amqp.Delivery, taskProcessor ifac...
    method delay (line 345) | func (b *Broker) delay(signature *tasks.Signature, delayMs int64) error {
    method isDirectExchange (line 430) | func (b *Broker) isDirectExchange() bool {
    method AdjustRoutingKey (line 438) | func (b *Broker) AdjustRoutingKey(s *tasks.Signature) {
    method GetPendingTasks (line 472) | func (b *Broker) GetPendingTasks(queue string) ([]*tasks.Signature, er...
  function New (line 42) | func New(cnf *config.Config) iface.Broker {
  type sigDumper (line 454) | type sigDumper struct
    method Process (line 459) | func (s *sigDumper) Process(sig *tasks.Signature) error {
    method CustomQueue (line 464) | func (s *sigDumper) CustomQueue() string {
    method PreConsumeHandler (line 468) | func (_ *sigDumper) PreConsumeHandler() bool {

FILE: v2/brokers/amqp/amqp_concurrence_test.go
  type doNothingProcessor (line 13) | type doNothingProcessor struct
    method Process (line 15) | func (_ doNothingProcessor) Process(signature *tasks.Signature) error {
    method CustomQueue (line 19) | func (_ doNothingProcessor) CustomQueue() string {
    method PreConsumeHandler (line 23) | func (_ doNothingProcessor) PreConsumeHandler() bool {
  function TestConsume (line 27) | func TestConsume(t *testing.T) {

FILE: v2/brokers/amqp/amqp_test.go
  function TestAdjustRoutingKey (line 13) | func TestAdjustRoutingKey(t *testing.T) {

FILE: v2/brokers/eager/eager.go
  type Broker (line 16) | type Broker struct
    method StartConsuming (line 32) | func (eagerBroker *Broker) StartConsuming(consumerTag string, concurre...
    method StopConsuming (line 37) | func (eagerBroker *Broker) StopConsuming() {
    method Publish (line 42) | func (eagerBroker *Broker) Publish(ctx context.Context, task *tasks.Si...
    method AssignWorker (line 66) | func (eagerBroker *Broker) AssignWorker(w iface.TaskProcessor) {
  function New (line 22) | func New() iface.Broker {
  type Mode (line 27) | type Mode interface

FILE: v2/brokers/errs/errors.go
  type ErrCouldNotUnmarshalTaskSignature (line 9) | type ErrCouldNotUnmarshalTaskSignature struct
    method Error (line 15) | func (e ErrCouldNotUnmarshalTaskSignature) Error() string {
  function NewErrCouldNotUnmarshalTaskSignature (line 20) | func NewErrCouldNotUnmarshalTaskSignature(msg []byte, err error) ErrCoul...

FILE: v2/brokers/gcppubsub/gcp_pubsub.go
  type Broker (line 19) | type Broker struct
    method StartConsuming (line 85) | func (b *Broker) StartConsuming(consumerTag string, concurrency int, t...
    method StopConsuming (line 121) | func (b *Broker) StopConsuming() {
    method Publish (line 130) | func (b *Broker) Publish(ctx context.Context, signature *tasks.Signatu...
    method consumeOne (line 167) | func (b *Broker) consumeOne(delivery *pubsub.Message, taskProcessor if...
  function New (line 30) | func New(cnf *config.Config, projectID, subscriptionName string) (iface....

FILE: v2/brokers/iface/interfaces.go
  type Broker (line 11) | type Broker interface
  type TaskProcessor (line 25) | type TaskProcessor interface

FILE: v2/brokers/iface/sqs/api.go
  type API (line 10) | type API interface

FILE: v2/brokers/redis/goredis.go
  type BrokerGR (line 26) | type BrokerGR struct
    method StartConsuming (line 90) | func (b *BrokerGR) StartConsuming(consumerTag string, concurrency int,...
    method StopConsuming (line 191) | func (b *BrokerGR) StopConsuming() {
    method Publish (line 202) | func (b *BrokerGR) Publish(ctx context.Context, signature *tasks.Signa...
    method GetPendingTasks (line 228) | func (b *BrokerGR) GetPendingTasks(queue string) ([]*tasks.Signature, ...
    method GetDelayedTasks (line 252) | func (b *BrokerGR) GetDelayedTasks() ([]*tasks.Signature, error) {
    method consume (line 273) | func (b *BrokerGR) consume(deliveries <-chan []byte, concurrency int, ...
    method consumeOne (line 318) | func (b *BrokerGR) consumeOne(delivery []byte, taskProcessor iface.Tas...
    method nextTask (line 344) | func (b *BrokerGR) nextTask(queue string) (result []byte, err error) {
    method nextDelayedTask (line 372) | func (b *BrokerGR) nextDelayedTask(key string) (result []byte, err err...
  function NewGR (line 40) | func NewGR(cnf *config.Config, addrs []string, db int) iface.Broker {
  function getQueueGR (line 439) | func getQueueGR(config *config.Config, taskProcessor iface.TaskProcessor...

FILE: v2/brokers/redis/redis.go
  constant defaultRedisDelayedTasksKey (line 25) | defaultRedisDelayedTasksKey = "delayed_tasks"
  type Broker (line 28) | type Broker struct
    method StartConsuming (line 65) | func (b *Broker) StartConsuming(consumerTag string, concurrency int, t...
    method StopConsuming (line 185) | func (b *Broker) StopConsuming() {
    method Publish (line 200) | func (b *Broker) Publish(ctx context.Context, signature *tasks.Signatu...
    method GetPendingTasks (line 229) | func (b *Broker) GetPendingTasks(queue string) ([]*tasks.Signature, er...
    method GetDelayedTasks (line 259) | func (b *Broker) GetDelayedTasks() ([]*tasks.Signature, error) {
    method consume (line 287) | func (b *Broker) consume(deliveries <-chan []byte, concurrency int, ta...
    method consumeOne (line 340) | func (b *Broker) consumeOne(delivery []byte, taskProcessor iface.TaskP...
    method nextTask (line 365) | func (b *Broker) nextTask(queue string) (result []byte, err error) {
    method nextDelayedTask (line 403) | func (b *Broker) nextDelayedTask(key string) (result []byte, err error) {
    method open (line 478) | func (b *Broker) open() redis.Conn {
    method requeueMessage (line 495) | func (b *Broker) requeueMessage(delivery []byte, taskProcessor iface.T...
  function New (line 47) | func New(cnf *config.Config, host, username, password, socketPath string...
  function getQueue (line 487) | func getQueue(config *config.Config, taskProcessor iface.TaskProcessor) ...

FILE: v2/brokers/sqs/sqs.go
  constant maxAWSSQSDelay (line 26) | maxAWSSQSDelay = time.Minute * 15
  type Broker (line 31) | type Broker struct
    method StartConsuming (line 59) | func (b *Broker) StartConsuming(consumerTag string, concurrency int, t...
    method StopConsuming (line 112) | func (b *Broker) StopConsuming() {
    method Publish (line 125) | func (b *Broker) Publish(ctx context.Context, signature *tasks.Signatu...
    method consume (line 179) | func (b *Broker) consume(deliveries <-chan *sqs.ReceiveMessageOutput, ...
    method consumeOne (line 195) | func (b *Broker) consumeOne(delivery *sqs.ReceiveMessageOutput, taskPr...
    method deleteOne (line 257) | func (b *Broker) deleteOne(delivery *sqs.ReceiveMessageOutput) error {
    method defaultQueueURL (line 271) | func (b *Broker) defaultQueueURL() *string {
    method receiveMessage (line 281) | func (b *Broker) receiveMessage(qURL *string) (*sqs.ReceiveMessageOutp...
    method initializePool (line 311) | func (b *Broker) initializePool(pool chan struct{}, concurrency int) {
    method consumeDeliveries (line 318) | func (b *Broker) consumeDeliveries(deliveries <-chan *sqs.ReceiveMessa...
    method continueReceivingMessages (line 348) | func (b *Broker) continueReceivingMessages(qURL *string, deliveries ch...
    method visibilityHeartbeat (line 367) | func (b *Broker) visibilityHeartbeat(delivery *sqs.ReceiveMessageOutpu...
    method stopReceiving (line 401) | func (b *Broker) stopReceiving() {
    method getQueueURL (line 408) | func (b *Broker) getQueueURL(taskProcessor iface.TaskProcessor) *string {
  function New (line 41) | func New(cnf *config.Config) (iface.Broker, error) {

FILE: v2/brokers/sqs/sqs_export_test.go
  type FakeSQS (line 25) | type FakeSQS struct
    method SendMessage (line 29) | func (f *FakeSQS) SendMessage(context.Context, *awssqs.SendMessageInpu...
    method ReceiveMessage (line 38) | func (f *FakeSQS) ReceiveMessage(context.Context, *awssqs.ReceiveMessa...
    method DeleteMessage (line 42) | func (f *FakeSQS) DeleteMessage(context.Context, *awssqs.DeleteMessage...
  type ErrorSQS (line 46) | type ErrorSQS struct
    method SendMessage (line 50) | func (e *ErrorSQS) SendMessage(context.Context, *awssqs.SendMessageInp...
    method ReceiveMessage (line 55) | func (e *ErrorSQS) ReceiveMessage(context.Context, *awssqs.ReceiveMess...
    method DeleteMessage (line 60) | func (e *ErrorSQS) DeleteMessage(context.Context, *awssqs.DeleteMessag...
  function init (line 65) | func init() {
  function NewTestConfig (line 98) | func NewTestConfig() *config.Config {
  function NewTestBroker (line 116) | func NewTestBroker(cnf *config.Config) *Broker {
  function NewTestErrorBroker (line 132) | func NewTestErrorBroker() *Broker {
  method ConsumeForTest (line 146) | func (b *Broker) ConsumeForTest(deliveries <-chan *awssqs.ReceiveMessage...
  method ConsumeOneForTest (line 150) | func (b *Broker) ConsumeOneForTest(delivery *awssqs.ReceiveMessageOutput...
  method DeleteOneForTest (line 154) | func (b *Broker) DeleteOneForTest(delivery *awssqs.ReceiveMessageOutput)...
  method DefaultQueueURLForTest (line 158) | func (b *Broker) DefaultQueueURLForTest() *string {
  method ReceiveMessageForTest (line 162) | func (b *Broker) ReceiveMessageForTest(qURL *string) (*awssqs.ReceiveMes...
  method InitializePoolForTest (line 166) | func (b *Broker) InitializePoolForTest(pool chan struct{}, concurrency i...
  method ConsumeDeliveriesForTest (line 170) | func (b *Broker) ConsumeDeliveriesForTest(deliveries <-chan *awssqs.Rece...
  method ContinueReceivingMessagesForTest (line 174) | func (b *Broker) ContinueReceivingMessagesForTest(qURL *string, deliveri...
  method StopReceivingForTest (line 178) | func (b *Broker) StopReceivingForTest() {
  method GetStopReceivingChanForTest (line 182) | func (b *Broker) GetStopReceivingChanForTest() chan int {
  method StartConsumingForTest (line 186) | func (b *Broker) StartConsumingForTest(consumerTag string, concurrency i...
  method GetRetryFuncForTest (line 190) | func (b *Broker) GetRetryFuncForTest() func(chan int) {
  method GetStopChanForTest (line 194) | func (b *Broker) GetStopChanForTest() chan int {
  method GetRetryStopChanForTest (line 198) | func (b *Broker) GetRetryStopChanForTest() chan int {
  method GetQueueURLForTest (line 202) | func (b *Broker) GetQueueURLForTest(taskProcessor iface.TaskProcessor) *...
  method GetCustomQueueURL (line 206) | func (b *Broker) GetCustomQueueURL(customQueue string) *string {

FILE: v2/brokers/sqs/sqs_test.go
  function init (line 31) | func init() {
  function TestNewAWSSQSBroker (line 36) | func TestNewAWSSQSBroker(t *testing.T) {
  function TestPrivateFunc_continueReceivingMessages (line 47) | func TestPrivateFunc_continueReceivingMessages(t *testing.T) {
  function TestPrivateFunc_consume (line 96) | func TestPrivateFunc_consume(t *testing.T) {
  function TestPrivateFunc_consumeOne (line 113) | func TestPrivateFunc_consumeOne(t *testing.T) {
  function TestPrivateFunc_consumeOneWithVisibilityHeartBeat (line 135) | func TestPrivateFunc_consumeOneWithVisibilityHeartBeat(t *testing.T) {
  function TestPrivateFunc_initializePool (line 177) | func TestPrivateFunc_initializePool(t *testing.T) {
  function TestPrivateFunc_startConsuming (line 187) | func TestPrivateFunc_startConsuming(t *testing.T) {
  function TestPrivateFuncDefaultQueueURL (line 205) | func TestPrivateFuncDefaultQueueURL(t *testing.T) {
  function TestPrivateFunc_stopReceiving (line 214) | func TestPrivateFunc_stopReceiving(t *testing.T) {
  function TestPrivateFunc_receiveMessage (line 224) | func TestPrivateFunc_receiveMessage(t *testing.T) {
  function TestPrivateFunc_consumeDeliveries (line 234) | func TestPrivateFunc_consumeDeliveries(t *testing.T) {
  function TestPrivateFunc_deleteOne (line 291) | func TestPrivateFunc_deleteOne(t *testing.T) {
  function Test_CustomQueueName (line 303) | func Test_CustomQueueName(t *testing.T) {
  function TestPrivateFunc_consumeWithConcurrency (line 318) | func TestPrivateFunc_consumeWithConcurrency(t *testing.T) {
  type MockSQSAPI (line 375) | type MockSQSAPI struct
    method ReceiveMessage (line 381) | func (m *MockSQSAPI) ReceiveMessage(ctx context.Context, input *awssqs...
    method DeleteMessage (line 386) | func (m *MockSQSAPI) DeleteMessage(ctx context.Context, input *awssqs....
    method ChangeMessageVisibility (line 391) | func (m *MockSQSAPI) ChangeMessageVisibility(ctx context.Context, inpu...

FILE: v2/common/amqp.go
  type AMQPConnector (line 12) | type AMQPConnector struct
    method Connect (line 16) | func (ac *AMQPConnector) Connect(urls string, urlSeparator string, tls...
    method DeleteQueue (line 91) | func (ac *AMQPConnector) DeleteQueue(channel *amqp.Channel, queueName ...
    method InspectQueue (line 104) | func (*AMQPConnector) InspectQueue(channel *amqp.Channel, queueName st...
    method Open (line 114) | func (ac *AMQPConnector) Open(url string, tlsConfig *tls.Config) (*amq...
    method Close (line 133) | func (ac *AMQPConnector) Close(channel *amqp.Channel, conn *amqp.Conne...

FILE: v2/common/backend.go
  type Backend (line 8) | type Backend struct
    method GetConfig (line 18) | func (b *Backend) GetConfig() *config.Config {
    method IsAMQP (line 23) | func (b *Backend) IsAMQP() bool {
  function NewBackend (line 13) | func NewBackend(cnf *config.Config) Backend {

FILE: v2/common/broker.go
  type registeredTaskNames (line 14) | type registeredTaskNames struct
  type Broker (line 20) | type Broker struct
    method GetConfig (line 40) | func (b *Broker) GetConfig() *config.Config {
    method GetRetry (line 45) | func (b *Broker) GetRetry() bool {
    method GetRetryFunc (line 50) | func (b *Broker) GetRetryFunc() func(chan int) {
    method GetRetryStopChan (line 55) | func (b *Broker) GetRetryStopChan() chan int {
    method GetStopChan (line 60) | func (b *Broker) GetStopChan() chan int {
    method Publish (line 65) | func (b *Broker) Publish(signature *tasks.Signature) error {
    method SetRegisteredTaskNames (line 70) | func (b *Broker) SetRegisteredTaskNames(names []string) {
    method IsTaskRegistered (line 77) | func (b *Broker) IsTaskRegistered(name string) bool {
    method GetPendingTasks (line 89) | func (b *Broker) GetPendingTasks(queue string) ([]*tasks.Signature, er...
    method GetDelayedTasks (line 94) | func (b *Broker) GetDelayedTasks() ([]*tasks.Signature, error) {
    method StartConsuming (line 99) | func (b *Broker) StartConsuming(consumerTag string, concurrency int, t...
    method StopConsuming (line 107) | func (b *Broker) StopConsuming() {
    method GetRegisteredTaskNames (line 122) | func (b *Broker) GetRegisteredTaskNames() []string {
    method AdjustRoutingKey (line 133) | func (b *Broker) AdjustRoutingKey(s *tasks.Signature) {
  function NewBroker (line 30) | func NewBroker(cnf *config.Config) Broker {

FILE: v2/common/broker_test.go
  function TestIsTaskRegistered (line 13) | func TestIsTaskRegistered(t *testing.T) {
  function TestAdjustRoutingKey (line 23) | func TestAdjustRoutingKey(t *testing.T) {
  function TestGetRegisteredTaskNames (line 50) | func TestGetRegisteredTaskNames(t *testing.T) {
  function TestStopConsuming (line 59) | func TestStopConsuming(t *testing.T) {

FILE: v2/common/redis.go
  type RedisConnector (line 27) | type RedisConnector struct
    method NewPool (line 30) | func (rc *RedisConnector) NewPool(socketPath, host, username, password...
    method open (line 66) | func (rc *RedisConnector) open(socketPath, host, username, password st...

FILE: v2/config/config.go
  constant DefaultResultsExpireIn (line 17) | DefaultResultsExpireIn = 3600
  type Config (line 55) | type Config struct
  type QueueBindingArgs (line 74) | type QueueBindingArgs
    method Decode (line 182) | func (args *QueueBindingArgs) Decode(value string) error {
  type QueueDeclareArgs (line 77) | type QueueDeclareArgs
  type AMQPConfig (line 80) | type AMQPConfig struct
  type DynamoDBConfig (line 92) | type DynamoDBConfig struct
  type SQSConfig (line 99) | type SQSConfig struct
  type RedisConfig (line 111) | type RedisConfig struct
  type GCPPubSubConfig (line 169) | type GCPPubSubConfig struct
  type MongoDBConfig (line 175) | type MongoDBConfig struct

FILE: v2/config/env.go
  function NewFromEnvironment (line 10) | func NewFromEnvironment() (*Config, error) {
  function fromEnvironment (line 21) | func fromEnvironment() (*Config, error) {

FILE: v2/config/env_test.go
  function TestNewFromEnvironment (line 13) | func TestNewFromEnvironment(t *testing.T) {

FILE: v2/config/file.go
  function NewFromYaml (line 13) | func NewFromYaml(cnfPath string, keepReloading bool) (*Config, error) {
  function ReadFromFile (line 44) | func ReadFromFile(cnfPath string) ([]byte, error) {
  function fromFile (line 63) | func fromFile(cnfPath string) (*Config, error) {

FILE: v2/config/file_test.go
  function TestReadFromFile (line 46) | func TestReadFromFile(t *testing.T) {
  function TestNewFromYaml (line 57) | func TestNewFromYaml(t *testing.T) {

FILE: v2/example/amqp/main.go
  function init (line 31) | func init() {
  function main (line 39) | func main() {
  function startServer (line 68) | func startServer() (*machinery.Server, error) {
  function worker (line 103) | func worker() error {
  function send (line 142) | func send() error {

FILE: v2/example/go-redis/main.go
  function init (line 31) | func init() {
  function main (line 39) | func main() {
  function startServer (line 68) | func startServer() (*machinery.Server, error) {
  function worker (line 104) | func worker() error {
  function send (line 143) | func send() error {

FILE: v2/example/redigo/main.go
  function init (line 31) | func init() {
  function main (line 39) | func main() {
  function startServer (line 68) | func startServer() (*machinery.Server, error) {
  function worker (line 104) | func worker() error {
  function send (line 143) | func send() error {

FILE: v2/example/tasks/tasks.go
  function Add (line 12) | func Add(args ...int64) (int64, error) {
  function Multiply (line 21) | func Multiply(args ...int64) (int64, error) {
  function SumInts (line 30) | func SumInts(numbers []int64) (int64, error) {
  function SumFloats (line 39) | func SumFloats(numbers []float64) (float64, error) {
  function Concat (line 48) | func Concat(strs []string) (string, error) {
  function Split (line 57) | func Split(str string) ([]string, error) {
  function PanicTask (line 62) | func PanicTask() (string, error) {
  function LongRunningTask (line 67) | func LongRunningTask() error {

FILE: v2/example/tracers/jaeger.go
  function SetupTracer (line 20) | func SetupTracer(serviceName string) (func(), error) {

FILE: v2/integration-tests/amqp_amqp_test.go
  function TestAmqpAmqp (line 15) | func TestAmqpAmqp(t *testing.T) {

FILE: v2/integration-tests/redis_redis_test.go
  function TestRedisRedis_GoRedis (line 14) | func TestRedisRedis_GoRedis(t *testing.T) {

FILE: v2/integration-tests/suite_test.go
  type ascendingInt64s (line 20) | type ascendingInt64s
    method Len (line 22) | func (a ascendingInt64s) Len() int           { return len(a) }
    method Swap (line 23) | func (a ascendingInt64s) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
    method Less (line 24) | func (a ascendingInt64s) Less(i, j int) bool { return a[i] < a[j] }
  type Server (line 26) | type Server interface
  function testAll (line 40) | func testAll(server Server, t *testing.T) {
  function testSendTask (line 52) | func testSendTask(server Server, t *testing.T) {
  function testSendGroup (line 101) | func testSendGroup(server Server, t *testing.T, sendConcurrency int) {
  function testSendChain (line 146) | func testSendChain(server Server, t *testing.T) {
  function testSendChord (line 177) | func testSendChord(server Server, t *testing.T) {
  function testReturnJustError (line 213) | func testReturnJustError(server Server, t *testing.T) {
  function testReturnMultipleValues (line 241) | func testReturnMultipleValues(server Server, t *testing.T) {
  function testPanic (line 290) | func testPanic(server Server, t *testing.T) {
  function testDelay (line 304) | func testDelay(server Server, t *testing.T) {
  function registerTestTasks (line 341) | func registerTestTasks(server Server) {
  function newAddTask (line 391) | func newAddTask(a, b int) *tasks.Signature {
  function newMultipleTask (line 407) | func newMultipleTask(nums ...int) *tasks.Signature {
  function newSumTask (line 421) | func newSumTask(nums []int64) *tasks.Signature {
  function newErrorTask (line 433) | func newErrorTask(msg string, fail bool) *tasks.Signature {
  function newMultipleReturnTask (line 449) | func newMultipleReturnTask(arg1, arg2 string, fail bool) *tasks.Signature {
  function newDelayTask (line 469) | func newDelayTask(eta time.Time) *tasks.Signature {

FILE: v2/locks/eager/eager.go
  type Lock (line 13) | type Lock struct
    method LockWithRetries (line 33) | func (e *Lock) LockWithRetries(key string, value int64) error {
    method Lock (line 46) | func (e *Lock) Lock(key string, value int64) error {
  function New (line 22) | func New() *Lock {

FILE: v2/locks/eager/eager_test.go
  function TestLock_Lock (line 11) | func TestLock_Lock(t *testing.T) {
  function TestLock_LockWithRetries (line 25) | func TestLock_LockWithRetries(t *testing.T) {
  function TestNew (line 39) | func TestNew(t *testing.T) {

FILE: v2/locks/iface/interfaces.go
  type Lock (line 3) | type Lock interface

FILE: v2/locks/redis/redis.go
  type Lock (line 19) | type Lock struct
    method LockWithRetries (line 61) | func (r Lock) LockWithRetries(key string, unixTsToExpireNs int64) error {
    method Lock (line 74) | func (r Lock) Lock(key string, unixTsToExpireNs int64) error {
  function New (line 25) | func New(cnf *config.Config, addrs []string, db, retries int) Lock {

FILE: v2/log/log.go
  function Set (line 23) | func Set(l logging.LoggerInterface) {
  function SetDebug (line 32) | func SetDebug(l logging.LoggerInterface) {
  function SetInfo (line 37) | func SetInfo(l logging.LoggerInterface) {
  function SetWarning (line 42) | func SetWarning(l logging.LoggerInterface) {
  function SetError (line 47) | func SetError(l logging.LoggerInterface) {
  function SetFatal (line 52) | func SetFatal(l logging.LoggerInterface) {

FILE: v2/log/log_test.go
  function TestDefaultLogger (line 9) | func TestDefaultLogger(t *testing.T) {

FILE: v2/retry/fibonacci.go
  function Fibonacci (line 4) | func Fibonacci() func() int {
  function FibonacciNext (line 13) | func FibonacciNext(start int) int {

FILE: v2/retry/fibonacci_test.go
  function TestFibonacci (line 10) | func TestFibonacci(t *testing.T) {
  function TestFibonacciNext (line 25) | func TestFibonacciNext(t *testing.T) {

FILE: v2/server.go
  type Server (line 28) | type Server struct
    method NewWorker (line 56) | func (server *Server) NewWorker(consumerTag string, concurrency int) *...
    method NewCustomQueueWorker (line 66) | func (server *Server) NewCustomQueueWorker(consumerTag string, concurr...
    method GetBroker (line 76) | func (server *Server) GetBroker() brokersiface.Broker {
    method SetBroker (line 81) | func (server *Server) SetBroker(broker brokersiface.Broker) {
    method GetBackend (line 86) | func (server *Server) GetBackend() backendsiface.Backend {
    method SetBackend (line 91) | func (server *Server) SetBackend(backend backendsiface.Backend) {
    method GetConfig (line 96) | func (server *Server) GetConfig() *config.Config {
    method SetConfig (line 101) | func (server *Server) SetConfig(cnf *config.Config) {
    method SetPreTaskHandler (line 106) | func (server *Server) SetPreTaskHandler(handler func(*tasks.Signature)) {
    method RegisterTasks (line 111) | func (server *Server) RegisterTasks(namedTaskFuncs map[string]interfac...
    method RegisterTask (line 125) | func (server *Server) RegisterTask(name string, taskFunc interface{}) ...
    method IsTaskRegistered (line 135) | func (server *Server) IsTaskRegistered(name string) bool {
    method GetRegisteredTask (line 141) | func (server *Server) GetRegisteredTask(name string) (interface{}, err...
    method SendTaskWithContext (line 150) | func (server *Server) SendTaskWithContext(ctx context.Context, signatu...
    method SendTask (line 185) | func (server *Server) SendTask(signature *tasks.Signature) (*result.As...
    method SendChainWithContext (line 190) | func (server *Server) SendChainWithContext(ctx context.Context, chain ...
    method SendChain (line 200) | func (server *Server) SendChain(chain *tasks.Chain) (*result.ChainAsyn...
    method SendGroupWithContext (line 210) | func (server *Server) SendGroupWithContext(ctx context.Context, group ...
    method SendGroup (line 286) | func (server *Server) SendGroup(group *tasks.Group, sendConcurrency in...
    method SendChordWithContext (line 291) | func (server *Server) SendChordWithContext(ctx context.Context, chord ...
    method SendChord (line 310) | func (server *Server) SendChord(chord *tasks.Chord, sendConcurrency in...
    method GetRegisteredTaskNames (line 315) | func (server *Server) GetRegisteredTaskNames() []string {
    method RegisterPeriodicTask (line 326) | func (server *Server) RegisterPeriodicTask(spec, name string, signatur...
    method RegisterPeriodicChain (line 352) | func (server *Server) RegisterPeriodicChain(spec, name string, signatu...
    method RegisterPeriodicGroup (line 381) | func (server *Server) RegisterPeriodicGroup(spec, name string, sendCon...
    method RegisterPeriodicChord (line 410) | func (server *Server) RegisterPeriodicChord(spec, name string, sendCon...
  function NewServer (line 39) | func NewServer(cnf *config.Config, brokerServer brokersiface.Broker, bac...

FILE: v2/server_test.go
  function TestRegisterTasks (line 16) | func TestRegisterTasks(t *testing.T) {
  function TestRegisterTask (line 29) | func TestRegisterTask(t *testing.T) {
  function TestGetRegisteredTask (line 40) | func TestGetRegisteredTask(t *testing.T) {
  function TestGetRegisteredTaskNames (line 48) | func TestGetRegisteredTaskNames(t *testing.T) {
  function TestNewWorker (line 62) | func TestNewWorker(t *testing.T) {
  function TestNewCustomQueueWorker (line 71) | func TestNewCustomQueueWorker(t *testing.T) {
  function getTestServer (line 80) | func getTestServer(t *testing.T) *machinery.Server {

FILE: v2/tasks/errors.go
  type ErrRetryTaskLater (line 9) | type ErrRetryTaskLater struct
    method RetryIn (line 15) | func (e ErrRetryTaskLater) RetryIn() time.Duration {
    method Error (line 20) | func (e ErrRetryTaskLater) Error() string {
  function NewErrRetryTaskLater (line 25) | func NewErrRetryTaskLater(msg string, retryIn time.Duration) ErrRetryTas...
  type Retriable (line 30) | type Retriable interface

FILE: v2/tasks/reflect.go
  type ErrUnsupportedType (line 56) | type ErrUnsupportedType struct
    method Error (line 66) | func (e ErrUnsupportedType) Error() string {
  function NewErrUnsupportedType (line 61) | func NewErrUnsupportedType(valueType string) ErrUnsupportedType {
  function ReflectValue (line 71) | func ReflectValue(valueType string, value interface{}) (reflect.Value, e...
  function reflectValue (line 81) | func reflectValue(valueType string, value interface{}) (reflect.Value, e...
  function reflectValues (line 148) | func reflectValues(valueType string, value interface{}) (reflect.Value, ...
  function getBoolValue (line 261) | func getBoolValue(theType string, value interface{}) (bool, error) {
  function getIntValue (line 270) | func getIntValue(theType string, value interface{}) (int64, error) {
  function getUintValue (line 291) | func getUintValue(theType string, value interface{}) (uint64, error) {
  function getFloatValue (line 321) | func getFloatValue(theType string, value interface{}) (float64, error) {
  function getStringValue (line 341) | func getStringValue(theType string, value interface{}) (string, error) {
  function IsContextType (line 351) | func IsContextType(t reflect.Type) bool {

FILE: v2/tasks/reflect_test.go
  function TestReflectValue (line 227) | func TestReflectValue(t *testing.T) {

FILE: v2/tasks/result.go
  type TaskResult (line 10) | type TaskResult struct
  function ReflectTaskResults (line 16) | func ReflectTaskResults(taskResults []*TaskResult) ([]reflect.Value, err...
  function HumanReadableResults (line 29) | func HumanReadableResults(results []reflect.Value) string {

FILE: v2/tasks/result_test.go
  function TestReflectTaskResults (line 10) | func TestReflectTaskResults(t *testing.T) {

FILE: v2/tasks/signature.go
  type Arg (line 12) | type Arg struct
  type Headers (line 19) | type Headers
    method Set (line 22) | func (h Headers) Set(key, val string) {
    method ForeachKey (line 29) | func (h Headers) ForeachKey(handler func(key, val string) error) error {
  type Signature (line 46) | type Signature struct
  function NewSignature (line 75) | func NewSignature(name string, args []Arg) (*Signature, error) {
  function CopySignatures (line 84) | func CopySignatures(signatures ...*Signature) []*Signature {
  function CopySignature (line 92) | func CopySignature(signature *Signature) *Signature {

FILE: v2/tasks/state.go
  constant StatePending (line 7) | StatePending = "PENDING"
  constant StateReceived (line 9) | StateReceived = "RECEIVED"
  constant StateStarted (line 11) | StateStarted = "STARTED"
  constant StateRetry (line 13) | StateRetry = "RETRY"
  constant StateSuccess (line 15) | StateSuccess = "SUCCESS"
  constant StateFailure (line 17) | StateFailure = "FAILURE"
  type TaskState (line 21) | type TaskState struct
    method IsCompleted (line 97) | func (taskState *TaskState) IsCompleted() bool {
    method IsSuccess (line 102) | func (taskState *TaskState) IsSuccess() bool {
    method IsFailure (line 107) | func (taskState *TaskState) IsFailure() bool {
  type GroupMeta (line 34) | type GroupMeta struct
  function NewPendingTaskState (line 44) | func NewPendingTaskState(signature *Signature) *TaskState {
  function NewReceivedTaskState (line 54) | func NewReceivedTaskState(signature *Signature) *TaskState {
  function NewStartedTaskState (line 62) | func NewStartedTaskState(signature *Signature) *TaskState {
  function NewSuccessTaskState (line 70) | func NewSuccessTaskState(signature *Signature, results []*TaskResult) *T...
  function NewFailureTaskState (line 79) | func NewFailureTaskState(signature *Signature, err string) *TaskState {
  function NewRetryTaskState (line 88) | func NewRetryTaskState(signature *Signature) *TaskState {

FILE: v2/tasks/state_test.go
  function TestTaskStateIsCompleted (line 10) | func TestTaskStateIsCompleted(t *testing.T) {

FILE: v2/tasks/task.go
  type Task (line 22) | type Task struct
    method Call (line 102) | func (t *Task) Call() (taskResults []*TaskResult, err error) {
    method ReflectArgs (line 188) | func (t *Task) ReflectArgs(args []Arg) error {
  type signatureCtxType (line 29) | type signatureCtxType struct
  function SignatureFromContext (line 34) | func SignatureFromContext(ctx context.Context) *Signature {
  function NewWithSignature (line 49) | func NewWithSignature(taskFunc interface{}, signature *Signature) (*Task...
  function New (line 75) | func New(taskFunc interface{}, args []Arg) (*Task, error) {

FILE: v2/tasks/task_test.go
  function TestTaskCallErrorTest (line 14) | func TestTaskCallErrorTest(t *testing.T) {
  function TestTaskReflectArgs (line 43) | func TestTaskReflectArgs(t *testing.T) {
  function TestTaskCallInvalidArgRobustnessError (line 60) | func TestTaskCallInvalidArgRobustnessError(t *testing.T) {
  function TestTaskCallInterfaceValuedResult (line 80) | func TestTaskCallInterfaceValuedResult(t *testing.T) {
  function TestTaskCallWithContext (line 95) | func TestTaskCallWithContext(t *testing.T) {
  function TestTaskCallWithSignatureInContext (line 111) | func TestTaskCallWithSignatureInContext(t *testing.T) {

FILE: v2/tasks/validate.go
  function ValidateTask (line 20) | func ValidateTask(task interface{}) error {

FILE: v2/tasks/validate_test.go
  function TestValidateTask (line 10) | func TestValidateTask(t *testing.T) {

FILE: v2/tasks/workflow.go
  type Chain (line 10) | type Chain struct
  type Group (line 15) | type Group struct
    method GetUUIDs (line 28) | func (group *Group) GetUUIDs() []string {
  type Chord (line 22) | type Chord struct
  function NewChain (line 38) | func NewChain(signatures ...*Signature) (*Chain, error) {
  function NewGroup (line 59) | func NewGroup(signatures ...*Signature) (*Group, error) {
  function NewChord (line 82) | func NewChord(group *Group, callback *Signature) (*Chord, error) {

FILE: v2/tasks/workflow_test.go
  function TestNewChain (line 10) | func TestNewChain(t *testing.T) {

FILE: v2/tracing/tracing.go
  function StartSpanFromHeaders (line 23) | func StartSpanFromHeaders(headers tasks.Headers, operationName string) o...
  function HeadersWithSpan (line 44) | func HeadersWithSpan(headers tasks.Headers, span opentracing.Span) tasks...
  type consumerOption (line 57) | type consumerOption struct
    method Apply (line 61) | func (c consumerOption) Apply(o *opentracing.StartSpanOptions) {
  function ConsumerOption (line 69) | func ConsumerOption(producer opentracing.SpanContext) opentracing.StartS...
  type producerOption (line 73) | type producerOption struct
    method Apply (line 75) | func (p producerOption) Apply(o *opentracing.StartSpanOptions) {
  function ProducerOption (line 80) | func ProducerOption() opentracing.StartSpanOption {
  function AnnotateSpanWithSignatureInfo (line 85) | func AnnotateSpanWithSignatureInfo(span opentracing.Span, signature *tas...
  function AnnotateSpanWithChainInfo (line 101) | func AnnotateSpanWithChainInfo(span opentracing.Span, chain *tasks.Chain) {
  function AnnotateSpanWithGroupInfo (line 112) | func AnnotateSpanWithGroupInfo(span opentracing.Span, group *tasks.Group...
  function AnnotateSpanWithChordInfo (line 132) | func AnnotateSpanWithChordInfo(span opentracing.Span, chord *tasks.Chord...

FILE: v2/utils/deepcopy.go
  function deepCopy (line 14) | func deepCopy(dst, src reflect.Value) {
  function DeepCopy (line 59) | func DeepCopy(dst, src interface{}) error {
  function DeepClone (line 79) | func DeepClone(v interface{}) interface{} {

FILE: v2/utils/deepcopy_test.go
  function TestDeepCopy (line 9) | func TestDeepCopy(t *testing.T) {

FILE: v2/utils/utils.go
  constant LockKeyPrefix (line 9) | LockKeyPrefix = "machinery_lock_"
  function GetLockName (line 12) | func GetLockName(name, spec string) string {

FILE: v2/utils/utils_test.go
  function TestGetLockName (line 9) | func TestGetLockName(t *testing.T) {

FILE: v2/utils/uuid.go
  function GetPureUUID (line 8) | func GetPureUUID() string {

FILE: v2/utils/uuid_test.go
  function TestGetPureUUID (line 9) | func TestGetPureUUID(t *testing.T) {

FILE: v2/worker.go
  type Worker (line 24) | type Worker struct
    method Launch (line 44) | func (worker *Worker) Launch() error {
    method LaunchAsync (line 53) | func (worker *Worker) LaunchAsync(errorsChan chan<- error) {
    method CustomQueue (line 123) | func (worker *Worker) CustomQueue() string {
    method Quit (line 128) | func (worker *Worker) Quit() {
    method Process (line 133) | func (worker *Worker) Process(signature *tasks.Signature) error {
    method taskRetry (line 204) | func (worker *Worker) taskRetry(signature *tasks.Signature) error {
    method retryTaskIn (line 228) | func (worker *Worker) retryTaskIn(signature *tasks.Signature, retryIn ...
    method taskSucceeded (line 247) | func (worker *Worker) taskSucceeded(signature *tasks.Signature, taskRe...
    method taskFailed (line 361) | func (worker *Worker) taskFailed(signature *tasks.Signature, taskErr e...
    method hasAMQPBackend (line 392) | func (worker *Worker) hasAMQPBackend() bool {
    method SetErrorHandler (line 399) | func (worker *Worker) SetErrorHandler(handler func(err error)) {
    method SetPreTaskHandler (line 404) | func (worker *Worker) SetPreTaskHandler(handler func(*tasks.Signature)) {
    method SetPostTaskHandler (line 409) | func (worker *Worker) SetPostTaskHandler(handler func(*tasks.Signature...
    method SetPreConsumeHandler (line 414) | func (worker *Worker) SetPreConsumeHandler(handler func(*Worker) bool) {
    method GetServer (line 419) | func (worker *Worker) GetServer() *Server {
    method PreConsumeHandler (line 424) | func (worker *Worker) PreConsumeHandler() bool {
  function RedactURL (line 432) | func RedactURL(urlString string) string {

FILE: v2/worker_test.go
  function TestRedactURL (line 11) | func TestRedactURL(t *testing.T) {
  function TestPreConsumeHandler (line 19) | func TestPreConsumeHandler(t *testing.T) {
  function SamplePreConsumeHandler (line 28) | func SamplePreConsumeHandler(w *machinery.Worker) bool {
Condensed preview — 209 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,079K chars).
[
  {
    "path": ".deepsource.toml",
    "chars": 196,
    "preview": "version = 1\n\ntest_patterns = [\"**/*_test.go\"]\n\nexclude_patterns = [\"example/**\"]\n\n[[analyzers]]\nname = \"go\"\nenabled = tr"
  },
  {
    "path": ".gitignore",
    "chars": 51,
    "preview": "coverage*\n_vendor-*\n.idea/\n.env\n.DS_Store\ndump.rdb\n"
  },
  {
    "path": ".travis.yml",
    "chars": 161,
    "preview": "---\nlanguage: go\n\ngo:\n  - 1.13.x\n\nenv:\n  - GO111MODULE=on\n\nservices:\n  - docker\n\nscript:\n  - make ci\n\nafter_success:\n  -"
  },
  {
    "path": "Dockerfile.gcppubsub",
    "chars": 254,
    "preview": "FROM google/cloud-sdk:530.0.0-alpine\n\nRUN apk --update add openjdk8-jre\nRUN gcloud components install --quiet beta pubsu"
  },
  {
    "path": "Dockerfile.test",
    "chars": 518,
    "preview": "# Start from a Debian image with the latest version of Go installed\n# and a workspace (GOPATH) configured at /go.\nFROM g"
  },
  {
    "path": "LICENSE",
    "chars": 15885,
    "preview": "Mozilla Public License, version 2.0\n\n1. Definitions\n\n1.1. “Contributor”\n\n     means each individual or legal entity that"
  },
  {
    "path": "Makefile",
    "chars": 1094,
    "preview": ".PHONY: fmt lint golint test test-with-coverage ci\n# TODO: When Go 1.9 is released vendor folder should be ignored autom"
  },
  {
    "path": "README.md",
    "chars": 33174,
    "preview": "[1]: https://raw.githubusercontent.com/RichardKnop/assets/master/machinery/example_worker.png\n[2]: https://raw.githubuse"
  },
  {
    "path": "docker-compose.test.yml",
    "chars": 1680,
    "preview": "version: \"2\"\n\nservices:\n  sut:\n    container_name: machinery_sut\n    image: machinery_sut:latest\n    volumes:\n      - \"."
  },
  {
    "path": "example/amqp/main.go",
    "chars": 11228,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/urfave/cli\"\n\n\t\""
  },
  {
    "path": "example/redis/main.go",
    "chars": 11301,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/urfave/cli\"\n\n\t\""
  },
  {
    "path": "example/tasks/tasks.go",
    "chars": 1237,
    "preview": "package exampletasks\n\nimport (\n\t\"errors\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v1/log\"\n)\n\n// Add ...\nfu"
  },
  {
    "path": "example/tracers/jaeger.go",
    "chars": 1103,
    "preview": "package tracers\n\n// Uncomment the import statement for the jaeger tracer.\n// make sure you run dep ensure to pull in the"
  },
  {
    "path": "go.mod",
    "chars": 2800,
    "preview": "module github.com/RichardKnop/machinery\n\ngo 1.22\n\ntoolchain go1.24.1\n\nrequire (\n\tcloud.google.com/go/pubsub v1.10.0\n\tgit"
  },
  {
    "path": "go.sum",
    "chars": 60320,
    "preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1"
  },
  {
    "path": "instruction-notes/dynamodb.md",
    "chars": 1052,
    "preview": "# Using DynamoDB as a result backend\n## What is DynamoDB\nAmazon DynamoDB is a fast and flexible NoSQL database service.\n"
  },
  {
    "path": "integration-tests/amqp_amqp_test.go",
    "chars": 1076,
    "preview": "package integration_test\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1\"\n\t\"github.com/RichardKnop/mac"
  },
  {
    "path": "integration-tests/amqp_get_pending_tasks_test.go",
    "chars": 2606,
    "preview": "package integration_test\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v1\"\n\t\"github.com/"
  },
  {
    "path": "integration-tests/amqp_memcache_test.go",
    "chars": 1018,
    "preview": "package integration_test\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1\"\n\t\"github.com/RichardK"
  },
  {
    "path": "integration-tests/amqp_mongodb_test.go",
    "chars": 915,
    "preview": "package integration_test\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1\"\n\t\"github.com/RichardK"
  },
  {
    "path": "integration-tests/amqp_redis_test.go",
    "chars": 868,
    "preview": "package integration_test\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1\"\n\t\"github.com/RichardK"
  },
  {
    "path": "integration-tests/eager_eager_test.go",
    "chars": 2648,
    "preview": "package integration_test\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v1\"\n\t\"github.com/Ri"
  },
  {
    "path": "integration-tests/gcppubsub_redis_test.go",
    "chars": 2184,
    "preview": "package integration_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"cloud.google.com/go/pubsub\"\n\n\t\"github.c"
  },
  {
    "path": "integration-tests/redis_get_pending_tasks_test.go",
    "chars": 778,
    "preview": "package integration_test\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1/config\"\n)\n\nfunc TestRe"
  },
  {
    "path": "integration-tests/redis_memcache_test.go",
    "chars": 803,
    "preview": "package integration_test\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1\"\n\t\"github.com/RichardK"
  },
  {
    "path": "integration-tests/redis_mongodb_test.go",
    "chars": 829,
    "preview": "package integration_test\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1\"\n\t\"github.com/RichardK"
  },
  {
    "path": "integration-tests/redis_redis_test.go",
    "chars": 4213,
    "preview": "package integration_test\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v1\"\n\t\"g"
  },
  {
    "path": "integration-tests/redis_socket_test.go",
    "chars": 690,
    "preview": "package integration_test\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1\"\n\t\"github.com/RichardK"
  },
  {
    "path": "integration-tests/sqs_amqp_test.go",
    "chars": 822,
    "preview": "package integration_test\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1\"\n\t\"github.com/RichardKnop/mac"
  },
  {
    "path": "integration-tests/sqs_mongodb_test.go",
    "chars": 754,
    "preview": "package integration_test\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1\"\n\t\"github.com/RichardK"
  },
  {
    "path": "integration-tests/suite_test.go",
    "chars": 10958,
    "preview": "package integration_test\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"log\"\n\t\"reflect\"\n\t\"sort\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stret"
  },
  {
    "path": "integration-tests/worker_only_consumes_registered_tasks_test.go",
    "chars": 4804,
    "preview": "package integration_test\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"reflect\"\n\t\"sort\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machiner"
  },
  {
    "path": "v1/backends/amqp/amqp.go",
    "chars": 11827,
    "preview": "package amqp\n\n// NOTE: Using AMQP as a result backend is quite tricky since every time we\n// read a message from the que"
  },
  {
    "path": "v1/backends/amqp/amqp_test.go",
    "chars": 3952,
    "preview": "package amqp_test\n\nimport (\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v1/backends/amqp\"\n\t\"github.com/"
  },
  {
    "path": "v1/backends/dynamodb/dynamodb.go",
    "chars": 17791,
    "preview": "package dynamodb\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"time\"\n\n\t\"github.com/aws/aws-sdk-go/aws/session\"\n\n\t\"github.com/Rich"
  },
  {
    "path": "v1/backends/dynamodb/dynamodb_export_test.go",
    "chars": 7220,
    "preview": "package dynamodb\n\nimport (\n\t\"errors\"\n\t\"os\"\n\n\t\"github.com/RichardKnop/machinery/v1/config\"\n\t\"github.com/RichardKnop/machi"
  },
  {
    "path": "v1/backends/dynamodb/dynamodb_test.go",
    "chars": 22001,
    "preview": "package dynamodb_test\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v1/backends/dyn"
  },
  {
    "path": "v1/backends/eager/eager.go",
    "chars": 5451,
    "preview": "package eager\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"sync\"\n\n\t\"github.com/RichardKnop/machinery/v1/backends/iface\"\n"
  },
  {
    "path": "v1/backends/eager/eager_test.go",
    "chars": 6250,
    "preview": "package eager_test\n\nimport (\n\t\"encoding/json\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1/backends/eager\"\n\t\"github"
  },
  {
    "path": "v1/backends/iface/interfaces.go",
    "chars": 1018,
    "preview": "package iface\n\nimport (\n\t\"github.com/RichardKnop/machinery/v1/tasks\"\n)\n\n// Backend - a common interface for all result b"
  },
  {
    "path": "v1/backends/memcache/memcache.go",
    "chars": 7706,
    "preview": "package memcache\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v1/backends/iface\"\n\t\"gi"
  },
  {
    "path": "v1/backends/memcache/memcache_test.go",
    "chars": 3413,
    "preview": "package memcache_test\n\nimport (\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v1/backends/memcache\"\n\t\"git"
  },
  {
    "path": "v1/backends/mongo/mongodb.go",
    "chars": 9702,
    "preview": "package mongo\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"go.mongodb.org/mongo"
  },
  {
    "path": "v1/backends/mongo/mongodb_test.go",
    "chars": 5678,
    "preview": "package mongo_test\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1/backends/iface\"\n\t\"github.com/Richar"
  },
  {
    "path": "v1/backends/null/null.go",
    "chars": 3963,
    "preview": "package null\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/RichardKnop/machinery/v1/backends/iface\"\n\t\"github.com/RichardKnop/machinery/"
  },
  {
    "path": "v1/backends/package.go",
    "chars": 17,
    "preview": "package backends\n"
  },
  {
    "path": "v1/backends/redis/goredis.go",
    "chars": 8593,
    "preview": "package redis\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/go-redsync/redsync"
  },
  {
    "path": "v1/backends/redis/goredis_test.go",
    "chars": 3974,
    "preview": "package redis_test\n\nimport (\n\t\"github.com/RichardKnop/machinery/v1/backends/iface\"\n\t\"os\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github"
  },
  {
    "path": "v1/backends/redis/redis.go",
    "chars": 9015,
    "preview": "package redis\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/go-redsync/redsync/v4\"\n\tredsyncre"
  },
  {
    "path": "v1/backends/redis/redis_test.go",
    "chars": 4104,
    "preview": "package redis_test\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1/backends/redis\"\n\t\"github.com/Richar"
  },
  {
    "path": "v1/backends/result/async_result.go",
    "chars": 6371,
    "preview": "package result\n\nimport (\n\t\"errors\"\n\t\"reflect\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v1/backends/iface\"\n\t\"github.co"
  },
  {
    "path": "v1/brokers/amqp/amqp.go",
    "chars": 15367,
    "preview": "package amqp\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v"
  },
  {
    "path": "v1/brokers/amqp/amqp_concurrence_test.go",
    "chars": 1313,
    "preview": "package amqp\n\nimport (\n\t\"fmt\"\n\t\"github.com/RichardKnop/machinery/v1/brokers/iface\"\n\t\"github.com/RichardKnop/machinery/v1"
  },
  {
    "path": "v1/brokers/amqp/amqp_test.go",
    "chars": 1069,
    "preview": "package amqp_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1/brokers/amqp\"\n\t\"github.com/RichardKnop/mac"
  },
  {
    "path": "v1/brokers/eager/eager.go",
    "chars": 1713,
    "preview": "package eager\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/RichardKnop/machinery/v1/bro"
  },
  {
    "path": "v1/brokers/errs/errors.go",
    "chars": 971,
    "preview": "package errs\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n// ErrCouldNotUnmarshalTaskSignature ...\ntype ErrCouldNotUnmarshalTaskSignatu"
  },
  {
    "path": "v1/brokers/gcppubsub/gcp_pubsub.go",
    "chars": 4980,
    "preview": "package gcppubsub\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"cloud.google.com/go/pubsub\"\n\t\"github."
  },
  {
    "path": "v1/brokers/iface/interfaces.go",
    "chars": 834,
    "preview": "package iface\n\nimport (\n\t\"context\"\n\n\t\"github.com/RichardKnop/machinery/v1/config\"\n\t\"github.com/RichardKnop/machinery/v1/"
  },
  {
    "path": "v1/brokers/package.go",
    "chars": 16,
    "preview": "package brokers\n"
  },
  {
    "path": "v1/brokers/redis/goredis.go",
    "chars": 11877,
    "preview": "package redis\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\""
  },
  {
    "path": "v1/brokers/redis/redis.go",
    "chars": 12951,
    "preview": "package redis\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"math\"\n\t\"runtime\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/go-"
  },
  {
    "path": "v1/brokers/sqs/sqs.go",
    "chars": 11228,
    "preview": "package sqs\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/"
  },
  {
    "path": "v1/brokers/sqs/sqs_export_test.go",
    "chars": 6557,
    "preview": "package sqs\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"sync\"\n\n\t\"github.com/aws/aws-sdk-go/aws\"\n\t\"github.com/aws"
  },
  {
    "path": "v1/brokers/sqs/sqs_test.go",
    "chars": 8725,
    "preview": "package sqs_test\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/aws/aws-sdk-go/aws\"\n\t\"github.co"
  },
  {
    "path": "v1/common/amqp.go",
    "chars": 4234,
    "preview": "package common\n\nimport (\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"strings\"\n\n\tamqp \"github.com/rabbitmq/amqp091-go\"\n)\n\n// AMQPConnector ..."
  },
  {
    "path": "v1/common/backend.go",
    "chars": 440,
    "preview": "package common\n\nimport (\n\t\"github.com/RichardKnop/machinery/v1/config\"\n)\n\n// Backend represents a base backend structure"
  },
  {
    "path": "v1/common/broker.go",
    "chars": 3561,
    "preview": "package common\n\nimport (\n\t\"errors\"\n\t\"sync\"\n\n\t\"github.com/RichardKnop/machinery/v1/brokers/iface\"\n\t\"github.com/RichardKno"
  },
  {
    "path": "v1/common/broker_test.go",
    "chars": 1733,
    "preview": "package common_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1\"\n\t\"github.com/RichardKnop/machinery/v1/c"
  },
  {
    "path": "v1/common/redis.go",
    "chars": 2341,
    "preview": "package common\n\nimport (\n\t\"crypto/tls\"\n\t\"time\"\n\n\t\"github.com/gomodule/redigo/redis\"\n\n\t\"github.com/RichardKnop/machinery/"
  },
  {
    "path": "v1/config/config.go",
    "chars": 7467,
    "preview": "package config\n\nimport (\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"cloud.google.com/go/pubsub\"\n\t\"github.com/aws/aws-sdk"
  },
  {
    "path": "v1/config/env.go",
    "chars": 716,
    "preview": "package config\n\nimport (\n\t\"github.com/kelseyhightower/envconfig\"\n\n\t\"github.com/RichardKnop/machinery/v1/log\"\n)\n\n// NewFr"
  },
  {
    "path": "v1/config/env_test.go",
    "chars": 1129,
    "preview": "package config_test\n\nimport (\n\t\"bufio\"\n\t\"os\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1/config\"\n\t\"gith"
  },
  {
    "path": "v1/config/file.go",
    "chars": 1737,
    "preview": "package config\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v1/log\"\n\t\"gopkg.in/yaml.v2\"\n)\n\n// NewF"
  },
  {
    "path": "v1/config/file_test.go",
    "chars": 2662,
    "preview": "package config_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1/config\"\n\t\"github.com/stretchr/testify/as"
  },
  {
    "path": "v1/config/test.env",
    "chars": 257,
    "preview": "BROKER=broker\nDEFAULT_QUEUE=default_queue\nRESULT_BACKEND=result_backend\nRESULTS_EXPIRE_IN=123456\nAMQP_BINDING_KEY=bindin"
  },
  {
    "path": "v1/config/testconfig.yml",
    "chars": 768,
    "preview": "---\nbroker: broker\ndefault_queue: default_queue\nresult_backend: result_backend\nresults_expire_in: 123456\namqp:\n  binding"
  },
  {
    "path": "v1/factories.go",
    "chars": 10524,
    "preview": "package machinery\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\n\tneturl \"net/url\"\n\n\t\"github.com/RichardKnop/ma"
  },
  {
    "path": "v1/factories_test.go",
    "chars": 11857,
    "preview": "package machinery_test\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"reflect\"\n\t\"testing\"\n\t\"unsafe\"\n\n\tmachinery \"github.com/RichardK"
  },
  {
    "path": "v1/locks/eager/eager.go",
    "chars": 927,
    "preview": "package eager\n\nimport (\n\t\"errors\"\n\t\"sync\"\n\t\"time\"\n)\n\nvar (\n\tErrEagerLockFailed = errors.New(\"eager lock: failed to acqui"
  },
  {
    "path": "v1/locks/eager/eager_test.go",
    "chars": 1073,
    "preview": "package eager\n\nimport (\n\tlockiface \"github.com/RichardKnop/machinery/v1/locks/iface\"\n\t\"github.com/RichardKnop/machinery/"
  },
  {
    "path": "v1/locks/iface/interfaces.go",
    "chars": 412,
    "preview": "package iface\n\ntype Lock interface {\n\t//Acquire the lock with retry\n\t//key: the name of the lock,\n\t//value: at the nanos"
  },
  {
    "path": "v1/locks/redis/redis.go",
    "chars": 2159,
    "preview": "package redis\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v1/config"
  },
  {
    "path": "v1/log/log.go",
    "chars": 1063,
    "preview": "package log\n\nimport (\n\t\"github.com/RichardKnop/logging\"\n)\n\nvar (\n\tlogger = logging.New(nil, nil, new(logging.ColouredFor"
  },
  {
    "path": "v1/log/log_test.go",
    "chars": 275,
    "preview": "package log_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1/log\"\n)\n\nfunc TestDefaultLogger(t *testing.T"
  },
  {
    "path": "v1/package.go",
    "chars": 18,
    "preview": "package machinery\n"
  },
  {
    "path": "v1/retry/fibonacci.go",
    "chars": 378,
    "preview": "package retry\n\n// Fibonacci returns successive Fibonacci numbers starting from 1\nfunc Fibonacci() func() int {\n\ta, b := "
  },
  {
    "path": "v1/retry/fibonacci_test.go",
    "chars": 676,
    "preview": "package retry_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1/retry\"\n\t\"github.com/stretchr/testify/asse"
  },
  {
    "path": "v1/retry/retry.go",
    "chars": 649,
    "preview": "package retry\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v1/log\"\n)\n\n// Closure - a useful closure we c"
  },
  {
    "path": "v1/server.go",
    "chars": 13334,
    "preview": "package machinery\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/robfig/c"
  },
  {
    "path": "v1/server_test.go",
    "chars": 2540,
    "preview": "package machinery_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\n\t\"github.com/RichardKnop/machinery/"
  },
  {
    "path": "v1/tasks/errors.go",
    "chars": 770,
    "preview": "package tasks\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\n// ErrRetryTaskLater ...\ntype ErrRetryTaskLater struct {\n\tname, msg string\n\tre"
  },
  {
    "path": "v1/tasks/reflect.go",
    "chars": 9731,
    "preview": "package tasks\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nvar (\n"
  },
  {
    "path": "v1/tasks/reflect_test.go",
    "chars": 5933,
    "preview": "package tasks_test\n\nimport (\n\t\"encoding/json\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1/tasks\"\n)\n\nvar"
  },
  {
    "path": "v1/tasks/result.go",
    "chars": 986,
    "preview": "package tasks\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"strings\"\n)\n\n// TaskResult represents an actual return value of a processed t"
  },
  {
    "path": "v1/tasks/result_test.go",
    "chars": 614,
    "preview": "package tasks_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1/tasks\"\n\t\"github.com/stretchr/testify/asse"
  },
  {
    "path": "v1/tasks/signature.go",
    "chars": 2587,
    "preview": "package tasks\n\nimport (\n\t\"fmt\"\n\t\"github.com/RichardKnop/machinery/v1/utils\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n)\n\n// Arg"
  },
  {
    "path": "v1/tasks/state.go",
    "chars": 3057,
    "preview": "package tasks\n\nimport \"time\"\n\nconst (\n\t// StatePending - initial state of a task\n\tStatePending = \"PENDING\"\n\t// StateRece"
  },
  {
    "path": "v1/tasks/state_test.go",
    "chars": 647,
    "preview": "package tasks_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1/tasks\"\n\t\"github.com/stretchr/testify/asse"
  },
  {
    "path": "v1/tasks/task.go",
    "chars": 5159,
    "preview": "package tasks\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"runtime/debug\"\n\n\topentracing \"github.com/opentracing/op"
  },
  {
    "path": "v1/tasks/task_test.go",
    "chars": 3342,
    "preview": "package tasks_test\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"math\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v1/task"
  },
  {
    "path": "v1/tasks/validate.go",
    "chars": 1101,
    "preview": "package tasks\n\nimport (\n\t\"errors\"\n\t\"reflect\"\n)\n\nvar (\n\t// ErrTaskMustBeFunc ...\n\tErrTaskMustBeFunc = errors.New(\"Task mu"
  },
  {
    "path": "v1/tasks/validate_test.go",
    "chars": 835,
    "preview": "package tasks_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1/tasks\"\n\t\"github.com/stretchr/testify/asse"
  },
  {
    "path": "v1/tasks/workflow.go",
    "chars": 2446,
    "preview": "package tasks\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/google/uuid\"\n)\n\n// Chain creates a chain of tasks to be executed one after "
  },
  {
    "path": "v1/tasks/workflow_test.go",
    "chars": 973,
    "preview": "package tasks_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v1/tasks\"\n\t\"github.com/stretchr/testify/asse"
  },
  {
    "path": "v1/tracing/tracing.go",
    "chars": 4578,
    "preview": "package tracing\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/RichardKnop/machinery/v1/tasks\"\n\n\topentracing \"github.com/opent"
  },
  {
    "path": "v1/utils/deepcopy.go",
    "chars": 1871,
    "preview": "package utils\n\nimport (\n\t\"errors\"\n\t\"reflect\"\n)\n\nvar (\n\tErrNoMatchType     = errors.New(\"no match type\")\n\tErrNoPointer   "
  },
  {
    "path": "v1/utils/deepcopy_test.go",
    "chars": 537,
    "preview": "package utils\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestDeepCopy(t *testing.T) {\n\tt.Parall"
  },
  {
    "path": "v1/utils/utils.go",
    "chars": 207,
    "preview": "package utils\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n)\n\nconst (\n\tLockKeyPrefix = \"machinery_lock_\"\n)\n\nfunc GetLockName(name, s"
  },
  {
    "path": "v1/utils/utils_test.go",
    "chars": 246,
    "preview": "package utils\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestGetLockName(t *testing.T) {\n\tt.Par"
  },
  {
    "path": "v1/utils/uuid.go",
    "chars": 171,
    "preview": "package utils\n\nimport (\n\t\"github.com/google/uuid\"\n\t\"strings\"\n)\n\nfunc GetPureUUID() string {\n\tuid, _ := uuid.NewUUID()\n\tr"
  },
  {
    "path": "v1/utils/uuid_test.go",
    "chars": 165,
    "preview": "package utils\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestGetPureUUID(t *testing.T) {\n\tt.Par"
  },
  {
    "path": "v1/worker.go",
    "chars": 13251,
    "preview": "package machinery\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"os\"\n\t\"os/signal\"\n\t\"sync\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/open"
  },
  {
    "path": "v1/worker_test.go",
    "chars": 589,
    "preview": "package machinery_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/RichardKnop/machinery/v"
  },
  {
    "path": "v2/Dockerfile.test",
    "chars": 527,
    "preview": "# Start from a Debian image with the latest version of Go installed\n# and a workspace (GOPATH) configured at /go.\nFROM g"
  },
  {
    "path": "v2/Makefile",
    "chars": 1094,
    "preview": ".PHONY: fmt lint golint test test-with-coverage ci\n# TODO: When Go 1.9 is released vendor folder should be ignored autom"
  },
  {
    "path": "v2/backends/amqp/amqp.go",
    "chars": 11827,
    "preview": "package amqp\n\n// NOTE: Using AMQP as a result backend is quite tricky since every time we\n// read a message from the que"
  },
  {
    "path": "v2/backends/amqp/amqp_test.go",
    "chars": 3952,
    "preview": "package amqp_test\n\nimport (\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v2/backends/amqp\"\n\t\"github.com/"
  },
  {
    "path": "v2/backends/dynamodb/dynamodb.go",
    "chars": 18241,
    "preview": "package dynamodb\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v2/backends/i"
  },
  {
    "path": "v2/backends/dynamodb/dynamodb_export_test.go",
    "chars": 8359,
    "preview": "package dynamodb\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"os\"\n\n\tdynamodbiface \"github.com/RichardKnop/machinery/v2/backends/ifac"
  },
  {
    "path": "v2/backends/dynamodb/dynamodb_test.go",
    "chars": 24506,
    "preview": "package dynamodb_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v2/b"
  },
  {
    "path": "v2/backends/eager/eager.go",
    "chars": 5451,
    "preview": "package eager\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"sync\"\n\n\t\"github.com/RichardKnop/machinery/v2/backends/iface\"\n"
  },
  {
    "path": "v2/backends/eager/eager_test.go",
    "chars": 6250,
    "preview": "package eager_test\n\nimport (\n\t\"encoding/json\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v2/backends/eager\"\n\t\"github"
  },
  {
    "path": "v2/backends/iface/dynamodb/api.go",
    "chars": 971,
    "preview": "package dynamodb\n\nimport (\n\t\"context\"\n\n\t\"github.com/aws/aws-sdk-go-v2/service/dynamodb\"\n)\n\n// API is an interface for Dy"
  },
  {
    "path": "v2/backends/iface/interfaces.go",
    "chars": 1018,
    "preview": "package iface\n\nimport (\n\t\"github.com/RichardKnop/machinery/v2/tasks\"\n)\n\n// Backend - a common interface for all result b"
  },
  {
    "path": "v2/backends/memcache/memcache.go",
    "chars": 7706,
    "preview": "package memcache\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v2/backends/iface\"\n\t\"gi"
  },
  {
    "path": "v2/backends/memcache/memcache_test.go",
    "chars": 3413,
    "preview": "package memcache_test\n\nimport (\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v2/backends/memcache\"\n\t\"git"
  },
  {
    "path": "v2/backends/mongo/mongodb.go",
    "chars": 9718,
    "preview": "package mongo\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"go.mongodb.org/mongo"
  },
  {
    "path": "v2/backends/mongo/mongodb_test.go",
    "chars": 5678,
    "preview": "package mongo_test\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v2/backends/iface\"\n\t\"github.com/Richar"
  },
  {
    "path": "v2/backends/null/null.go",
    "chars": 3963,
    "preview": "package null\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/RichardKnop/machinery/v2/backends/iface\"\n\t\"github.com/RichardKnop/machinery/"
  },
  {
    "path": "v2/backends/package.go",
    "chars": 17,
    "preview": "package backends\n"
  },
  {
    "path": "v2/backends/redis/goredis.go",
    "chars": 8774,
    "preview": "package redis\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/go-redsync/redsync"
  },
  {
    "path": "v2/backends/redis/goredis_test.go",
    "chars": 3974,
    "preview": "package redis_test\n\nimport (\n\t\"github.com/RichardKnop/machinery/v2/backends/iface\"\n\t\"os\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github"
  },
  {
    "path": "v2/backends/redis/redis.go",
    "chars": 9015,
    "preview": "package redis\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/go-redsync/redsync/v4\"\n\tredsyncre"
  },
  {
    "path": "v2/backends/redis/redis_test.go",
    "chars": 4263,
    "preview": "package redis_test\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v2/backends/redis\"\n\t\"github.com/Richar"
  },
  {
    "path": "v2/backends/result/async_result.go",
    "chars": 6371,
    "preview": "package result\n\nimport (\n\t\"errors\"\n\t\"reflect\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v2/backends/iface\"\n\t\"github.co"
  },
  {
    "path": "v2/brokers/amqp/amqp.go",
    "chars": 15367,
    "preview": "package amqp\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/m"
  },
  {
    "path": "v2/brokers/amqp/amqp_concurrence_test.go",
    "chars": 1313,
    "preview": "package amqp\n\nimport (\n\t\"fmt\"\n\t\"github.com/RichardKnop/machinery/v2/brokers/iface\"\n\t\"github.com/RichardKnop/machinery/v2"
  },
  {
    "path": "v2/brokers/amqp/amqp_test.go",
    "chars": 1069,
    "preview": "package amqp_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v2/brokers/amqp\"\n\t\"github.com/RichardKnop/mac"
  },
  {
    "path": "v2/brokers/eager/eager.go",
    "chars": 1713,
    "preview": "package eager\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/RichardKnop/machinery/v2/bro"
  },
  {
    "path": "v2/brokers/errs/errors.go",
    "chars": 971,
    "preview": "package errs\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n// ErrCouldNotUnmarshalTaskSignature ...\ntype ErrCouldNotUnmarshalTaskSignatu"
  },
  {
    "path": "v2/brokers/gcppubsub/gcp_pubsub.go",
    "chars": 4922,
    "preview": "package gcppubsub\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"cloud.google.com/go/pubsub\"\n\t\"github."
  },
  {
    "path": "v2/brokers/iface/interfaces.go",
    "chars": 834,
    "preview": "package iface\n\nimport (\n\t\"context\"\n\n\t\"github.com/RichardKnop/machinery/v2/config\"\n\t\"github.com/RichardKnop/machinery/v2/"
  },
  {
    "path": "v2/brokers/iface/sqs/api.go",
    "chars": 694,
    "preview": "package sqs\n\nimport (\n\t\"context\"\n\n\t\"github.com/aws/aws-sdk-go-v2/service/sqs\"\n)\n\n// API is an interface for SQS API\ntype"
  },
  {
    "path": "v2/brokers/package.go",
    "chars": 16,
    "preview": "package brokers\n"
  },
  {
    "path": "v2/brokers/redis/goredis.go",
    "chars": 12078,
    "preview": "package redis\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\""
  },
  {
    "path": "v2/brokers/redis/redis.go",
    "chars": 12950,
    "preview": "package redis\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"math\"\n\t\"runtime\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/go-"
  },
  {
    "path": "v2/brokers/sqs/sqs.go",
    "chars": 12451,
    "preview": "package sqs\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/"
  },
  {
    "path": "v2/brokers/sqs/sqs_export_test.go",
    "chars": 6663,
    "preview": "package sqs\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"sync\"\n\n\tsqsiface \"github.com/RichardKnop/mach"
  },
  {
    "path": "v2/brokers/sqs/sqs_test.go",
    "chars": 11452,
    "preview": "package sqs_test\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v2\"\n\teage"
  },
  {
    "path": "v2/common/amqp.go",
    "chars": 4234,
    "preview": "package common\n\nimport (\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"strings\"\n\n\tamqp \"github.com/rabbitmq/amqp091-go\"\n)\n\n// AMQPConnector ..."
  },
  {
    "path": "v2/common/backend.go",
    "chars": 440,
    "preview": "package common\n\nimport (\n\t\"github.com/RichardKnop/machinery/v2/config\"\n)\n\n// Backend represents a base backend structure"
  },
  {
    "path": "v2/common/broker.go",
    "chars": 3561,
    "preview": "package common\n\nimport (\n\t\"errors\"\n\t\"sync\"\n\n\t\"github.com/RichardKnop/machinery/v2/brokers/iface\"\n\t\"github.com/RichardKno"
  },
  {
    "path": "v2/common/broker_test.go",
    "chars": 1733,
    "preview": "package common_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v2\"\n\t\"github.com/RichardKnop/machinery/v2/c"
  },
  {
    "path": "v2/common/redis.go",
    "chars": 2333,
    "preview": "package common\n\nimport (\n\t\"crypto/tls\"\n\t\"time\"\n\n\t\"github.com/gomodule/redigo/redis\"\n\n\t\"github.com/RichardKnop/machinery/"
  },
  {
    "path": "v2/config/config.go",
    "chars": 8228,
    "preview": "package config\n\nimport (\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"cloud.google.com/go/pubsub\"\n\tdynamodbiface \"github.c"
  },
  {
    "path": "v2/config/env.go",
    "chars": 716,
    "preview": "package config\n\nimport (\n\t\"github.com/kelseyhightower/envconfig\"\n\n\t\"github.com/RichardKnop/machinery/v2/log\"\n)\n\n// NewFr"
  },
  {
    "path": "v2/config/env_test.go",
    "chars": 1129,
    "preview": "package config_test\n\nimport (\n\t\"bufio\"\n\t\"os\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v2/config\"\n\t\"gith"
  },
  {
    "path": "v2/config/file.go",
    "chars": 1737,
    "preview": "package config\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v2/log\"\n\t\"gopkg.in/yaml.v2\"\n)\n\n// NewF"
  },
  {
    "path": "v2/config/file_test.go",
    "chars": 2662,
    "preview": "package config_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v2/config\"\n\t\"github.com/stretchr/testify/as"
  },
  {
    "path": "v2/config/test.env",
    "chars": 257,
    "preview": "BROKER=broker\nDEFAULT_QUEUE=default_queue\nRESULT_BACKEND=result_backend\nRESULTS_EXPIRE_IN=123456\nAMQP_BINDING_KEY=bindin"
  },
  {
    "path": "v2/config/testconfig.yml",
    "chars": 768,
    "preview": "---\nbroker: broker\ndefault_queue: default_queue\nresult_backend: result_backend\nresults_expire_in: 123456\namqp:\n  binding"
  },
  {
    "path": "v2/docker-compose.test.yml",
    "chars": 982,
    "preview": "version: \"2\"\n\nservices:\n  sut:\n    container_name: machinery_sut\n    image: machinery_sut:latest\n    volumes:\n      - \"."
  },
  {
    "path": "v2/example/amqp/main.go",
    "chars": 11357,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/urfave/cli\"\n\n\t\""
  },
  {
    "path": "v2/example/go-redis/main.go",
    "chars": 11412,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/urfave/cli\"\n\n\t\""
  },
  {
    "path": "v2/example/redigo/main.go",
    "chars": 11412,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/urfave/cli\"\n\n\t\""
  },
  {
    "path": "v2/example/tasks/tasks.go",
    "chars": 1237,
    "preview": "package exampletasks\n\nimport (\n\t\"errors\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v2/log\"\n)\n\n// Add ...\nfu"
  },
  {
    "path": "v2/example/tracers/jaeger.go",
    "chars": 1103,
    "preview": "package tracers\n\n// Uncomment the import statement for the jaeger tracer.\n// make sure you run dep ensure to pull in the"
  },
  {
    "path": "v2/go.mod",
    "chars": 3985,
    "preview": "module github.com/RichardKnop/machinery/v2\n\ngo 1.22\n\ntoolchain go1.24.1\n\nrequire (\n\tcloud.google.com/go/pubsub v1.10.0\n\t"
  },
  {
    "path": "v2/go.sum",
    "chars": 62482,
    "preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1"
  },
  {
    "path": "v2/integration-tests/amqp_amqp_test.go",
    "chars": 1374,
    "preview": "package integration_test\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v2\"\n\t\"github.com/RichardKnop/mac"
  },
  {
    "path": "v2/integration-tests/redis_redis_test.go",
    "chars": 1160,
    "preview": "package integration_test\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v2\"\n\tredisbackend \"github.com/Ri"
  },
  {
    "path": "v2/integration-tests/suite_test.go",
    "chars": 10711,
    "preview": "package integration_test\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"reflect\"\n\t\"sort\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/tes"
  },
  {
    "path": "v2/locks/eager/eager.go",
    "chars": 919,
    "preview": "package eager\n\nimport (\n\t\"errors\"\n\t\"sync\"\n\t\"time\"\n)\n\nvar (\n\tErrEagerLockFailed = errors.New(\"eager lock: failed to acqui"
  },
  {
    "path": "v2/locks/eager/eager_test.go",
    "chars": 1073,
    "preview": "package eager\n\nimport (\n\tlockiface \"github.com/RichardKnop/machinery/v2/locks/iface\"\n\t\"github.com/RichardKnop/machinery/"
  },
  {
    "path": "v2/locks/iface/interfaces.go",
    "chars": 412,
    "preview": "package iface\n\ntype Lock interface {\n\t//Acquire the lock with retry\n\t//key: the name of the lock,\n\t//value: at the nanos"
  },
  {
    "path": "v2/locks/redis/redis.go",
    "chars": 2367,
    "preview": "package redis\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/redis/go-redis/v9\"\n\n\t\"github.co"
  },
  {
    "path": "v2/log/log.go",
    "chars": 1063,
    "preview": "package log\n\nimport (\n\t\"github.com/RichardKnop/logging\"\n)\n\nvar (\n\tlogger = logging.New(nil, nil, new(logging.ColouredFor"
  },
  {
    "path": "v2/log/log_test.go",
    "chars": 275,
    "preview": "package log_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v2/log\"\n)\n\nfunc TestDefaultLogger(t *testing.T"
  },
  {
    "path": "v2/package.go",
    "chars": 18,
    "preview": "package machinery\n"
  },
  {
    "path": "v2/retry/fibonacci.go",
    "chars": 378,
    "preview": "package retry\n\n// Fibonacci returns successive Fibonacci numbers starting from 1\nfunc Fibonacci() func() int {\n\ta, b := "
  },
  {
    "path": "v2/retry/fibonacci_test.go",
    "chars": 676,
    "preview": "package retry_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v2/retry\"\n\t\"github.com/stretchr/testify/asse"
  },
  {
    "path": "v2/retry/retry.go",
    "chars": 649,
    "preview": "package retry\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v2/log\"\n)\n\n// Closure - a useful closure we c"
  },
  {
    "path": "v2/server.go",
    "chars": 12667,
    "preview": "package machinery\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/robfig/c"
  },
  {
    "path": "v2/server_test.go",
    "chars": 1997,
    "preview": "package machinery_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/RichardKnop/machinery/v"
  },
  {
    "path": "v2/tasks/errors.go",
    "chars": 770,
    "preview": "package tasks\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\n// ErrRetryTaskLater ...\ntype ErrRetryTaskLater struct {\n\tname, msg string\n\tre"
  },
  {
    "path": "v2/tasks/reflect.go",
    "chars": 9731,
    "preview": "package tasks\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nvar (\n"
  },
  {
    "path": "v2/tasks/reflect_test.go",
    "chars": 5933,
    "preview": "package tasks_test\n\nimport (\n\t\"encoding/json\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v2/tasks\"\n)\n\nvar"
  },
  {
    "path": "v2/tasks/result.go",
    "chars": 986,
    "preview": "package tasks\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"strings\"\n)\n\n// TaskResult represents an actual return value of a processed t"
  },
  {
    "path": "v2/tasks/result_test.go",
    "chars": 614,
    "preview": "package tasks_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v2/tasks\"\n\t\"github.com/stretchr/testify/asse"
  },
  {
    "path": "v2/tasks/signature.go",
    "chars": 2587,
    "preview": "package tasks\n\nimport (\n\t\"fmt\"\n\t\"github.com/RichardKnop/machinery/v2/utils\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n)\n\n// Arg"
  },
  {
    "path": "v2/tasks/state.go",
    "chars": 3057,
    "preview": "package tasks\n\nimport \"time\"\n\nconst (\n\t// StatePending - initial state of a task\n\tStatePending = \"PENDING\"\n\t// StateRece"
  },
  {
    "path": "v2/tasks/state_test.go",
    "chars": 647,
    "preview": "package tasks_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v2/tasks\"\n\t\"github.com/stretchr/testify/asse"
  },
  {
    "path": "v2/tasks/task.go",
    "chars": 5144,
    "preview": "package tasks\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"runtime/debug\"\n\n\topentracing \"github.com/opentracing/op"
  },
  {
    "path": "v2/tasks/task_test.go",
    "chars": 3342,
    "preview": "package tasks_test\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"math\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/RichardKnop/machinery/v2/task"
  },
  {
    "path": "v2/tasks/validate.go",
    "chars": 1101,
    "preview": "package tasks\n\nimport (\n\t\"errors\"\n\t\"reflect\"\n)\n\nvar (\n\t// ErrTaskMustBeFunc ...\n\tErrTaskMustBeFunc = errors.New(\"Task mu"
  },
  {
    "path": "v2/tasks/validate_test.go",
    "chars": 835,
    "preview": "package tasks_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v2/tasks\"\n\t\"github.com/stretchr/testify/asse"
  },
  {
    "path": "v2/tasks/workflow.go",
    "chars": 2446,
    "preview": "package tasks\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/google/uuid\"\n)\n\n// Chain creates a chain of tasks to be executed one after "
  },
  {
    "path": "v2/tasks/workflow_test.go",
    "chars": 973,
    "preview": "package tasks_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/RichardKnop/machinery/v2/tasks\"\n\t\"github.com/stretchr/testify/asse"
  },
  {
    "path": "v2/tracing/tracing.go",
    "chars": 4578,
    "preview": "package tracing\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/RichardKnop/machinery/v2/tasks\"\n\n\topentracing \"github.com/opent"
  },
  {
    "path": "v2/utils/deepcopy.go",
    "chars": 1871,
    "preview": "package utils\n\nimport (\n\t\"errors\"\n\t\"reflect\"\n)\n\nvar (\n\tErrNoMatchType     = errors.New(\"no match type\")\n\tErrNoPointer   "
  }
]

// ... and 9 more files (download for full content)

About this extraction

This page contains the full source code of the RichardKnop/machinery GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 209 files (966.3 KB), approximately 306.6k tokens, and a symbol index with 1445 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!