{"action":"created","comment":{"url":"https://api.github.com/repos/giftcardzen/la_gear/pulls/comments/30659392","id":30659392,"diff_hunk":"@@ -0,0 +1,121 @@\n+module LaGear\n+  module Sneakers\n+    module Handlers\n+      class ExponentialBackoff\n+        def initialize(channel, opts)\n+          @channel = channel\n+          @opts = opts\n+\n+          exchange = @opts.fetch(:exchange)\n+          @handler_opts = @opts.fetch(:handler_opts, {})\n+\n+          retry_name = @handler_opts.fetch(:retryexchange, \"#{exchange}.retry\")\n+          error_name = @handler_opts.fetch(:errorexchange, \"#{exchange}.error\")\n+\n+          @publish_channel = setup_publish_channel\n+          @retry_exchange = setup_retry(@publish_channel, retry_name, exchange)\n+          @error_exchange = setup_error(@publish_channel, error_name)\n+\n+          @max_retries = @handler_opts.fetch(:max_retries, 5)\n+          @expiration = @handler_opts.fetch(:expiration, 1000)\n+        end\n+\n+        def acknowledge(hdr)\n+          @channel.acknowledge(hdr.delivery_tag, false)\n+        end\n+\n+        def reject(hdr, props, msg, _requeue = false)\n+          retry_or_error(hdr, props, msg, 'rejected')\n+        end\n+\n+        def error(hdr, props, msg, err)\n+          retry_or_error(hdr, props, msg, err)\n+        end\n+\n+        def timeout(hdr, props, msg)\n+          error(hdr, props, msg, 'Timeout: Sneakers worker timedout.')\n+        end\n+\n+        def noop(_hdr); end\n+\n+        private\n+\n+        def retry_or_error(hdr, props, msg, reason, _requeue=false)\n+          retries = get_retries(props[:headers])\n+          if retries >= @max_retries\n+            @error_exchange.publish(\n+              msg,\n+              routing_key: @handler_opts.fetch(:routing_key, hdr.routing_key),\n+              headers: { \"sneakers-error-reason\" => (reason || \"Doh! No reason given. :(\").inspect }\n+            )\n+          else\n+            expire_delay = get_expire_delay(retries)\n+\n+            @retry_exchange.publish(msg,\n+                                    routing_key: @handler_opts.fetch(:routing_key, hdr.routing_key),\n+                                    expiration: expire_delay,\n+                                    headers: {\n+                                      'sneakers-retries' => retries + 1,\n+                                      \"sneakers-retry-reason\" => (reason || 'Doh! No reason given.').inspect\n+                                    })\n+          end\n+          @channel.acknowledge(hdr.delivery_tag, false)\n+        rescue => e\n+          logger.fatal \"#{self} #{e}, hdr.routing_key #{hdr.routing_key}, props #{props}, msg #{msg}, reason #{reason}, handler_opts #{@handler_opts}, retries #{retries}\"\n+        end\n+\n+        def setup_retry(publish_channel, retry_name, exchange)\n+          retry_exchange = publish_channel.exchange(retry_name,\n+                                                    :type    => 'topic',\n+                                                    :durable => 'true')\n+          retry_queue    = publish_channel.queue(retry_name,\n+                                                 :durable   => 'true',\n+                                                 :arguments => {\n+                                                   :'x-dead-letter-exchange' => exchange,\n+                                                 })\n+          retry_queue.bind(retry_exchange, :routing_key => '#')\n+          trace(retry_queue, '#{self} retry queue created.')\n+          retry_exchange\n+        end\n+\n+        def setup_error(publish_channel, error_name)\n+          error_exchange = publish_channel.exchange(error_name,\n+                                                    :type    => 'topic',\n+                                                    :durable => 'true')\n+          error_queue = publish_channel.queue(error_name, :durable => 'true')\n+          error_queue.bind(error_exchange, :routing_key => '#')\n+          trace(error_queue, '#{self} error queue created.')\n+          error_exchange\n+        end\n+\n+        def setup_publish_channel\n+          return @channel unless @opts.include?(:amqp_publish)\n+          publish_bunny = Bunny.new(@opts[:amqp_publish], vhost: @opts[:vhost], heartbeat: @opts[:heartbeat])\n+          publish_bunny.start\n+          publish_channel = publish_bunny.create_channel\n+          publish_channel.prefetch(@opts[:prefetch])\n+          logger.warn \"#{self} publish endpoint used: #{@opts[:amqp_publish]}, vhost #{@opts[:vhost]}\"\n+          publish_channel\n+        end\n+\n+        def trace(queue, msg)\n+          logger.debug \"[#{Thread.current}][#{queue.name}][#{queue.options}] #{msg}\"","path":"lib/la_gear/sneakers/exponential_backoff.rb","position":102,"original_position":102,"commit_id":"1bd34a84d0129e137f64facfc181218ddd915fcc","original_commit_id":"1bd34a84d0129e137f64facfc181218ddd915fcc","user":{"login":"houndci","id":6697940,"avatar_url":"https://avatars.githubusercontent.com/u/6697940?v=3","gravatar_id":"","url":"https://api.github.com/users/houndci","html_url":"https://github.com/houndci","followers_url":"https://api.github.com/users/houndci/followers","following_url":"https://api.github.com/users/houndci/following{/other_user}","gists_url":"https://api.github.com/users/houndci/gists{/gist_id}","starred_url":"https://api.github.com/users/houndci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/houndci/subscriptions","organizations_url":"https://api.github.com/users/houndci/orgs","repos_url":"https://api.github.com/users/houndci/repos","events_url":"https://api.github.com/users/houndci/events{/privacy}","received_events_url":"https://api.github.com/users/houndci/received_events","type":"User","site_admin":false},"body":"Line is too long. [84/80]","created_at":"2015-05-19T23:37:56Z","updated_at":"2015-05-19T23:37:56Z","html_url":"https://github.com/giftcardzen/la_gear/pull/16#discussion_r30659392","pull_request_url":"https://api.github.com/repos/giftcardzen/la_gear/pulls/16","_links":{"self":{"href":"https://api.github.com/repos/giftcardzen/la_gear/pulls/comments/30659392"},"html":{"href":"https://github.com/giftcardzen/la_gear/pull/16#discussion_r30659392"},"pull_request":{"href":"https://api.github.com/repos/giftcardzen/la_gear/pulls/16"}}},"pull_request":{"url":"https://api.github.com/repos/giftcardzen/la_gear/pulls/16","id":35785586,"html_url":"https://github.com/giftcardzen/la_gear/pull/16","diff_url":"https://github.com/giftcardzen/la_gear/pull/16.diff","patch_url":"https://github.com/giftcardzen/la_gear/pull/16.patch","issue_url":"https://api.github.com/repos/giftcardzen/la_gear/issues/16","number":16,"state":"open","locked":false,"title":"Exponential backoff","user":{"login":"crazydog115","id":794237,"avatar_url":"https://avatars.githubusercontent.com/u/794237?v=3","gravatar_id":"","url":"https://api.github.com/users/crazydog115","html_url":"https://github.com/crazydog115","followers_url":"https://api.github.com/users/crazydog115/followers","following_url":"https://api.github.com/users/crazydog115/following{/other_user}","gists_url":"https://api.github.com/users/crazydog115/gists{/gist_id}","starred_url":"https://api.github.com/users/crazydog115/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/crazydog115/subscriptions","organizations_url":"https://api.github.com/users/crazydog115/orgs","repos_url":"https://api.github.com/users/crazydog115/repos","events_url":"https://api.github.com/users/crazydog115/events{/privacy}","received_events_url":"https://api.github.com/users/crazydog115/received_events","type":"User","site_admin":false},"body":"v1.0.0 after this is merged","created_at":"2015-05-19T23:31:21Z","updated_at":"2015-05-19T23:37:56Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d72f6b9e11b9942580fd3c93577f84e8f5942b8c","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/giftcardzen/la_gear/pulls/16/commits","review_comments_url":"https://api.github.com/repos/giftcardzen/la_gear/pulls/16/comments","review_comment_url":"https://api.github.com/repos/giftcardzen/la_gear/pulls/comments{/number}","comments_url":"https://api.github.com/repos/giftcardzen/la_gear/issues/16/comments","statuses_url":"https://api.github.com/repos/giftcardzen/la_gear/statuses/1bd34a84d0129e137f64facfc181218ddd915fcc","head":{"label":"giftcardzen:exponential_backoff","ref":"exponential_backoff","sha":"1bd34a84d0129e137f64facfc181218ddd915fcc","user":{"login":"giftcardzen","id":7176061,"avatar_url":"https://avatars.githubusercontent.com/u/7176061?v=3","gravatar_id":"","url":"https://api.github.com/users/giftcardzen","html_url":"https://github.com/giftcardzen","followers_url":"https://api.github.com/users/giftcardzen/followers","following_url":"https://api.github.com/users/giftcardzen/following{/other_user}","gists_url":"https://api.github.com/users/giftcardzen/gists{/gist_id}","starred_url":"https://api.github.com/users/giftcardzen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/giftcardzen/subscriptions","organizations_url":"https://api.github.com/users/giftcardzen/orgs","repos_url":"https://api.github.com/users/giftcardzen/repos","events_url":"https://api.github.com/users/giftcardzen/events{/privacy}","received_events_url":"https://api.github.com/users/giftcardzen/received_events","type":"Organization","site_admin":false},"repo":{"id":23089940,"name":"la_gear","full_name":"giftcardzen/la_gear","owner":{"login":"giftcardzen","id":7176061,"avatar_url":"https://avatars.githubusercontent.com/u/7176061?v=3","gravatar_id":"","url":"https://api.github.com/users/giftcardzen","html_url":"https://github.com/giftcardzen","followers_url":"https://api.github.com/users/giftcardzen/followers","following_url":"https://api.github.com/users/giftcardzen/following{/other_user}","gists_url":"https://api.github.com/users/giftcardzen/gists{/gist_id}","starred_url":"https://api.github.com/users/giftcardzen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/giftcardzen/subscriptions","organizations_url":"https://api.github.com/users/giftcardzen/orgs","repos_url":"https://api.github.com/users/giftcardzen/repos","events_url":"https://api.github.com/users/giftcardzen/events{/privacy}","received_events_url":"https://api.github.com/users/giftcardzen/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/giftcardzen/la_gear","description":"What do you get when you glue sneakers and sidekiq together? la_gear! Pump it up!","fork":false,"url":"https://api.github.com/repos/giftcardzen/la_gear","forks_url":"https://api.github.com/repos/giftcardzen/la_gear/forks","keys_url":"https://api.github.com/repos/giftcardzen/la_gear/keys{/key_id}","collaborators_url":"https://api.github.com/repos/giftcardzen/la_gear/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/giftcardzen/la_gear/teams","hooks_url":"https://api.github.com/repos/giftcardzen/la_gear/hooks","issue_events_url":"https://api.github.com/repos/giftcardzen/la_gear/issues/events{/number}","events_url":"https://api.github.com/repos/giftcardzen/la_gear/events","assignees_url":"https://api.github.com/repos/giftcardzen/la_gear/assignees{/user}","branches_url":"https://api.github.com/repos/giftcardzen/la_gear/branches{/branch}","tags_url":"https://api.github.com/repos/giftcardzen/la_gear/tags","blobs_url":"https://api.github.com/repos/giftcardzen/la_gear/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/giftcardzen/la_gear/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/giftcardzen/la_gear/git/refs{/sha}","trees_url":"https://api.github.com/repos/giftcardzen/la_gear/git/trees{/sha}","statuses_url":"https://api.github.com/repos/giftcardzen/la_gear/statuses/{sha}","languages_url":"https://api.github.com/repos/giftcardzen/la_gear/languages","stargazers_url":"https://api.github.com/repos/giftcardzen/la_gear/stargazers","contributors_url":"https://api.github.com/repos/giftcardzen/la_gear/contributors","subscribers_url":"https://api.github.com/repos/giftcardzen/la_gear/subscribers","subscription_url":"https://api.github.com/repos/giftcardzen/la_gear/subscription","commits_url":"https://api.github.com/repos/giftcardzen/la_gear/commits{/sha}","git_commits_url":"https://api.github.com/repos/giftcardzen/la_gear/git/commits{/sha}","comments_url":"https://api.github.com/repos/giftcardzen/la_gear/comments{/number}","issue_comment_url":"https://api.github.com/repos/giftcardzen/la_gear/issues/comments{/number}","contents_url":"https://api.github.com/repos/giftcardzen/la_gear/contents/{+path}","compare_url":"https://api.github.com/repos/giftcardzen/la_gear/compare/{base}...{head}","merges_url":"https://api.github.com/repos/giftcardzen/la_gear/merges","archive_url":"https://api.github.com/repos/giftcardzen/la_gear/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/giftcardzen/la_gear/downloads","issues_url":"https://api.github.com/repos/giftcardzen/la_gear/issues{/number}","pulls_url":"https://api.github.com/repos/giftcardzen/la_gear/pulls{/number}","milestones_url":"https://api.github.com/repos/giftcardzen/la_gear/milestones{/number}","notifications_url":"https://api.github.com/repos/giftcardzen/la_gear/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/giftcardzen/la_gear/labels{/name}","releases_url":"https://api.github.com/repos/giftcardzen/la_gear/releases{/id}","created_at":"2014-08-18T23:29:18Z","updated_at":"2015-04-07T19:47:32Z","pushed_at":"2015-05-19T23:37:48Z","git_url":"git://github.com/giftcardzen/la_gear.git","ssh_url":"git@github.com:giftcardzen/la_gear.git","clone_url":"https://github.com/giftcardzen/la_gear.git","svn_url":"https://github.com/giftcardzen/la_gear","homepage":"","size":492,"stargazers_count":1,"watchers_count":1,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":10,"forks":0,"open_issues":10,"watchers":1,"default_branch":"master"}},"base":{"label":"giftcardzen:master","ref":"master","sha":"8e06dec860fb54bf77d7266e1d469070db95abbf","user":{"login":"giftcardzen","id":7176061,"avatar_url":"https://avatars.githubusercontent.com/u/7176061?v=3","gravatar_id":"","url":"https://api.github.com/users/giftcardzen","html_url":"https://github.com/giftcardzen","followers_url":"https://api.github.com/users/giftcardzen/followers","following_url":"https://api.github.com/users/giftcardzen/following{/other_user}","gists_url":"https://api.github.com/users/giftcardzen/gists{/gist_id}","starred_url":"https://api.github.com/users/giftcardzen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/giftcardzen/subscriptions","organizations_url":"https://api.github.com/users/giftcardzen/orgs","repos_url":"https://api.github.com/users/giftcardzen/repos","events_url":"https://api.github.com/users/giftcardzen/events{/privacy}","received_events_url":"https://api.github.com/users/giftcardzen/received_events","type":"Organization","site_admin":false},"repo":{"id":23089940,"name":"la_gear","full_name":"giftcardzen/la_gear","owner":{"login":"giftcardzen","id":7176061,"avatar_url":"https://avatars.githubusercontent.com/u/7176061?v=3","gravatar_id":"","url":"https://api.github.com/users/giftcardzen","html_url":"https://github.com/giftcardzen","followers_url":"https://api.github.com/users/giftcardzen/followers","following_url":"https://api.github.com/users/giftcardzen/following{/other_user}","gists_url":"https://api.github.com/users/giftcardzen/gists{/gist_id}","starred_url":"https://api.github.com/users/giftcardzen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/giftcardzen/subscriptions","organizations_url":"https://api.github.com/users/giftcardzen/orgs","repos_url":"https://api.github.com/users/giftcardzen/repos","events_url":"https://api.github.com/users/giftcardzen/events{/privacy}","received_events_url":"https://api.github.com/users/giftcardzen/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/giftcardzen/la_gear","description":"What do you get when you glue sneakers and sidekiq together? la_gear! Pump it up!","fork":false,"url":"https://api.github.com/repos/giftcardzen/la_gear","forks_url":"https://api.github.com/repos/giftcardzen/la_gear/forks","keys_url":"https://api.github.com/repos/giftcardzen/la_gear/keys{/key_id}","collaborators_url":"https://api.github.com/repos/giftcardzen/la_gear/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/giftcardzen/la_gear/teams","hooks_url":"https://api.github.com/repos/giftcardzen/la_gear/hooks","issue_events_url":"https://api.github.com/repos/giftcardzen/la_gear/issues/events{/number}","events_url":"https://api.github.com/repos/giftcardzen/la_gear/events","assignees_url":"https://api.github.com/repos/giftcardzen/la_gear/assignees{/user}","branches_url":"https://api.github.com/repos/giftcardzen/la_gear/branches{/branch}","tags_url":"https://api.github.com/repos/giftcardzen/la_gear/tags","blobs_url":"https://api.github.com/repos/giftcardzen/la_gear/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/giftcardzen/la_gear/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/giftcardzen/la_gear/git/refs{/sha}","trees_url":"https://api.github.com/repos/giftcardzen/la_gear/git/trees{/sha}","statuses_url":"https://api.github.com/repos/giftcardzen/la_gear/statuses/{sha}","languages_url":"https://api.github.com/repos/giftcardzen/la_gear/languages","stargazers_url":"https://api.github.com/repos/giftcardzen/la_gear/stargazers","contributors_url":"https://api.github.com/repos/giftcardzen/la_gear/contributors","subscribers_url":"https://api.github.com/repos/giftcardzen/la_gear/subscribers","subscription_url":"https://api.github.com/repos/giftcardzen/la_gear/subscription","commits_url":"https://api.github.com/repos/giftcardzen/la_gear/commits{/sha}","git_commits_url":"https://api.github.com/repos/giftcardzen/la_gear/git/commits{/sha}","comments_url":"https://api.github.com/repos/giftcardzen/la_gear/comments{/number}","issue_comment_url":"https://api.github.com/repos/giftcardzen/la_gear/issues/comments{/number}","contents_url":"https://api.github.com/repos/giftcardzen/la_gear/contents/{+path}","compare_url":"https://api.github.com/repos/giftcardzen/la_gear/compare/{base}...{head}","merges_url":"https://api.github.com/repos/giftcardzen/la_gear/merges","archive_url":"https://api.github.com/repos/giftcardzen/la_gear/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/giftcardzen/la_gear/downloads","issues_url":"https://api.github.com/repos/giftcardzen/la_gear/issues{/number}","pulls_url":"https://api.github.com/repos/giftcardzen/la_gear/pulls{/number}","milestones_url":"https://api.github.com/repos/giftcardzen/la_gear/milestones{/number}","notifications_url":"https://api.github.com/repos/giftcardzen/la_gear/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/giftcardzen/la_gear/labels{/name}","releases_url":"https://api.github.com/repos/giftcardzen/la_gear/releases{/id}","created_at":"2014-08-18T23:29:18Z","updated_at":"2015-04-07T19:47:32Z","pushed_at":"2015-05-19T23:37:48Z","git_url":"git://github.com/giftcardzen/la_gear.git","ssh_url":"git@github.com:giftcardzen/la_gear.git","clone_url":"https://github.com/giftcardzen/la_gear.git","svn_url":"https://github.com/giftcardzen/la_gear","homepage":"","size":492,"stargazers_count":1,"watchers_count":1,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":10,"forks":0,"open_issues":10,"watchers":1,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/giftcardzen/la_gear/pulls/16"},"html":{"href":"https://github.com/giftcardzen/la_gear/pull/16"},"issue":{"href":"https://api.github.com/repos/giftcardzen/la_gear/issues/16"},"comments":{"href":"https://api.github.com/repos/giftcardzen/la_gear/issues/16/comments"},"review_comments":{"href":"https://api.github.com/repos/giftcardzen/la_gear/pulls/16/comments"},"review_comment":{"href":"https://api.github.com/repos/giftcardzen/la_gear/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/giftcardzen/la_gear/pulls/16/commits"},"statuses":{"href":"https://api.github.com/repos/giftcardzen/la_gear/statuses/1bd34a84d0129e137f64facfc181218ddd915fcc"}}}}