{"id":13455032,"url":"https://github.com/diamondio/better-queue","last_synced_at":"2025-04-11T11:49:21.435Z","repository":{"id":41183315,"uuid":"49420805","full_name":"diamondio/better-queue","owner":"diamondio","description":"Better Queue for NodeJS","archived":false,"fork":false,"pushed_at":"2024-06-22T07:26:25.000Z","size":286,"stargazers_count":529,"open_issues_count":28,"forks_count":44,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-03-31T10:01:58.531Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/diamondio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-01-11T11:11:28.000Z","updated_at":"2025-03-30T11:54:12.000Z","dependencies_parsed_at":"2024-06-18T12:19:05.571Z","dependency_job_id":"dda12f0c-b153-48a7-b9ba-a8640202753c","html_url":"https://github.com/diamondio/better-queue","commit_stats":{"total_commits":258,"total_committers":14,"mean_commits":"18.428571428571427","dds":0.2829457364341085,"last_synced_commit":"8d0ff8ba8801b8fad4db429d76ed9afc01fc1e8e"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diamondio%2Fbetter-queue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diamondio%2Fbetter-queue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diamondio%2Fbetter-queue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diamondio%2Fbetter-queue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/diamondio","download_url":"https://codeload.github.com/diamondio/better-queue/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246632502,"owners_count":20808882,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T08:01:00.491Z","updated_at":"2025-04-04T06:02:42.557Z","avatar_url":"https://github.com/diamondio.png","language":"JavaScript","readme":"# Better Queue - Powerful flow control\n\n[![npm package](https://nodei.co/npm/better-queue.png?downloads=true\u0026downloadRank=true\u0026stars=true)](https://nodei.co/npm/better-queue/)\n\n[![Build status](https://img.shields.io/travis/diamondio/better-queue.svg?style=flat-square)](https://travis-ci.org/diamondio/better-queue)\n[![Dependency Status](https://img.shields.io/david/diamondio/better-queue.svg?style=flat-square)](https://david-dm.org/diamondio/better-queue)\n[![Known Vulnerabilities](https://snyk.io/test/npm/better-queue/badge.svg?style=flat-square)](https://snyk.io/test/npm/better-queue)\n[![Gitter](https://img.shields.io/badge/gitter-join_chat-blue.svg?style=flat-square)](https://gitter.im/leanderlee/better-queue?utm_source=badge)\n\n\n## Super simple to use\n\nBetter Queue is designed to be simple to set up but still let you do complex things.\n\n- Persistent (and extendable) storage\n- Batched processing\n- Prioritize tasks\n- Merge/filter tasks\n- Progress events (with ETA!)\n- Fine-tuned timing controls\n- Retry on fail\n- Concurrent batch processing\n- Task statistics (average completion time, failure rate and peak queue size)\n- ... and more!\n\n---\n\n#### Install (via npm)\n\n```bash\nnpm install --save better-queue\n```\n\n---\n\n#### Quick Example\n\n```js\nvar Queue = require('better-queue');\n\nvar q = new Queue(function (input, cb) {\n  \n  // Some processing here ...\n\n  cb(null, result);\n})\n\nq.push(1)\nq.push({ x: 1 })\n```\n\n## Table of contents\n\n- [Queuing](#queuing)\n- [Task Management](#task-management)\n- [Queue Management](#queue-management)\n- [Advanced](#advanced)\n- [Storage](#storage)\n- [Using with Webpack](#using-with-webpack)\n- [Full Documentation](#full-documentation)\n\n---\n\nYou will be able to combine any (and all) of these options\nfor your queue!\n\n\n## Queuing\n\nIt's very easy to push tasks into the queue.\n\n```js\nvar q = new Queue(fn);\nq.push(1);\nq.push({ x: 1, y: 2 });\nq.push(\"hello\");\n```\n\nYou can also include a callback as a second parameter to the push\nfunction, which would be called when that task is done. For example:\n\n```js\nvar q = new Queue(fn);\nq.push(1, function (err, result) {\n  // Results from the task!\n});\n```\n\nYou can also listen to events on the results of the `push` call.\n\n```js\nvar q = new Queue(fn);\nq.push(1)\n  .on('finish', function (result) {\n    // Task succeeded with {result}!\n  })\n  .on('failed', function (err) {\n    // Task failed!\n  })\n```\n\nAlternatively, you can subscribe to the queue's events.\n\n```js\nvar q = new Queue(fn);\nq.on('task_finish', function (taskId, result, stats) {\n  // taskId = 1, result: 3, stats = { elapsed: \u003ctime taken\u003e }\n  // taskId = 2, result: 5, stats = { elapsed: \u003ctime taken\u003e }\n})\nq.on('task_failed', function (taskId, err, stats) {\n  // Handle error, stats = { elapsed: \u003ctime taken\u003e }\n})\nq.on('empty', function (){})\nq.on('drain', function (){})\nq.push({ id: 1, a: 1, b: 2 });\nq.push({ id: 2, a: 2, b: 3 });\n```\n\n`empty` event fires when all of the tasks have been pulled off of\nthe queue (there may still be tasks running!)\n\n`drain` event fires when there are no more tasks on the queue _and_\nwhen no more tasks are running.\n\nYou can control how many tasks process at the same time.\n\n```js\nvar q = new Queue(fn, { concurrent: 3 })\n```\n\nNow the queue will allow 3 tasks running at the same time. (By \ndefault, we handle tasks one at a time.)\n\nYou can also turn the queue into a stack by turning on `filo`.\n\n```js\nvar q = new Queue(fn, { filo: true })\n```\n\nNow items you push on will be handled first.\n\n\n\n[back to top](#table-of-contents)\n\n---\n\n## Task Management\n\n#### Task ID\n\nTasks can be given an ID to help identify and track it as it goes through\nthe queue.\n\nBy default, we look for `task.id` to see if it's a string property,\notherwise we generate a random ID for the task.\n\nYou can pass in an `id` property to options to change this behaviour.\nHere are some examples of how:\n\n```js\nvar q = new Queue(fn, {\n  id: 'id',   // Default: task's `id` property\n  id: 'name', // task's `name` property\n  id: function (task, cb) {\n    // Compute the ID\n    cb(null, 'computed_id');\n  }\n})\n```\n\nOne thing you can do with Task ID is merge tasks:\n\n```js\nvar counter = new Queue(function (task, cb) {\n  console.log(\"I have %d %ss.\", task.count, task.id);\n  cb();\n}, {\n  merge: function (oldTask, newTask, cb) {\n    oldTask.count += newTask.count;\n    cb(null, oldTask);\n  }\n})\ncounter.push({ id: 'apple', count: 2 });\ncounter.push({ id: 'apple', count: 1 });\ncounter.push({ id: 'orange', count: 1 });\ncounter.push({ id: 'orange', count: 1 });\n// Prints out:\n//   I have 3 apples.\n//   I have 2 oranges.\n```\n\nBy default, if tasks have the same ID they replace the previous task.\n\n```js\nvar counter = new Queue(function (task, cb) {\n  console.log(\"I have %d %ss.\", task.count, task.id);\n  cb();\n})\ncounter.push({ id: 'apple', count: 1 });\ncounter.push({ id: 'apple', count: 3 });\ncounter.push({ id: 'orange', count: 1 });\ncounter.push({ id: 'orange', count: 2 });\n// Prints out:\n//   I have 3 apples.\n//   I have 2 oranges.\n```\n\nYou can also use the task ID when subscribing to events from Queue.\n\n```js\nvar counter = new Queue(fn)\ncounter.on('task_finish', function (taskId, result) {\n  // taskId will be 'jim' or 'bob'\n})\ncounter.push({ id: 'jim', count: 2 });\ncounter.push({ id: 'bob', count: 1 });\n```\n\n\n#### Batch Processing\n\nYour processing function can also be modified to handle multiple\ntasks at the same time. For example:\n\n```js\nvar ages = new Queue(function (batch, cb) {\n  // Batch 1:\n  //   [ { id: 'steve', age: 21 },\n  //     { id: 'john', age: 34 },\n  //     { id: 'joe', age: 18 } ]\n  // Batch 2:\n  //   [ { id: 'mary', age: 23 } ]\n  cb();\n}, { batchSize: 3 })\nages.push({ id: 'steve', age: 21 });\nages.push({ id: 'john', age: 34 });\nages.push({ id: 'joe', age: 18 });\nages.push({ id: 'mary', age: 23 });\n```\n\nNote how the queue will only handle at most 3 items at a time.\n\nBelow is another example of a batched call with numbers.\n\n```js\nvar ages = new Queue(function (batch, cb) {\n  // batch = [1,2,3]\n  cb();\n}, { batchSize: 3 })\nages.push(1);\nages.push(2);\nages.push(3);\n```\n\n\n#### Filtering, Validation and Priority\n\nYou can also format (and filter) the input that arrives from a push\nbefore it gets processed by the queue by passing in a `filter` \nfunction.\n\n```js\nvar greeter = new Queue(function (name, cb) {\n  console.log(\"Hello, %s!\", name)\n  cb();\n}, {\n  filter: function (input, cb) {\n    if (input === 'Bob') {\n      return cb('not_allowed');\n    }\n    return cb(null, input.toUpperCase())\n  }\n});\ngreeter.push('anna'); // Prints 'Hello, ANNA!'\n```\n\nThis can be particularly useful if your queue needs to do some pre-processing,\ninput validation, database lookup, etc. before you load it onto the queue.\n\nYou can also define a priority function to control which tasks get\nprocessed first.\n\n```js\nvar greeter = new Queue(function (name, cb) {\n  console.log(\"Greetings, %s.\", name);\n  cb();\n}, {\n  priority: function (name, cb) {\n    if (name === \"Steve\") return cb(null, 10);\n    if (name === \"Mary\") return cb(null, 5);\n    if (name === \"Joe\") return cb(null, 5);\n    cb(null, 1);\n  }\n})\ngreeter.push(\"Steve\");\ngreeter.push(\"John\");\ngreeter.push(\"Joe\");\ngreeter.push(\"Mary\");\n\n// Prints out:\n//   Greetings, Steve.\n//   Greetings, Joe.\n//   Greetings, Mary.\n//   Greetings, John.\n```\n\nIf `filo` is set to `true` in the example above, then Joe and Mary \nwould swap order.\n\n\n[back to top](#table-of-contents)\n\n---\n\n## Queue Management\n\n#### Retry\n\nYou can set tasks to retry `maxRetries` times if they fail. By default,\ntasks will fail (and will not retry.) Optionally, you can set a `retryDelay`\nto wait a little while before retrying.\n\n```js\nvar q = new Queue(fn, { maxRetries: 10, retryDelay: 1000 })\n```\n\n\n#### Timing\n\nYou can configure the queue to have a `maxTimeout`.\n\n```js\nvar q = new Queue(function (name, cb) {\n  someLongTask(function () {\n    cb();\n  })\n}, { maxTimeout: 2000 })\n```\n\nAfter 2 seconds, the process will throw an error instead of waiting for the\ncallback to finish.\n\nYou can also delay the queue before it starts its processing. This is the \nbehaviour of a timed cargo.\n\n```js\nvar q = new Queue(function (batch, cb) {\n  // Batch [1,2] will process after 2s.\n  cb();\n}, { batchSize: 5, batchDelay: 2000 })\nq.push(1);\nsetTimeout(function () {\n  q.push(2);\n}, 1000)\n```\n\nYou can also set `afterProcessDelay`, which will delay processing between tasks.\n\n```js\nvar q = new Queue(function (task, cb) {\n  cb(); // Will wait 1 second before taking the next task\n}, { afterProcessDelay: 1000 })\nq.push(1);\nq.push(2);\n```\n\nInstead of just the `batchDelay`, you can add a `batchDelayTimeout`, which is for firing off a batch if it hasn't had any new tasks pushed to the queue in the `batchDelayTimeout` time (in milliseconds.)\n\n```js\nvar q = new Queue(fn, {\n  batchSize: 50,\n  batchDelay: 5000,\n  batchDelayTimeout: 1000\n})\nq.push(1);\nq.push(2);\n```\n\nIn the example above, the queue will wait for 50 items to fill up in 5s or process the queue if no new tasks were added in 1s.\n\n#### Precondition\n\nYou can define a function called `precondition` that checks that it's ok to process\nthe next batch. If the preconditions fail, it will keep calling this function until\nit passes again.\n\n```js\nvar q = new Queue(function (batch, cb) {\n\n  // Do something that requires internet\n\n}, {\n  precondition: function (cb) {\n    isOnline(function (err, ok) {\n      if (ok) {\n        cb(null, true);\n      } else {\n        cb(null, false);\n      }\n    })\n  },\n  preconditionRetryTimeout: 10*1000 // If we go offline, retry every 10s\n})\n```\n\n\n#### Pause/Resume\n\nThere are options to control processes while they are running.\n\nYou can return an object in your processing function with the functions\n`cancel`, `pause` and `resume`. This will allow operations to pause, resume \nor cancel while it's running.\n\n```js\nvar uploader = new Queue(function (file, cb) {\n  \n  var worker = someLongProcess(file);\n\n  return {\n    cancel: function () {\n      // Cancel the file upload\n    },\n    pause: function () {\n      // Pause the file upload\n    },\n    resume: function () {\n      // Resume the file upload\n    }\n  }\n})\nuploader.push('/path/to/file.pdf');\nuploader.pause();\nuploader.resume();\n```\n\n#### Cancel/Abort\n\nYou can also set `cancelIfRunning` to `true`. This will cancel a running task if\na task with the same ID is pushed onto the queue.\n\n```js\nvar uploader = new Queue(function (file, cb) {\n  var request = someLongProcess(file);\n  return {\n    cancel: function () {\n      request.cancel();\n    }\n  }\n}, {\n  id: 'path',\n  cancelIfRunning: true\n})\nuploader.push({ path: '/path/to/file.pdf' });\n// ... Some time later\nuploader.push({ path: '/path/to/file.pdf' });\n```\n\nIn the example above, the first upload process is cancelled and the task is requeued.\n\nYou can also call `.cancel(taskId)` to cancel and unqueue the task.\n\n```js\nuploader.cancel('/path/to/file.pdf');\n```\n\nNote that if you enable this option in batch mode, it will cancel the entire batch!\n\n\n[back to top](#table-of-contents)\n\n---\n\n## Advanced\n\n#### Updating Task Status\n\nThe process function will be run in a context with `progress`,\n`finishBatch` and `failedBatch` functions.\n\nThe example below illustrates how you can use these:\n\n```js\nvar uploader = new Queue(function (file, cb) {\n  this.failedBatch('some_error')\n  this.finishBatch(result)\n  this.progressBatch(bytesUploaded, totalBytes, \"uploading\")\n});\nuploader.on('task_finish', function (taskId, result) {\n  // Handle finished result\n})\nuploader.on('task_failed', function (taskId, errorMessage) {\n  // Handle error\n})\nuploader.on('task_progress', function (taskId, completed, total) {\n  // Handle task progress\n})\n\nuploader.push('/some/file.jpg')\n  .on('finish', function (result) {\n    // Handle upload result\n  })\n  .on('failed', function (err) {\n    // Handle error\n  })\n  .on('progress', function (progress) {\n    // progress.eta - human readable string estimating time remaining\n    // progress.pct - % complete (out of 100)\n    // progress.complete - # completed so far\n    // progress.total - # for completion\n    // progress.message - status message\n  })\n```\n\n#### Update Status in Batch mode (batchSize \u003e 1)\n\nYou can also complete individual tasks in a batch by using `failedTask` and\n`finishTask` functions.\n\n```js\nvar uploader = new Queue(function (files, cb) {\n  this.failedTask(0, 'some_error')         // files[0] has failed with 'some_error'\n  this.finishTask(1, result)               // files[1] has finished with {result}\n  this.progressTask(2, 30, 100, \"copying\") // files[2] is 30% done, currently copying\n}, { batchSize: 3 });\nuploader.push('/some/file1.jpg')\nuploader.push('/some/file2.jpg')\nuploader.push('/some/file3.jpg')\n```\n\nNote that if you use *-Task and *-Batch functions together, the batch functions will only\napply to the tasks that have not yet finished/failed.\n\n\n#### Queue Statistics\n\nYou can inspect the queue at any given time to see information about how many items are\nqueued, average queue time in milliseconds, success rate and total item processed.\n\n```js\nvar q = new Queue(fn);\nvar stats = q.getStats();\n\n// stats.total = Total tasks processed\n// stats.average = Average process time in milliseconds\n// stats.successRate = % success (between 0 and 1)\n// stats.peak = Most tasks queued at any given point in time\n```\n\n\n[back to top](#table-of-contents)\n\n---\n\n\n## Storage\n\n\n#### Using a store\n\nFor your convenience, we have added compatibility for a few storage options.\n\nBy default, we are using an in-memory store that doesn't persist. You can change\nto one of our other built in stores by passing in the `store` option.\n\n#### Built-in store\n\nCurrently, we support the following stores:\n\n - memory\n - sql (SQLite, PostgreSQL)\n\n#### SQLite store (`npm install sqlite3`)\n```\nvar q = new Queue(fn, {\n  store: {\n    type: 'sql',\n    dialect: 'sqlite',\n    path: '/path/to/sqlite/file'\n  }\n});\n```\n\nNote that this requires `better-queue-sql` or `better-queue-sqlite`.\n\n#### PostgreSQL store (`npm install pg`)\n```\nvar q = new Queue(fn, {\n  store: {\n    type: 'sql',\n    dialect: 'postgres',\n    host: 'localhost',\n    port: 5432,\n    username: 'username',\n    password: 'password',\n    dbname: 'template1',\n    tableName: 'tasks'\n  }\n});\n```\n\nPlease help us add support for more stores; contributions are welcome!\n\n#### Custom Store\n\nWriting your own store is very easy; you just need to implement a few functions\nthen call `queue.use(store)` on your store.\n\n```js\nvar q = new Queue(fn, { store: myStore });\n```\n\nor\n\n```js\nq.use(myStore);\n```\n\nYour store needs the following functions:\n```js\nq.use({\n  connect: function (cb) {\n    // Connect to your db\n  },\n  getRunningTasks: function (cb) {\n    // Returns a map of running tasks (lockId =\u003e taskIds)\n  },\n  getTask: function (taskId, cb) {\n    // Retrieves a task\n  },\n  putTask: function (taskId, task, priority, cb) {\n    // Save task with given priority\n  },\n  takeFirstN: function (n, cb) {\n    // Removes the first N items (sorted by priority and age)\n  },\n  takeLastN: function (n, cb) {\n    // Removes the last N items (sorted by priority and recency)\n  }\n})\n```\n\n[back to top](#table-of-contents)\n\n---\n## Using with Webpack\n\nBetter Queue can be used in the browser using the default in-memory store. However you have to create and pass the store to its constructor. \n\n\n```js\nimport Queue = require('better-queue')\nimport MemoryStore = require('better-queue-memory')\n\nvar q = new Queue(function (input, cb) {\n  \n  // Some processing here ...\n\n  cb(null, result);\n},\n{\n    store: new MemoryStore(),\n  }\n)\n```\n\n### TypeScript Support\n\nBetter Queue can be used in TypeScript projects by installing type definitions from the [Definitely Typed](https://github.com/DefinitelyTyped/DefinitelyTyped) repository:\n\n```bash\nnpm install --save @types/better-queue\n```\n\nAfterwards, you can simply import the library:\n\n```ts\nimport Queue = require('better-queue')\n\nconst q: Queue = new Queue(() =\u003e {});\n```\n\n\n[back to top](#table-of-contents)\n\n---\n\n## Full Documentation\n\n#### new Queue(process, options)\n\nThe first argument can be either the process function or the `options` object.\n\nA process function is required, all other options are optional.\n\n- `process` - function to process tasks. Will be run with either one single task (if `batchSize` is 1) or as an array of at most `batchSize` items. The second argument will be a callback `cb(error, result)` that must be called regardless of success or failure.\n\n---\n\n- `filter` - function to filter input. Will be run with `input` whatever was passed to `q.push()`. If you define this function, then you will be expected to call the callback `cb(error, task)`. If an error is sent in the callback then the input is rejected.\n- `merge` - function to merge tasks with the same task ID. Will be run with `oldTask`, `newTask` and a callback `cb(error, mergedTask)`. If you define this function then the callback is expected to be called.\n- `priority` - function to determine the priority of a task. Takes in a task and returns callback `cb(error, priority)`.\n- `precondition` - function that runs a check before processing to ensure it can process the next batch. Takes a callback `cb(error, passOrFail)`.\n\n---\n\n- `id` - The property to use as the task ID. This can be a string or a function (for more complicated IDs). The function `(task, cb)` and must call the callback with `cb(error, taskId)`.\n- `cancelIfRunning` - If true, when a task with the same ID is running, its worker will be cancelled. Defaults to `false`.\n- `autoResume` - If true, tasks in the store will automatically start processing once it connects to the store. Defaults to `true`.\n- `failTaskOnProcessException` - If true, when the process function throws an error the batch fails. Defaults to `true`.\n- `filo` - If true, tasks will be completed in a first in, last out order. Defaults to `false`.\n- `batchSize` - The number of tasks (at most) that can be processed at once. Defaults to `1`.\n- `batchDelay` - Number of milliseconds to delay before starting to popping items off the queue. Defaults to `0`.\n- `batchDelayTimeout` - Number of milliseconds to wait for a new task to arrive before firing off the batch. Defaults to `Infinity`.\n- `concurrent` - Number of workers that can be running at any given time. Defaults to `1`.\n- `maxTimeout` - Number of milliseconds before a task is considered timed out. Defaults to `Infinity`.\n- `afterProcessDelay` - Number of milliseconds to delay before processing the next batch of items. Defaults to `1`.\n- `maxRetries` - Maximum number of attempts to retry on a failed task. Defaults to `0`.\n- `retryDelay` - Number of milliseconds before retrying. Defaults to `0`.\n- `storeMaxRetries` - Maximum number of attempts before giving up on the store. Defaults to `Infinity`.\n- `storeRetryTimeout` - Number of milliseconds to delay before trying to connect to the store again. Defaults to `1000`.\n- `preconditionRetryTimeout` - Number of milliseconds to delay before checking the precondition function again. Defaults to `1000`.\n- `store` - Represents the options for the initial store. Can be an object containing `{ type: storeType, ... options ... }`, or the store instance itself.\n\n#### Methods on Queue\n\n- `push(task, cb)` - Push a task onto the queue, with an optional callback when it completes. Returns a `Ticket` object.\n- `pause()` - Pauses the queue: tries to pause running tasks and prevents tasks from getting processed until resumed.\n- `resume()` - Resumes the queue and its runnign tasks.\n- `destroy(cb)` - Destroys the queue: closes the store, tries to clean up.\n- `use(store)` - Sets the queue to read from and write to the given store.\n- `getStats()` - Gets the aggregate stats for the queue. Returns an object with properties `successRate`, `peak`, `total` and `average`, representing the success rate on tasks, peak number of items queued, total number of items processed and average processing time in milliseconds, respectively.\n- `resetStats()` - Resets all of the aggregate stats.\n\n#### Events on Queue\n\n- `task_queued` - When a task is queued\n- `task_accepted` - When a task is accepted\n- `task_started` - When a task begins processing\n- `task_finish` - When a task is completed\n- `task_failed` - When a task fails\n- `task_progress` - When a task progress changes\n- `batch_finish` - When a batch of tasks (or worker) completes\n- `batch_failed` - When a batch of tasks (or worker) fails\n- `batch_progress` - When a batch of tasks (or worker) updates its progress\n\n#### Events on Ticket\n\n- `accepted` - When the corresponding task is accepted (has passed filter)\n- `queued` - When the corresponding task is queued (and saved into the store)\n- `started` - When the corresponding task is started\n- `progress` - When the corresponding task progress changes\n- `finish` - When the corresponding task completes\n- `failed` - When the corresponding task fails\n\n","funding_links":[],"categories":["Packages","包","Repository","JavaScript","目录"],"sub_categories":["Job queues","任务队列","Job Queues","工作队列"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdiamondio%2Fbetter-queue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdiamondio%2Fbetter-queue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdiamondio%2Fbetter-queue/lists"}