[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-8000":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":16,"stars30d":17,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":20,"hasPages":20,"topics":22,"createdAt":10,"pushedAt":10,"updatedAt":23,"readmeContent":24,"aiSummary":25,"trendingCount":16,"starSnapshotCount":16,"syncStatus":17,"lastSyncTime":26,"discoverSource":27},8000,"que","que-rb\u002Fque","que-rb","A Ruby job queue that uses PostgreSQL's advisory locks for speed and reliability.","",null,"Ruby",2319,195,35,44,0,2,28.88,"MIT License",false,"master",[],"2026-06-12 02:01:47","# Que ![tests](https:\u002F\u002Fgithub.com\u002Fque-rb\u002Fque\u002Fworkflows\u002Ftests\u002Fbadge.svg)\n\n**This README and the rest of the docs on the master branch all refer to Que 2.x. For older versions, please refer to the docs on the respective branches: [1.x](https:\u002F\u002Fgithub.com\u002Fque-rb\u002Fque\u002Ftree\u002F1.x), or [0.x](https:\u002F\u002Fgithub.com\u002Fque-rb\u002Fque\u002Ftree\u002F0.x).**\n\n*TL;DR: Que is a high-performance job queue that improves the reliability of your application by protecting your jobs with the same [ACID guarantees](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FACID) as the rest of your data.*\n\nQue (\"keɪ\", or \"kay\") is a queue for Ruby and PostgreSQL that manages jobs using [advisory locks](http:\u002F\u002Fwww.postgresql.org\u002Fdocs\u002Fcurrent\u002Fstatic\u002Fexplicit-locking.html#ADVISORY-LOCKS), which gives it several advantages over other RDBMS-backed queues:\n\n- **Concurrency** - Workers don't block each other when trying to lock jobs, as often occurs with \"SELECT FOR UPDATE\"-style locking. This allows for very high throughput with a large number of workers.\n- **Efficiency** - Locks are held in memory, so locking a job doesn't incur a disk write. These first two points are what limit performance with other queues. Under heavy load, Que's bottleneck is CPU, not I\u002FO.\n- **Safety** - If a Ruby process dies, the jobs it's working won't be lost, or left in a locked or ambiguous state - they immediately become available for any other worker to pick up.\n\nAdditionally, there are the general benefits of storing jobs in Postgres, alongside the rest of your data, rather than in Redis or a dedicated queue:\n\n- **Transactional Control** - Queue a job along with other changes to your database, and it'll commit or rollback with everything else. If you're using ActiveRecord or Sequel, Que can piggyback on their connections, so setup is simple and jobs are protected by the transactions you're already using.\n- **Atomic Backups** - Your jobs and data can be backed up together and restored as a snapshot. If your jobs relate to your data (and they usually do), there's no risk of jobs falling through the cracks during a recovery.\n- **Fewer Dependencies** - If you're already using Postgres (and you probably should be), a separate queue is another moving part that can break.\n- **Security** - Postgres' support for SSL connections keeps your data safe in transport, for added protection when you're running workers on cloud platforms that you can't completely control.\n\nQue's primary goal is reliability. You should be able to leave your application running indefinitely without worrying about jobs being lost due to a lack of transactional support, or left in limbo due to a crashing process. Que does everything it can to ensure that jobs you queue are performed exactly once (though the occasional repetition of a job can be impossible to avoid - see the docs on [how to write a reliable job](\u002Fdocs\u002FREADME.md#writing-reliable-jobs)).\n\nQue's secondary goal is performance. The worker process is multithreaded, so that a single process can run many jobs simultaneously.\n\nCompatibility:\n\n- MRI Ruby 2.7+ (for Ruby 3, Que 2+ is required)\n- PostgreSQL 9.5+\n- Rails 6.0+ (optional)\n\n**Please note** - Que's job table undergoes a lot of churn when it is under high load, and like any heavily-written table, is susceptible to bloat and slowness if Postgres isn't able to clean it up. The most common cause of this is long-running transactions, so it's recommended to try to keep all transactions against the database housing Que's job table as short as possible. This is good advice to remember for any high-activity database, but bears emphasizing when using tables that undergo a lot of writes.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'que'\n```\n\nAnd then execute:\n\n```bash\nbundle\n```\n\nOr install it yourself as:\n\n```bash\ngem install que\n```\n\n## Usage\n\nFirst, create the queue schema in a migration. For example:\n\n```ruby\nclass CreateQueSchema \u003C ActiveRecord::Migration[6.0]\n  def up\n    # Whenever you use Que in a migration, always specify the version you're\n    # migrating to. If you're unsure what the current version is, check the\n    # changelog.\n    Que.migrate!(version: 7)\n  end\n\n  def down\n    # Migrate to version 0 to remove Que entirely.\n    Que.migrate!(version: 0)\n  end\nend\n```\n\nCreate a class for each type of job you want to run:\n\n```ruby\n# app\u002Fjobs\u002Fcharge_credit_card.rb\nclass ChargeCreditCard \u003C Que::Job\n  # Default settings for this job. These are optional - without them, jobs\n  # will default to priority 100 and run immediately.\n  self.run_at = proc { 1.minute.from_now }\n\n  # We use the Linux priority scale - a lower number is more important.\n  self.priority = 10\n\n  def run(credit_card_id, user_id:)\n    # Do stuff.\n    user = User.find(user_id)\n    card = CreditCard.find(credit_card_id)\n\n    User.transaction do\n      # Write any changes you'd like to the database.\n      user.update charged_at: Time.now\n\n      # It's best to destroy the job in the same transaction as any other\n      # changes you make. Que will mark the job as destroyed for you after the\n      # run method if you don't do it yourself; however if your job writes to the DB\n      # but doesn't destroy the job in the same transaction, it's possible that\n      # the job could be repeated in the event of a crash.\n      destroy\n\n      # If you'd rather leave the job record in the database to maintain a job\n      # history, simply replace the `destroy` call with a `finish` call.\n    end\n  end\nend\n```\n\nQueue your job. Again, it's best to do this in a transaction with other changes you're making. Also note that any arguments you pass will be serialized to JSON and back again, so stick to simple types (strings, integers, floats, hashes, and arrays).\n\n```ruby\nCreditCard.transaction do\n  # Persist credit card information\n  card = CreditCard.create(params[:credit_card])\n  ChargeCreditCard.enqueue(card.id, user_id: current_user.id)\nend\n```\n\nYou can also add options to run the job after a specific time, or with a specific priority:\n\n```ruby\nChargeCreditCard.enqueue(card.id, user_id: current_user.id, job_options: { run_at: 1.day.from_now, priority: 5 })\n```\n\n[Learn more about job options](docs\u002FREADME.md#job-options).\n\n## Running the Que Worker\n\nIn order to process jobs, you must start a separate worker process outside of your main server.\n\n```bash\nbundle exec que\n```\n\nTry running `que -h` to get a list of runtime options:\n\n```\n$ que -h\nusage: que [options] [file\u002Fto\u002Frequire] ...\n    -h, --help                       Show this help text.\n    -i, --poll-interval [INTERVAL]   Set maximum interval between polls for available jobs, in seconds (default: 5)\n    ...\n```\n\nYou may need to pass que a file path to require so that it can load your app. Que will automatically load `config\u002Fenvironment.rb` if it exists, so you shouldn't need an argument if you're using Rails.\n\n## Additional Rails-specific Setup\n\nIf you're using ActiveRecord to dump your database's schema, please [set your schema_format to :sql](http:\u002F\u002Fguides.rubyonrails.org\u002Fmigrations.html#types-of-schema-dumps) so that Que's table structure is managed correctly. This is a good idea regardless, as the `:ruby` schema format doesn't support many of PostgreSQL's advanced features.\n\nPre-1.0, the default queue name needed to be configured in order for Que to work out of the box with Rails. As of 1.0 the default queue name is now 'default', as Rails expects, but when Rails enqueues some types of jobs it may try to use another queue name that isn't worked by default. You can either:\n\n- [Configure Rails](https:\u002F\u002Fguides.rubyonrails.org\u002Fconfiguring.html) to send all internal job types to the 'default' queue by adding the following to `config\u002Fapplication.rb`:\n\n    ```ruby\n    config.action_mailer.deliver_later_queue_name = :default\n    config.action_mailbox.queues.incineration = :default\n    config.action_mailbox.queues.routing = :default\n    config.active_storage.queues.analysis = :default\n    config.active_storage.queues.purge = :default\n    ```\n\n- [Tell que](\u002Fdocs#multiple-queues) to work all of these queues (less efficient because it requires polling all of them):\n\n    ```bash\n    que -q default -q mailers -q action_mailbox_incineration -q action_mailbox_routing -q active_storage_analysis -q active_storage_purge\n    ```\n\nAlso, if you would like to integrate Que with Active Job, you can do it by setting the adapter in `config\u002Fapplication.rb` or in a specific environment by setting it in `config\u002Fenvironments\u002Fproduction.rb`, for example:\n\n```ruby\nconfig.active_job.queue_adapter = :que\n```\n\nQue will automatically use the database configuration of your rails application, so there is no need to configure anything else.\n\nYou can then write your jobs as usual following the [Active Job documentation](https:\u002F\u002Fguides.rubyonrails.org\u002Factive_job_basics.html). However, be aware that you'll lose the ability to finish the job in the same transaction as other database operations. That happens because Active Job is a generic background job framework that doesn't benefit from the database integration Que provides.\n\nIf you later decide to switch a job from Active Job to Que to have transactional integrity you can easily change the corresponding job class to inherit from `Que::Job` and follow the usage guidelines in the previous section.\n\n## Testing\n\nThere are a couple ways to do testing. You may want to set `Que::Job.run_synchronously = true`, which will cause JobClass.enqueue to simply execute the job's logic synchronously, as if you'd run JobClass.run(*your_args). Or, you may want to leave it disabled so you can assert on the job state once they are stored in the database.\n\n## Documentation\n\n**For full documentation, see [here](docs\u002FREADME.md)**.\n\n## Related Projects\n\nThese projects are tested to be compatible with Que 1.x:\n\n- [que-web](https:\u002F\u002Fgithub.com\u002Fstatianzo\u002Fque-web) is a Sinatra-based UI for inspecting your job queue.\n- [que-view](https:\u002F\u002Fgithub.com\u002Fkortirso\u002Fque-view) is a Rails engine-based UI for inspecting your job queue.\n- [que-scheduler](https:\u002F\u002Fgithub.com\u002Fhlascelles\u002Fque-scheduler) lets you schedule tasks using a cron style config file.\n- [que-locks](https:\u002F\u002Fgithub.com\u002Fairhorns\u002Fque-locks) lets you lock around job execution for so only one job runs at once for a set of arguments.\n- [que-unique](https:\u002F\u002Fgithub.com\u002Fbambooengineering\u002Fque-unique) provides fast in-memory `enqueue` deduping.\n- [que-prometheus](https:\u002F\u002Fgithub.com\u002Fmnbbrown\u002Fque-prometheus) exposes Prometheus API endpoints for job, worker, and queue metrics\n\nIf you have a project that uses or relates to Que, feel free to submit a PR adding it to the list!\n\n## Community and Contributing\n\n- For feature suggestions or bugs in the library, please feel free to [open an issue](https:\u002F\u002Fgithub.com\u002Fque-rb\u002Fque\u002Fissues\u002Fnew).\n- For general discussion and questions\u002Fconcerns that don't relate to obvious bugs, join our [Discord Server](https:\u002F\u002Fdiscord.gg\u002FB3EW32H).\n- For contributions, pull requests submitted via Github are welcome.\n\nRegarding contributions, one of the project's priorities is to keep Que as simple, lightweight and dependency-free as possible, and pull requests that change too much or wouldn't be useful to the majority of Que's users have a good chance of being rejected. If you're thinking of submitting a pull request that adds a new feature, consider starting a discussion in an issue first about what it would do and how it would be implemented. If it's a sufficiently large feature, or if most of Que's users wouldn't find it useful, it may be best implemented as a standalone gem, like some of the related projects above.\n\n### Specs\n\nA note on running specs - Que's worker system is multithreaded and therefore prone to race conditions. As such, if you've touched that code, a single spec run passing isn't a guarantee that any changes you've made haven't introduced bugs. One thing I like to do before pushing changes is rerun the specs many times and watching for hangs. You can do this from the command line with something like:\n\n```bash\nfor i in {1..1000}; do SEED=$i bundle exec rake; done\n```\n\nThis will iterate the specs one thousand times, each with a different ordering. If the specs hang, note what the seed number was on that iteration. For example, if the previous specs finished with a \"Randomized with seed 328\", you know that there's a hang with seed 329, and you can narrow it down to a specific spec with:\n\n```bash\nfor i in {1..1000}; do LOG_SPEC=true SEED=328 bundle exec rake; done\n```\n\nNote that we iterate because there's no guarantee that the hang would reappear with a single additional run, so we need to rerun the specs until it reappears. The LOG_SPEC parameter will output the name and file location of each spec before it is run, so you can easily tell which spec is hanging, and you can continue narrowing things down from there.\n\nAnother helpful technique is to replace an `it` spec declaration with `hit` - this will run that particular spec 100 times during the run.\n\n#### With Docker\n\nWe've provided a Dockerised environment to avoid the need to manually: install Ruby, install the gem bundle, set up Postgres, and connect to the database.\n\nTo run the specs using this environment, run:\n\n```bash\n.\u002Fauto\u002Ftest\n```\n\nTo get a shell in the environment, run:\n\n```bash\n.\u002Fauto\u002Fdev\n```\n\nThe [Docker Compose config](docker-compose.yml) provides a convenient way to inject your local shell aliases into the Docker container. Simply create a file containing your alias definitions (or which sources them from other files) at `~\u002F.docker-rc.d\u002F.docker-bashrc`, and they will be available inside the container.\n\n#### Without Docker\n\nYou'll need to have Postgres running. Assuming you have it running on port 5697, with a `que-test` database, and a username & password of `que`, you can run:\n\n```bash\nDATABASE_URL=postgres:\u002F\u002Fque:que@localhost:5697\u002Fque-test bundle exec rake\n```\n\nIf you don't already have Postgres, you could use Docker Compose to run just the database:\n\n```bash\ndocker compose up -d db\n```\n\nIf you want to try a different version of Postgres, e.g. 12:\n\n```bash\nexport POSTGRES_VERSION=12\n```\n\n### Git pre-push hook\n\nSo we can avoid breaking the build, we've created Git pre-push hooks to verify everything is ok before pushing.\n\nTo set up the pre-push hook locally, run:\n\n```bash\necho -e \"#\\!\u002Fbin\u002Fbash\\n\\$(dirname \\$0)\u002F..\u002F..\u002Fauto\u002Fpre-push-hook\" > .git\u002Fhooks\u002Fpre-push\nchmod +x .git\u002Fhooks\u002Fpre-push\n```\n\n### Release process\n\nThe process for releasing a new version of the gem is:\n\n- Merge PR(s)\n- Git pull locally\n- Update the version number, bundle install, and commit\n- Update `CHANGELOG.md`, and commit\n- Tag the commit with the version number, prefixed by `v`\n- Git push to master\n- Git push the tag\n- Publish the new version of the gem to RubyGems: `gem build -o que.gem && gem push que.gem`\n- Create a GitHub release - rather than describe anything there, link to the heading for the release in `CHANGELOG.md`\n- Post on the Que Discord in `#announcements`\n","Que 是一个使用 PostgreSQL 的咨询锁来提高速度和可靠性的 Ruby 作业队列。它通过利用 PostgreSQL 的内存锁定机制，实现了高并发和高效处理能力，同时保证了数据的一致性和安全性。Que 的设计使得即使在高负载下，其性能瓶颈也主要在于 CPU 而非 I\u002FO 操作。此外，由于直接将作业存储于 Postgres 中，与应用程序的其他数据共享相同的 ACID 事务保证，因此非常适合需要强一致性和高可靠性任务调度的应用场景，如金融交易、日志处理等。对于已经在使用 PostgreSQL 的项目来说，Que 提供了一个减少额外依赖且易于集成的任务队列解决方案。","2026-06-11 03:15:35","top_language"]