{"action":"created","comment":{"url":"https://api.github.com/repos/jondot/sneakers/pulls/comments/48998180","id":48998180,"diff_hunk":"@@ -100,8 +85,352 @@ def start_worker(w)\n          jobs: job_count,\n       )\n     end\n-    \n+\n   end\n-end\n-  \n \n+  describe 'worker with maxretry handler' do\n+    let(:rabbitmq_client) do\n+      RabbitMQ::HTTP::Client.new('http://guest:guest@127.0.0.1:15672/')\n+    end\n+    let(:redis) { Redis.new }\n+    let(:queue_name) { \"integration_#{rand(10**36).to_s(36)}\" }\n+    let(:exchange_name) { \"integration_#{rand(10**36).to_s(36)}\" }\n+\n+    before :each do\n+      skip unless ENV['INTEGRATION']\n+\n+      begin\n+        rabbitmq_client.overview\n+      rescue\n+        puts 'Rabbitmq admin seems to not exist? You better be running this on'\\\n+          \"Travis or Docker. proceeding.\\n#{$ERROR_INFO}\"\n+        skip\n+      end\n+\n+      begin\n+        redis.info\n+      rescue\n+        puts 'Redis seems to not exist? You better be running this on'\\\n+          'Travis or Docker.'\n+        skip\n+      end\n+\n+      cleanup_rabbitmq(rabbitmq_client)\n+      cleanup_redis(redis)\n+      prepare_sneakers(exchange: exchange_name)\n+\n+      worker.from_queue(queue_name, worker_opts)\n+      @worker_pid = start_worker(worker)\n+    end\n+\n+    after :each do\n+      Process.kill('TERM', @worker_pid)\n+\n+      cleanup_rabbitmq(rabbitmq_client)\n+      cleanup_redis(redis)\n+    end\n+\n+    describe 'with defaults for maxretry handler' do\n+      let(:worker) { MaxretryWorker }\n+      let(:worker_opts) do\n+        {\n+          handler:         Sneakers::Handlers::Maxretry,\n+          retry_max_times: 2,\n+          retry_timeout:   100,\n+          arguments: {\n+            'x-dead-letter-exchange' => \"#{queue_name}-retry\"\n+          }\n+        }\n+      end\n+\n+      it 'creates the required exchanges' do\n+        expected_exchange_names = [\n+          exchange_name,\n+          \"#{queue_name}-error\",\n+          \"#{queue_name}-retry\",\n+          \"#{queue_name}-retry-requeue\"\n+        ]\n+        exchange_names = rabbitmq_client.list_exchanges.map(&:name)\n+\n+        expected_exchange_names.each do |expected_exchange_name|\n+          assert_includes(exchange_names, expected_exchange_name)\n+        end\n+      end\n+\n+      it 'creates the required queues' do\n+        expected_queue_names = [\n+          queue_name,\n+          \"#{queue_name}-error\",\n+          \"#{queue_name}-retry\"\n+        ]\n+        queue_names = rabbitmq_client.list_queues.map(&:name)\n+\n+        expected_queue_names.each do |expected_queue_name|\n+          assert_includes(queue_names, expected_queue_name)\n+        end\n+      end\n+\n+      describe 'when worker allways fails' do\n+        let(:worker) { FailingMaxretryWorker }\n+\n+        before do\n+          Sneakers::Publisher.new(\n+            exchange: exchange_name\n+          ).publish(\n+            'foo',\n+            routing_key: queue_name\n+          )\n+        end\n+\n+        it 'has a message in the error queue' do\n+          # wait for failing message\n+          sleep REQUEUING_WAIT_TIME\n+\n+          message = get_message_from_queue(\"#{queue_name}-error\")\n+\n+          refute_nil(message.first)\n+        end\n+\n+        it 'has been retried twice' do\n+          # wait for failing message\n+          sleep REQUEUING_WAIT_TIME\n+\n+          message = get_message_from_queue(\"#{queue_name}-error\")\n+\n+          # Hmmmmm... should be 2\n+          assert_equal(JSON.load(message[2])['num_attempts'], 3)\n+        end\n+      end\n+\n+      describe 'when worker fails once' do\n+        let(:worker) { RetryOnceWorker }\n+\n+        before do\n+          Sneakers::Publisher.new(\n+            exchange: exchange_name\n+          ).publish(\n+            'foo',\n+            routing_key: queue_name\n+          )\n+        end\n+\n+        it 'has no message in the error queue' do\n+          # wait for failing message\n+          sleep REQUEUING_WAIT_TIME\n+\n+          message = get_message_from_queue(\"#{queue_name}-error\")\n+\n+          assert_nil(message.first)\n+        end\n+\n+        it 'consumes the requeued message' do","path":"spec/sneakers/integration_spec.rb","position":204,"original_position":205,"commit_id":"40a8caf692668c8070ddc96764605918d99763a6","original_commit_id":"bde75aae4fb9b25669b36af4523fa79e725bf35c","user":{"login":"nevesenin","id":102794,"avatar_url":"https://avatars.githubusercontent.com/u/102794?v=3","gravatar_id":"","url":"https://api.github.com/users/nevesenin","html_url":"https://github.com/nevesenin","followers_url":"https://api.github.com/users/nevesenin/followers","following_url":"https://api.github.com/users/nevesenin/following{/other_user}","gists_url":"https://api.github.com/users/nevesenin/gists{/gist_id}","starred_url":"https://api.github.com/users/nevesenin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nevesenin/subscriptions","organizations_url":"https://api.github.com/users/nevesenin/orgs","repos_url":"https://api.github.com/users/nevesenin/repos","events_url":"https://api.github.com/users/nevesenin/events{/privacy}","received_events_url":"https://api.github.com/users/nevesenin/received_events","type":"User","site_admin":false},"body":"Ok, now I got your point. I never thought about a scenario where routing keys are important for the consumer. I see routing keys as information for rabbitmq. The worker needs to know the routing key, only because it creates the binding between exchange and queue. It consumes every message in the queue no matter how it gets there.\r\nThe retried message does not have the same routing key as the original message. There is an additional binding which routes the retry messages to the original queue.\r\nI added some integration tests to show how the maxretry handler would work in our existing environment. It creates only one additional exchange. The error exchange. This is why we need different routing keys.\r\nIf it is important to keep the original routing key, I think I should add a new\r\nhandler instead of changing this one.\r\n","created_at":"2016-01-06T19:29:16Z","updated_at":"2016-01-06T19:29:16Z","html_url":"https://github.com/jondot/sneakers/pull/194#discussion_r48998180","pull_request_url":"https://api.github.com/repos/jondot/sneakers/pulls/194","_links":{"self":{"href":"https://api.github.com/repos/jondot/sneakers/pulls/comments/48998180"},"html":{"href":"https://github.com/jondot/sneakers/pull/194#discussion_r48998180"},"pull_request":{"href":"https://api.github.com/repos/jondot/sneakers/pulls/194"}}},"pull_request":{"url":"https://api.github.com/repos/jondot/sneakers/pulls/194","id":53943688,"html_url":"https://github.com/jondot/sneakers/pull/194","diff_url":"https://github.com/jondot/sneakers/pull/194.diff","patch_url":"https://github.com/jondot/sneakers/pull/194.patch","issue_url":"https://api.github.com/repos/jondot/sneakers/issues/194","number":194,"state":"open","locked":false,"title":"Maxretry more flexible","user":{"login":"nevesenin","id":102794,"avatar_url":"https://avatars.githubusercontent.com/u/102794?v=3","gravatar_id":"","url":"https://api.github.com/users/nevesenin","html_url":"https://github.com/nevesenin","followers_url":"https://api.github.com/users/nevesenin/followers","following_url":"https://api.github.com/users/nevesenin/following{/other_user}","gists_url":"https://api.github.com/users/nevesenin/gists{/gist_id}","starred_url":"https://api.github.com/users/nevesenin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nevesenin/subscriptions","organizations_url":"https://api.github.com/users/nevesenin/orgs","repos_url":"https://api.github.com/users/nevesenin/repos","events_url":"https://api.github.com/users/nevesenin/events{/privacy}","received_events_url":"https://api.github.com/users/nevesenin/received_events","type":"User","site_admin":false},"body":"Hi,\r\n\r\nwe are currently evaluating if we can switch from our own bunny wrapper gem to sneakers. To make sneakers fit to our existing infrastructure the MaxRetryHandler needs some more configuration options. I'd like to discuss the idea.\r\n\r\nMerten","created_at":"2015-12-17T07:40:47Z","updated_at":"2016-01-06T19:29:16Z","closed_at":null,"merged_at":null,"merge_commit_sha":"975ac29c41e9259a8145bbb67c6f0e97978c825a","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/jondot/sneakers/pulls/194/commits","review_comments_url":"https://api.github.com/repos/jondot/sneakers/pulls/194/comments","review_comment_url":"https://api.github.com/repos/jondot/sneakers/pulls/comments{/number}","comments_url":"https://api.github.com/repos/jondot/sneakers/issues/194/comments","statuses_url":"https://api.github.com/repos/jondot/sneakers/statuses/40a8caf692668c8070ddc96764605918d99763a6","head":{"label":"werliefertwas:feature/maxretry_more_flexible","ref":"feature/maxretry_more_flexible","sha":"40a8caf692668c8070ddc96764605918d99763a6","user":{"login":"werliefertwas","id":12716983,"avatar_url":"https://avatars.githubusercontent.com/u/12716983?v=3","gravatar_id":"","url":"https://api.github.com/users/werliefertwas","html_url":"https://github.com/werliefertwas","followers_url":"https://api.github.com/users/werliefertwas/followers","following_url":"https://api.github.com/users/werliefertwas/following{/other_user}","gists_url":"https://api.github.com/users/werliefertwas/gists{/gist_id}","starred_url":"https://api.github.com/users/werliefertwas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/werliefertwas/subscriptions","organizations_url":"https://api.github.com/users/werliefertwas/orgs","repos_url":"https://api.github.com/users/werliefertwas/repos","events_url":"https://api.github.com/users/werliefertwas/events{/privacy}","received_events_url":"https://api.github.com/users/werliefertwas/received_events","type":"Organization","site_admin":false},"repo":{"id":48049117,"name":"sneakers","full_name":"werliefertwas/sneakers","owner":{"login":"werliefertwas","id":12716983,"avatar_url":"https://avatars.githubusercontent.com/u/12716983?v=3","gravatar_id":"","url":"https://api.github.com/users/werliefertwas","html_url":"https://github.com/werliefertwas","followers_url":"https://api.github.com/users/werliefertwas/followers","following_url":"https://api.github.com/users/werliefertwas/following{/other_user}","gists_url":"https://api.github.com/users/werliefertwas/gists{/gist_id}","starred_url":"https://api.github.com/users/werliefertwas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/werliefertwas/subscriptions","organizations_url":"https://api.github.com/users/werliefertwas/orgs","repos_url":"https://api.github.com/users/werliefertwas/repos","events_url":"https://api.github.com/users/werliefertwas/events{/privacy}","received_events_url":"https://api.github.com/users/werliefertwas/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/werliefertwas/sneakers","description":"A fast background processing framework for Ruby and RabbitMQ","fork":true,"url":"https://api.github.com/repos/werliefertwas/sneakers","forks_url":"https://api.github.com/repos/werliefertwas/sneakers/forks","keys_url":"https://api.github.com/repos/werliefertwas/sneakers/keys{/key_id}","collaborators_url":"https://api.github.com/repos/werliefertwas/sneakers/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/werliefertwas/sneakers/teams","hooks_url":"https://api.github.com/repos/werliefertwas/sneakers/hooks","issue_events_url":"https://api.github.com/repos/werliefertwas/sneakers/issues/events{/number}","events_url":"https://api.github.com/repos/werliefertwas/sneakers/events","assignees_url":"https://api.github.com/repos/werliefertwas/sneakers/assignees{/user}","branches_url":"https://api.github.com/repos/werliefertwas/sneakers/branches{/branch}","tags_url":"https://api.github.com/repos/werliefertwas/sneakers/tags","blobs_url":"https://api.github.com/repos/werliefertwas/sneakers/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/werliefertwas/sneakers/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/werliefertwas/sneakers/git/refs{/sha}","trees_url":"https://api.github.com/repos/werliefertwas/sneakers/git/trees{/sha}","statuses_url":"https://api.github.com/repos/werliefertwas/sneakers/statuses/{sha}","languages_url":"https://api.github.com/repos/werliefertwas/sneakers/languages","stargazers_url":"https://api.github.com/repos/werliefertwas/sneakers/stargazers","contributors_url":"https://api.github.com/repos/werliefertwas/sneakers/contributors","subscribers_url":"https://api.github.com/repos/werliefertwas/sneakers/subscribers","subscription_url":"https://api.github.com/repos/werliefertwas/sneakers/subscription","commits_url":"https://api.github.com/repos/werliefertwas/sneakers/commits{/sha}","git_commits_url":"https://api.github.com/repos/werliefertwas/sneakers/git/commits{/sha}","comments_url":"https://api.github.com/repos/werliefertwas/sneakers/comments{/number}","issue_comment_url":"https://api.github.com/repos/werliefertwas/sneakers/issues/comments{/number}","contents_url":"https://api.github.com/repos/werliefertwas/sneakers/contents/{+path}","compare_url":"https://api.github.com/repos/werliefertwas/sneakers/compare/{base}...{head}","merges_url":"https://api.github.com/repos/werliefertwas/sneakers/merges","archive_url":"https://api.github.com/repos/werliefertwas/sneakers/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/werliefertwas/sneakers/downloads","issues_url":"https://api.github.com/repos/werliefertwas/sneakers/issues{/number}","pulls_url":"https://api.github.com/repos/werliefertwas/sneakers/pulls{/number}","milestones_url":"https://api.github.com/repos/werliefertwas/sneakers/milestones{/number}","notifications_url":"https://api.github.com/repos/werliefertwas/sneakers/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/werliefertwas/sneakers/labels{/name}","releases_url":"https://api.github.com/repos/werliefertwas/sneakers/releases{/id}","created_at":"2015-12-15T14:49:20Z","updated_at":"2015-12-15T14:49:21Z","pushed_at":"2016-01-06T19:23:49Z","git_url":"git://github.com/werliefertwas/sneakers.git","ssh_url":"git@github.com:werliefertwas/sneakers.git","clone_url":"https://github.com/werliefertwas/sneakers.git","svn_url":"https://github.com/werliefertwas/sneakers","homepage":"http://sneakers.io","size":1360,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"jondot:master","ref":"master","sha":"081208977eb5d606b1b7f6f3e24f83410e2c305b","user":{"login":"jondot","id":83390,"avatar_url":"https://avatars.githubusercontent.com/u/83390?v=3","gravatar_id":"","url":"https://api.github.com/users/jondot","html_url":"https://github.com/jondot","followers_url":"https://api.github.com/users/jondot/followers","following_url":"https://api.github.com/users/jondot/following{/other_user}","gists_url":"https://api.github.com/users/jondot/gists{/gist_id}","starred_url":"https://api.github.com/users/jondot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jondot/subscriptions","organizations_url":"https://api.github.com/users/jondot/orgs","repos_url":"https://api.github.com/users/jondot/repos","events_url":"https://api.github.com/users/jondot/events{/privacy}","received_events_url":"https://api.github.com/users/jondot/received_events","type":"User","site_admin":false},"repo":{"id":13441956,"name":"sneakers","full_name":"jondot/sneakers","owner":{"login":"jondot","id":83390,"avatar_url":"https://avatars.githubusercontent.com/u/83390?v=3","gravatar_id":"","url":"https://api.github.com/users/jondot","html_url":"https://github.com/jondot","followers_url":"https://api.github.com/users/jondot/followers","following_url":"https://api.github.com/users/jondot/following{/other_user}","gists_url":"https://api.github.com/users/jondot/gists{/gist_id}","starred_url":"https://api.github.com/users/jondot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jondot/subscriptions","organizations_url":"https://api.github.com/users/jondot/orgs","repos_url":"https://api.github.com/users/jondot/repos","events_url":"https://api.github.com/users/jondot/events{/privacy}","received_events_url":"https://api.github.com/users/jondot/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jondot/sneakers","description":"A fast background processing framework for Ruby and RabbitMQ","fork":false,"url":"https://api.github.com/repos/jondot/sneakers","forks_url":"https://api.github.com/repos/jondot/sneakers/forks","keys_url":"https://api.github.com/repos/jondot/sneakers/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jondot/sneakers/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jondot/sneakers/teams","hooks_url":"https://api.github.com/repos/jondot/sneakers/hooks","issue_events_url":"https://api.github.com/repos/jondot/sneakers/issues/events{/number}","events_url":"https://api.github.com/repos/jondot/sneakers/events","assignees_url":"https://api.github.com/repos/jondot/sneakers/assignees{/user}","branches_url":"https://api.github.com/repos/jondot/sneakers/branches{/branch}","tags_url":"https://api.github.com/repos/jondot/sneakers/tags","blobs_url":"https://api.github.com/repos/jondot/sneakers/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jondot/sneakers/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jondot/sneakers/git/refs{/sha}","trees_url":"https://api.github.com/repos/jondot/sneakers/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jondot/sneakers/statuses/{sha}","languages_url":"https://api.github.com/repos/jondot/sneakers/languages","stargazers_url":"https://api.github.com/repos/jondot/sneakers/stargazers","contributors_url":"https://api.github.com/repos/jondot/sneakers/contributors","subscribers_url":"https://api.github.com/repos/jondot/sneakers/subscribers","subscription_url":"https://api.github.com/repos/jondot/sneakers/subscription","commits_url":"https://api.github.com/repos/jondot/sneakers/commits{/sha}","git_commits_url":"https://api.github.com/repos/jondot/sneakers/git/commits{/sha}","comments_url":"https://api.github.com/repos/jondot/sneakers/comments{/number}","issue_comment_url":"https://api.github.com/repos/jondot/sneakers/issues/comments{/number}","contents_url":"https://api.github.com/repos/jondot/sneakers/contents/{+path}","compare_url":"https://api.github.com/repos/jondot/sneakers/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jondot/sneakers/merges","archive_url":"https://api.github.com/repos/jondot/sneakers/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jondot/sneakers/downloads","issues_url":"https://api.github.com/repos/jondot/sneakers/issues{/number}","pulls_url":"https://api.github.com/repos/jondot/sneakers/pulls{/number}","milestones_url":"https://api.github.com/repos/jondot/sneakers/milestones{/number}","notifications_url":"https://api.github.com/repos/jondot/sneakers/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jondot/sneakers/labels{/name}","releases_url":"https://api.github.com/repos/jondot/sneakers/releases{/id}","created_at":"2013-10-09T12:41:36Z","updated_at":"2016-01-05T10:59:59Z","pushed_at":"2016-01-06T19:23:50Z","git_url":"git://github.com/jondot/sneakers.git","ssh_url":"git@github.com:jondot/sneakers.git","clone_url":"https://github.com/jondot/sneakers.git","svn_url":"https://github.com/jondot/sneakers","homepage":"http://sneakers.io","size":1402,"stargazers_count":1160,"watchers_count":1160,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":146,"mirror_url":null,"open_issues_count":46,"forks":146,"open_issues":46,"watchers":1160,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/jondot/sneakers/pulls/194"},"html":{"href":"https://github.com/jondot/sneakers/pull/194"},"issue":{"href":"https://api.github.com/repos/jondot/sneakers/issues/194"},"comments":{"href":"https://api.github.com/repos/jondot/sneakers/issues/194/comments"},"review_comments":{"href":"https://api.github.com/repos/jondot/sneakers/pulls/194/comments"},"review_comment":{"href":"https://api.github.com/repos/jondot/sneakers/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/jondot/sneakers/pulls/194/commits"},"statuses":{"href":"https://api.github.com/repos/jondot/sneakers/statuses/40a8caf692668c8070ddc96764605918d99763a6"}}}}