{"action":"closed","number":106,"pull_request":{"url":"https://api.github.com/repos/chanks/que/pulls/106","id":33501671,"html_url":"https://github.com/chanks/que/pull/106","diff_url":"https://github.com/chanks/que/pull/106.diff","patch_url":"https://github.com/chanks/que/pull/106.patch","issue_url":"https://api.github.com/repos/chanks/que/issues/106","number":106,"state":"closed","locked":false,"title":"Add flexible failure handling","user":{"login":"barisbalic","id":196469,"avatar_url":"https://avatars.githubusercontent.com/u/196469?v=3","gravatar_id":"","url":"https://api.github.com/users/barisbalic","html_url":"https://github.com/barisbalic","followers_url":"https://api.github.com/users/barisbalic/followers","following_url":"https://api.github.com/users/barisbalic/following{/other_user}","gists_url":"https://api.github.com/users/barisbalic/gists{/gist_id}","starred_url":"https://api.github.com/users/barisbalic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/barisbalic/subscriptions","organizations_url":"https://api.github.com/users/barisbalic/orgs","repos_url":"https://api.github.com/users/barisbalic/repos","events_url":"https://api.github.com/users/barisbalic/events{/privacy}","received_events_url":"https://api.github.com/users/barisbalic/received_events","type":"User","site_admin":false},"body":"Hi Chris,\r\n\r\nWe've tried to come up with some modest changes that would allow us to implement the different kinds of failure behaviours that we currently use at GoCardless. This pull request contains everything that is necessary to get us going, and we've actually got a Job running on this in production right now.\r\n\r\nWe've written a gem called `que-retry` that makes use of these changes.  We're hoping to open source it soon, but it's not quite ready.  Looking at it might provide better context for our changes, so let us know if you'd like to take a look.\r\n\r\nThe current changes are:\r\n- The failure handling code from the work loop has been extracted into a method of it's own.\r\n- A `retryable` field has been introduced to stop \"failed\" jobs from being re-run constantly.\r\n- A `retryable` argument has been added to `Job`.\r\n- The new migration sets `retryable` to true for all existing jobs.  This ensures users with existing jobs will be unaffected.\r\n- The `lock_job` query has been updated to only select jobs that are `retryable`.\r\n- A `failed_at` field has been added for introspection/diagnostic purposes.\r\n- The `freeze` on `Que::SQL` has been removed, because we needed to introduce more queries in our `que-retry` gem.\r\n\r\nThe last point is one we've been unsure about, it could be avoided by including one of our queries in `Que` itself, but by default it wouldn't be used by `Que`.  It would be great to hear how you feel about this, and we'd be happy to show you `que-retry`.  It's not quite finished, but it's pretty close, and will be open-sourced.\r\n\r\nAnother change that starts to make sense when you look at `que-retry` is the possibility of passing instances of Jobs to the handlers, rather than hashes.  It would end up being a bit cleaner.\r\n\r\nOne last thing to note, is that we have been running our branch in `queue-shootout` against your master to make sure we've not had a detrimental impact on performance, so far it's a close match and seems like we've had literally no impact.","created_at":"2015-04-16T23:11:46Z","updated_at":"2016-09-09T19:31:34Z","closed_at":"2016-09-09T19:31:34Z","merged_at":null,"merge_commit_sha":"f896361d048d16a6ccd1750f92b039e8a5817d01","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/chanks/que/pulls/106/commits","review_comments_url":"https://api.github.com/repos/chanks/que/pulls/106/comments","review_comment_url":"https://api.github.com/repos/chanks/que/pulls/comments{/number}","comments_url":"https://api.github.com/repos/chanks/que/issues/106/comments","statuses_url":"https://api.github.com/repos/chanks/que/statuses/493822047483c957bdc56a833f49f129d7ffc463","head":{"label":"gocardless:flexible-failure-handling","ref":"flexible-failure-handling","sha":"493822047483c957bdc56a833f49f129d7ffc463","user":{"login":"gocardless","id":790629,"avatar_url":"https://avatars.githubusercontent.com/u/790629?v=3","gravatar_id":"","url":"https://api.github.com/users/gocardless","html_url":"https://github.com/gocardless","followers_url":"https://api.github.com/users/gocardless/followers","following_url":"https://api.github.com/users/gocardless/following{/other_user}","gists_url":"https://api.github.com/users/gocardless/gists{/gist_id}","starred_url":"https://api.github.com/users/gocardless/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gocardless/subscriptions","organizations_url":"https://api.github.com/users/gocardless/orgs","repos_url":"https://api.github.com/users/gocardless/repos","events_url":"https://api.github.com/users/gocardless/events{/privacy}","received_events_url":"https://api.github.com/users/gocardless/received_events","type":"Organization","site_admin":false},"repo":{"id":31955140,"name":"que","full_name":"gocardless/que","owner":{"login":"gocardless","id":790629,"avatar_url":"https://avatars.githubusercontent.com/u/790629?v=3","gravatar_id":"","url":"https://api.github.com/users/gocardless","html_url":"https://github.com/gocardless","followers_url":"https://api.github.com/users/gocardless/followers","following_url":"https://api.github.com/users/gocardless/following{/other_user}","gists_url":"https://api.github.com/users/gocardless/gists{/gist_id}","starred_url":"https://api.github.com/users/gocardless/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gocardless/subscriptions","organizations_url":"https://api.github.com/users/gocardless/orgs","repos_url":"https://api.github.com/users/gocardless/repos","events_url":"https://api.github.com/users/gocardless/events{/privacy}","received_events_url":"https://api.github.com/users/gocardless/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/gocardless/que","description":"A Ruby job queue that uses PostgreSQL's advisory locks for speed and reliability.","fork":true,"url":"https://api.github.com/repos/gocardless/que","forks_url":"https://api.github.com/repos/gocardless/que/forks","keys_url":"https://api.github.com/repos/gocardless/que/keys{/key_id}","collaborators_url":"https://api.github.com/repos/gocardless/que/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/gocardless/que/teams","hooks_url":"https://api.github.com/repos/gocardless/que/hooks","issue_events_url":"https://api.github.com/repos/gocardless/que/issues/events{/number}","events_url":"https://api.github.com/repos/gocardless/que/events","assignees_url":"https://api.github.com/repos/gocardless/que/assignees{/user}","branches_url":"https://api.github.com/repos/gocardless/que/branches{/branch}","tags_url":"https://api.github.com/repos/gocardless/que/tags","blobs_url":"https://api.github.com/repos/gocardless/que/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/gocardless/que/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/gocardless/que/git/refs{/sha}","trees_url":"https://api.github.com/repos/gocardless/que/git/trees{/sha}","statuses_url":"https://api.github.com/repos/gocardless/que/statuses/{sha}","languages_url":"https://api.github.com/repos/gocardless/que/languages","stargazers_url":"https://api.github.com/repos/gocardless/que/stargazers","contributors_url":"https://api.github.com/repos/gocardless/que/contributors","subscribers_url":"https://api.github.com/repos/gocardless/que/subscribers","subscription_url":"https://api.github.com/repos/gocardless/que/subscription","commits_url":"https://api.github.com/repos/gocardless/que/commits{/sha}","git_commits_url":"https://api.github.com/repos/gocardless/que/git/commits{/sha}","comments_url":"https://api.github.com/repos/gocardless/que/comments{/number}","issue_comment_url":"https://api.github.com/repos/gocardless/que/issues/comments{/number}","contents_url":"https://api.github.com/repos/gocardless/que/contents/{+path}","compare_url":"https://api.github.com/repos/gocardless/que/compare/{base}...{head}","merges_url":"https://api.github.com/repos/gocardless/que/merges","archive_url":"https://api.github.com/repos/gocardless/que/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/gocardless/que/downloads","issues_url":"https://api.github.com/repos/gocardless/que/issues{/number}","pulls_url":"https://api.github.com/repos/gocardless/que/pulls{/number}","milestones_url":"https://api.github.com/repos/gocardless/que/milestones{/number}","notifications_url":"https://api.github.com/repos/gocardless/que/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/gocardless/que/labels{/name}","releases_url":"https://api.github.com/repos/gocardless/que/releases{/id}","deployments_url":"https://api.github.com/repos/gocardless/que/deployments","created_at":"2015-03-10T12:04:49Z","updated_at":"2016-06-29T03:27:53Z","pushed_at":"2016-07-01T19:49:06Z","git_url":"git://github.com/gocardless/que.git","ssh_url":"git@github.com:gocardless/que.git","clone_url":"https://github.com/gocardless/que.git","svn_url":"https://github.com/gocardless/que","homepage":"","size":796,"stargazers_count":1,"watchers_count":1,"language":"Ruby","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"chanks:master","ref":"master","sha":"4dc843201fa040f7e672ab44feb59733a6b48638","user":{"login":"chanks","id":300058,"avatar_url":"https://avatars.githubusercontent.com/u/300058?v=3","gravatar_id":"","url":"https://api.github.com/users/chanks","html_url":"https://github.com/chanks","followers_url":"https://api.github.com/users/chanks/followers","following_url":"https://api.github.com/users/chanks/following{/other_user}","gists_url":"https://api.github.com/users/chanks/gists{/gist_id}","starred_url":"https://api.github.com/users/chanks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chanks/subscriptions","organizations_url":"https://api.github.com/users/chanks/orgs","repos_url":"https://api.github.com/users/chanks/repos","events_url":"https://api.github.com/users/chanks/events{/privacy}","received_events_url":"https://api.github.com/users/chanks/received_events","type":"User","site_admin":false},"repo":{"id":14000045,"name":"que","full_name":"chanks/que","owner":{"login":"chanks","id":300058,"avatar_url":"https://avatars.githubusercontent.com/u/300058?v=3","gravatar_id":"","url":"https://api.github.com/users/chanks","html_url":"https://github.com/chanks","followers_url":"https://api.github.com/users/chanks/followers","following_url":"https://api.github.com/users/chanks/following{/other_user}","gists_url":"https://api.github.com/users/chanks/gists{/gist_id}","starred_url":"https://api.github.com/users/chanks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chanks/subscriptions","organizations_url":"https://api.github.com/users/chanks/orgs","repos_url":"https://api.github.com/users/chanks/repos","events_url":"https://api.github.com/users/chanks/events{/privacy}","received_events_url":"https://api.github.com/users/chanks/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/chanks/que","description":"A Ruby job queue that uses PostgreSQL's advisory locks for speed and reliability.","fork":false,"url":"https://api.github.com/repos/chanks/que","forks_url":"https://api.github.com/repos/chanks/que/forks","keys_url":"https://api.github.com/repos/chanks/que/keys{/key_id}","collaborators_url":"https://api.github.com/repos/chanks/que/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/chanks/que/teams","hooks_url":"https://api.github.com/repos/chanks/que/hooks","issue_events_url":"https://api.github.com/repos/chanks/que/issues/events{/number}","events_url":"https://api.github.com/repos/chanks/que/events","assignees_url":"https://api.github.com/repos/chanks/que/assignees{/user}","branches_url":"https://api.github.com/repos/chanks/que/branches{/branch}","tags_url":"https://api.github.com/repos/chanks/que/tags","blobs_url":"https://api.github.com/repos/chanks/que/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/chanks/que/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/chanks/que/git/refs{/sha}","trees_url":"https://api.github.com/repos/chanks/que/git/trees{/sha}","statuses_url":"https://api.github.com/repos/chanks/que/statuses/{sha}","languages_url":"https://api.github.com/repos/chanks/que/languages","stargazers_url":"https://api.github.com/repos/chanks/que/stargazers","contributors_url":"https://api.github.com/repos/chanks/que/contributors","subscribers_url":"https://api.github.com/repos/chanks/que/subscribers","subscription_url":"https://api.github.com/repos/chanks/que/subscription","commits_url":"https://api.github.com/repos/chanks/que/commits{/sha}","git_commits_url":"https://api.github.com/repos/chanks/que/git/commits{/sha}","comments_url":"https://api.github.com/repos/chanks/que/comments{/number}","issue_comment_url":"https://api.github.com/repos/chanks/que/issues/comments{/number}","contents_url":"https://api.github.com/repos/chanks/que/contents/{+path}","compare_url":"https://api.github.com/repos/chanks/que/compare/{base}...{head}","merges_url":"https://api.github.com/repos/chanks/que/merges","archive_url":"https://api.github.com/repos/chanks/que/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/chanks/que/downloads","issues_url":"https://api.github.com/repos/chanks/que/issues{/number}","pulls_url":"https://api.github.com/repos/chanks/que/pulls{/number}","milestones_url":"https://api.github.com/repos/chanks/que/milestones{/number}","notifications_url":"https://api.github.com/repos/chanks/que/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/chanks/que/labels{/name}","releases_url":"https://api.github.com/repos/chanks/que/releases{/id}","deployments_url":"https://api.github.com/repos/chanks/que/deployments","created_at":"2013-10-30T21:21:53Z","updated_at":"2016-09-07T00:41:13Z","pushed_at":"2016-09-09T19:27:18Z","git_url":"git://github.com/chanks/que.git","ssh_url":"git@github.com:chanks/que.git","clone_url":"https://github.com/chanks/que.git","svn_url":"https://github.com/chanks/que","homepage":"","size":962,"stargazers_count":1012,"watchers_count":1012,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":63,"mirror_url":null,"open_issues_count":16,"forks":63,"open_issues":16,"watchers":1012,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/chanks/que/pulls/106"},"html":{"href":"https://github.com/chanks/que/pull/106"},"issue":{"href":"https://api.github.com/repos/chanks/que/issues/106"},"comments":{"href":"https://api.github.com/repos/chanks/que/issues/106/comments"},"review_comments":{"href":"https://api.github.com/repos/chanks/que/pulls/106/comments"},"review_comment":{"href":"https://api.github.com/repos/chanks/que/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/chanks/que/pulls/106/commits"},"statuses":{"href":"https://api.github.com/repos/chanks/que/statuses/493822047483c957bdc56a833f49f129d7ffc463"}},"merged":false,"mergeable":false,"mergeable_state":"dirty","merged_by":null,"comments":15,"review_comments":0,"commits":1,"additions":52,"deletions":15,"changed_files":7}}
{"actor":{"display_login":"chanks"}}