{"id":13879077,"url":"https://github.com/hopsoft/bg","last_synced_at":"2025-04-15T11:13:00.339Z","repository":{"id":20657224,"uuid":"23939443","full_name":"hopsoft/bg","owner":"hopsoft","description":"Non-blocking ActiveRecord method invocation","archived":false,"fork":false,"pushed_at":"2019-08-28T13:41:27.000Z","size":49,"stargazers_count":48,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-15T11:12:43.081Z","etag":null,"topics":["activejob","background-jobs","rails","ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","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/hopsoft.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"MIT-LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-09-11T23:22:04.000Z","updated_at":"2024-04-20T20:54:37.000Z","dependencies_parsed_at":"2022-08-18T13:52:00.250Z","dependency_job_id":null,"html_url":"https://github.com/hopsoft/bg","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hopsoft%2Fbg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hopsoft%2Fbg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hopsoft%2Fbg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hopsoft%2Fbg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hopsoft","download_url":"https://codeload.github.com/hopsoft/bg/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249058384,"owners_count":21205911,"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":["activejob","background-jobs","rails","ruby"],"created_at":"2024-08-06T08:02:09.033Z","updated_at":"2025-04-15T11:13:00.306Z","avatar_url":"https://github.com/hopsoft.png","language":"Ruby","readme":"[![Lines of Code](http://img.shields.io/badge/lines_of_code-117-brightgreen.svg?style=flat)](http://blog.codinghorror.com/the-best-code-is-no-code-at-all/)\n[![Maintainability](https://api.codeclimate.com/v1/badges/1144d074fee9298347a7/maintainability)](https://codeclimate.com/github/hopsoft/bg/maintainability)\n[![Build Status](http://img.shields.io/travis/hopsoft/bg.svg?style=flat)](https://travis-ci.org/hopsoft/bg)\n[![Coverage Status](https://img.shields.io/coveralls/hopsoft/bg.svg?style=flat)](https://coveralls.io/r/hopsoft/bg?branch=master)\n[![Downloads](http://img.shields.io/gem/dt/bg.svg?style=flat)](http://rubygems.org/gems/bg)\n\n# Bg\n\n## Non-blocking ActiveRecord method invocation\n\nThis library allows you to invoke ActiveRecord instance methods in the background.\n\n* `Bg::Asyncable` uses concurrent-ruby to execute methods in a different thread\n* `Bg::Deferrable` uses ActiveJob to execute methods in a background process\n\n\n## Quickstart\n\n### Setup\n\n```ruby\nclass User \u003c ApplicationRecord\n  include Bg::Asyncable::Behavior  # uses concurrent-ruby\n  include Bg::Deferrable::Behavior # uses ActiveJob\nend\n```\n\n### Usage\n\n```ruby\nuser = User.find(params[:id])\n\n# blocking in-process\nuser.do_hard_work\n\n# non-blocking in-process separate thread\nuser.async.do_hard_work\n\n# non-blocking out-of-process background job\nuser.defer.do_hard_work\nuser.defer(queue: :low, wait: 5.minutes).do_hard_work\n```\n\n## Deferrable\n\n`Bg::Deferrable` leverages [GlobalID::Identification](https://github.com/rails/globalid) to marshal ActiveRecord instances across process boundaries.\nThis means that state is not shared between the main process \u0026 the process actually executing the method.\n\n* __Do not__ depend on lexically scoped bindings when invoking methods.\n* __Do not__ pass unmarshallable types as arguments.\n  `Bg::Deferrable` will prepare arguments for enqueuing, but best practice is to follow\n  Sidekiq's [simple parameters](https://github.com/mperham/sidekiq/wiki/Best-Practices#1-make-your-job-parameters-small-and-simple) rule.\n\n### Examples\n\n#### Good\n\n```ruby\nuser = User.find(params[:id])\nuser.defer.do_hard_work 1, true, \"foo\"\n```\n\n#### Bad\n\n```ruby\nuser = User.find(params[:id])\n# in memory changes will not be available in Bg::Deferrable invoked methods\nuser.name = \"new value\"\n\n# args may not marshal properly\nuser.defer.do_hard_work :foo, Time.now, instance_of_complex_type\n\nuser.defer.do_hard_work do\n  # blocks are not supported\nend\n```\n\n## Asyncable\n\n`Bg::Asyncable` disallows invoking methods that take blocks as an argument.\n\n* __Important:__ It's your responsibility to protect shared data between threads\n\n### Examples\n\n#### Good\n\n```ruby\nuser = User.find(params[:id])\nuser.name = \"new value\"\nuser.async.do_hard_work 1, true, \"foo\"\nuser.async.do_hard_work :foo, Time.now, instance_of_complex_type\n```\n\n#### Bad\n\n```ruby\nuser = User.find(params[:id])\n\nuser.async.do_hard_work do\n  # blocks are not supported\nend\n```\n\n","funding_links":[],"categories":["Ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhopsoft%2Fbg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhopsoft%2Fbg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhopsoft%2Fbg/lists"}