{"action":"created","comment":{"url":"https://api.github.com/repos/akka/akka/pulls/comments/28769971","id":28769971,"diff_hunk":"@@ -0,0 +1,139 @@\n+/**\n+ * Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com>\n+ */\n+\n+package akka.http.engine.client\n+\n+import scala.annotation.tailrec\n+import scala.concurrent.{ Future, Promise }\n+import scala.concurrent.duration.{ Duration, FiniteDuration }\n+import scala.util.{ Failure, Try }\n+import akka.actor.{ ActorLogging, Cancellable }\n+import akka.stream.FlowMaterializer\n+import akka.stream.actor.{ ActorPublisher, ActorSubscriber, ZeroRequestStrategy }\n+import akka.stream.actor.ActorPublisherMessage._\n+import akka.stream.actor.ActorSubscriberMessage._\n+import akka.stream.impl.ResizableMultiReaderRingBuffer\n+import akka.stream.scaladsl.{ Sink, Source, Flow }\n+import akka.http.model._\n+\n+private object HostConnectionPoolGateway {\n+  import ConnectionPool.{ PoolRequest, BeginShutdown }\n+\n+  case class RequestContext(request: HttpRequest, responsePromise: Promise[HttpResponse], retriesLeft: Int) {\n+    require(retriesLeft >= 0)\n+  }\n+  case class ResponseContext(rc: RequestContext, response: Try[HttpResponse])\n+\n+  private case object ShutdownNow\n+\n+  class PoolGateway(poolFlow: Flow[RequestContext, ResponseContext, Any],\n+                    hcps: HostConnectionPoolSetup,\n+                    whenShuttingDown: Promise[Future[Unit]])(implicit fm: FlowMaterializer)\n+    extends ActorSubscriber with ActorPublisher[RequestContext] with ActorLogging\n+    with ResizableMultiReaderRingBuffer.Cursors with ResizableMultiReaderRingBuffer.Cursor {\n+    import context.dispatcher\n+\n+    val cursors = this :: Nil // ResizableMultiReaderRingBuffer.Cursors\n+    var cursor: Int = _ // ResizableMultiReaderRingBuffer.Cursor\n+    private[this] val inputBuffer = {\n+      val maxOpenRequests = hcps.setup.settings.maxOpenRequests\n+      new ResizableMultiReaderRingBuffer[PoolRequest](maxOpenRequests, maxOpenRequests, this)\n+    }\n+    private[this] var activeIdleTimeout: Option[Cancellable] = None\n+    private[this] val effectiveDefaultHeaders =\n+      if (!hcps.setup.defaultHeaders.exists(_.isInstanceOf[headers.Host])) {\n+        import Uri._\n+        val normalizedPort = normalizePort(hcps.port, httpScheme(securedConnection = hcps.setup.encrypted))\n+        headers.Host(hcps.host, normalizedPort) +: hcps.setup.defaultHeaders\n+      } else hcps.setup.defaultHeaders\n+\n+    log.debug(\"(Re-)starting host connection pool to {}:{}\", hcps.host, hcps.port)\n+\n+    // start the pool flow with this actor acting as source as well as sink\n+    Source(ActorPublisher(self)).via(poolFlow).runWith(Sink(ActorSubscriber[ResponseContext](self)))\n+\n+    activateIdleTimeoutIfNecessary()\n+\n+    def requestStrategy = ZeroRequestStrategy\n+\n+    def receive: Receive = {\n+\n+      /////////////// FROM POOL DOWNSTREAM //////////////\n+\n+      case Request(_) ⇒ dispatchRequests() // the pool is ready to take on more requests\n+\n+      case Cancel ⇒\n+        // somehow the pool shut down, however, we don't do anything here because we'll also see an\n+        // OnComplete or OnError which we use as the sole trigger for cleaning up\n+        ()","path":"akka-http-core/src/main/scala/akka/http/engine/client/HostConnectionPoolGateway.scala","position":69,"original_position":69,"commit_id":"370d6d49114182742eadfc0ca1afc0cfbf3a96d4","original_commit_id":"370d6d49114182742eadfc0ca1afc0cfbf3a96d4","user":{"login":"rkuhn","id":470469,"avatar_url":"https://avatars.githubusercontent.com/u/470469?v=3","gravatar_id":"","url":"https://api.github.com/users/rkuhn","html_url":"https://github.com/rkuhn","followers_url":"https://api.github.com/users/rkuhn/followers","following_url":"https://api.github.com/users/rkuhn/following{/other_user}","gists_url":"https://api.github.com/users/rkuhn/gists{/gist_id}","starred_url":"https://api.github.com/users/rkuhn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rkuhn/subscriptions","organizations_url":"https://api.github.com/users/rkuhn/orgs","repos_url":"https://api.github.com/users/rkuhn/repos","events_url":"https://api.github.com/users/rkuhn/events{/privacy}","received_events_url":"https://api.github.com/users/rkuhn/received_events","type":"User","site_admin":false},"body":"this line should be removed","created_at":"2015-04-21T11:40:10Z","updated_at":"2015-04-21T11:40:10Z","html_url":"https://github.com/akka/akka/pull/17222#discussion_r28769971","pull_request_url":"https://api.github.com/repos/akka/akka/pulls/17222","_links":{"self":{"href":"https://api.github.com/repos/akka/akka/pulls/comments/28769971"},"html":{"href":"https://github.com/akka/akka/pull/17222#discussion_r28769971"},"pull_request":{"href":"https://api.github.com/repos/akka/akka/pulls/17222"}}},"pull_request":{"url":"https://api.github.com/repos/akka/akka/pulls/17222","id":33608676,"html_url":"https://github.com/akka/akka/pull/17222","diff_url":"https://github.com/akka/akka/pull/17222.diff","patch_url":"https://github.com/akka/akka/pull/17222.patch","issue_url":"https://api.github.com/repos/akka/akka/issues/17222","number":17222,"state":"open","locked":false,"title":"Support for client-side HTTP connection pooling","user":{"login":"sirthias","id":135347,"avatar_url":"https://avatars.githubusercontent.com/u/135347?v=3","gravatar_id":"","url":"https://api.github.com/users/sirthias","html_url":"https://github.com/sirthias","followers_url":"https://api.github.com/users/sirthias/followers","following_url":"https://api.github.com/users/sirthias/following{/other_user}","gists_url":"https://api.github.com/users/sirthias/gists{/gist_id}","starred_url":"https://api.github.com/users/sirthias/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sirthias/subscriptions","organizations_url":"https://api.github.com/users/sirthias/orgs","repos_url":"https://api.github.com/users/sirthias/repos","events_url":"https://api.github.com/users/sirthias/events{/privacy}","received_events_url":"https://api.github.com/users/sirthias/received_events","type":"User","site_admin":false},"body":"Supersedes https://github.com/akka/akka/pull/17036 and closes these 4 tickets:\r\n\r\n- #15681\r\n- #15906\r\n- #16852\r\n- #17064\r\n\r\n/cc @jrudolph","created_at":"2015-04-18T20:57:07Z","updated_at":"2015-04-21T11:40:10Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ec4fdc6fd1b30e99e0de05bf2026ec5cf93bab32","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/akka/akka/pulls/17222/commits","review_comments_url":"https://api.github.com/repos/akka/akka/pulls/17222/comments","review_comment_url":"https://api.github.com/repos/akka/akka/pulls/comments{/number}","comments_url":"https://api.github.com/repos/akka/akka/issues/17222/comments","statuses_url":"https://api.github.com/repos/akka/akka/statuses/370d6d49114182742eadfc0ca1afc0cfbf3a96d4","head":{"label":"spray:wip-15681-mathias-final","ref":"wip-15681-mathias-final","sha":"370d6d49114182742eadfc0ca1afc0cfbf3a96d4","user":{"login":"spray","id":688516,"avatar_url":"https://avatars.githubusercontent.com/u/688516?v=3","gravatar_id":"","url":"https://api.github.com/users/spray","html_url":"https://github.com/spray","followers_url":"https://api.github.com/users/spray/followers","following_url":"https://api.github.com/users/spray/following{/other_user}","gists_url":"https://api.github.com/users/spray/gists{/gist_id}","starred_url":"https://api.github.com/users/spray/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/spray/subscriptions","organizations_url":"https://api.github.com/users/spray/orgs","repos_url":"https://api.github.com/users/spray/repos","events_url":"https://api.github.com/users/spray/events{/privacy}","received_events_url":"https://api.github.com/users/spray/received_events","type":"Organization","site_admin":false},"repo":{"id":3809985,"name":"akka","full_name":"spray/akka","owner":{"login":"spray","id":688516,"avatar_url":"https://avatars.githubusercontent.com/u/688516?v=3","gravatar_id":"","url":"https://api.github.com/users/spray","html_url":"https://github.com/spray","followers_url":"https://api.github.com/users/spray/followers","following_url":"https://api.github.com/users/spray/following{/other_user}","gists_url":"https://api.github.com/users/spray/gists{/gist_id}","starred_url":"https://api.github.com/users/spray/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/spray/subscriptions","organizations_url":"https://api.github.com/users/spray/orgs","repos_url":"https://api.github.com/users/spray/repos","events_url":"https://api.github.com/users/spray/events{/privacy}","received_events_url":"https://api.github.com/users/spray/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/spray/akka","description":"Akka Project","fork":true,"url":"https://api.github.com/repos/spray/akka","forks_url":"https://api.github.com/repos/spray/akka/forks","keys_url":"https://api.github.com/repos/spray/akka/keys{/key_id}","collaborators_url":"https://api.github.com/repos/spray/akka/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/spray/akka/teams","hooks_url":"https://api.github.com/repos/spray/akka/hooks","issue_events_url":"https://api.github.com/repos/spray/akka/issues/events{/number}","events_url":"https://api.github.com/repos/spray/akka/events","assignees_url":"https://api.github.com/repos/spray/akka/assignees{/user}","branches_url":"https://api.github.com/repos/spray/akka/branches{/branch}","tags_url":"https://api.github.com/repos/spray/akka/tags","blobs_url":"https://api.github.com/repos/spray/akka/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/spray/akka/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/spray/akka/git/refs{/sha}","trees_url":"https://api.github.com/repos/spray/akka/git/trees{/sha}","statuses_url":"https://api.github.com/repos/spray/akka/statuses/{sha}","languages_url":"https://api.github.com/repos/spray/akka/languages","stargazers_url":"https://api.github.com/repos/spray/akka/stargazers","contributors_url":"https://api.github.com/repos/spray/akka/contributors","subscribers_url":"https://api.github.com/repos/spray/akka/subscribers","subscription_url":"https://api.github.com/repos/spray/akka/subscription","commits_url":"https://api.github.com/repos/spray/akka/commits{/sha}","git_commits_url":"https://api.github.com/repos/spray/akka/git/commits{/sha}","comments_url":"https://api.github.com/repos/spray/akka/comments{/number}","issue_comment_url":"https://api.github.com/repos/spray/akka/issues/comments{/number}","contents_url":"https://api.github.com/repos/spray/akka/contents/{+path}","compare_url":"https://api.github.com/repos/spray/akka/compare/{base}...{head}","merges_url":"https://api.github.com/repos/spray/akka/merges","archive_url":"https://api.github.com/repos/spray/akka/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/spray/akka/downloads","issues_url":"https://api.github.com/repos/spray/akka/issues{/number}","pulls_url":"https://api.github.com/repos/spray/akka/pulls{/number}","milestones_url":"https://api.github.com/repos/spray/akka/milestones{/number}","notifications_url":"https://api.github.com/repos/spray/akka/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/spray/akka/labels{/name}","releases_url":"https://api.github.com/repos/spray/akka/releases{/id}","created_at":"2012-03-23T15:57:31Z","updated_at":"2014-10-15T18:53:07Z","pushed_at":"2015-04-21T08:02:44Z","git_url":"git://github.com/spray/akka.git","ssh_url":"git@github.com:spray/akka.git","clone_url":"https://github.com/spray/akka.git","svn_url":"https://github.com/spray/akka","homepage":"http://akka.io","size":157481,"stargazers_count":7,"watchers_count":7,"language":"Scala","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":0,"forks":1,"open_issues":0,"watchers":7,"default_branch":"master"}},"base":{"label":"akka:release-2.3-dev","ref":"release-2.3-dev","sha":"242e1b835de55eefad0b9164958ce55e23f218f1","user":{"login":"akka","id":1496237,"avatar_url":"https://avatars.githubusercontent.com/u/1496237?v=3","gravatar_id":"","url":"https://api.github.com/users/akka","html_url":"https://github.com/akka","followers_url":"https://api.github.com/users/akka/followers","following_url":"https://api.github.com/users/akka/following{/other_user}","gists_url":"https://api.github.com/users/akka/gists{/gist_id}","starred_url":"https://api.github.com/users/akka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akka/subscriptions","organizations_url":"https://api.github.com/users/akka/orgs","repos_url":"https://api.github.com/users/akka/repos","events_url":"https://api.github.com/users/akka/events{/privacy}","received_events_url":"https://api.github.com/users/akka/received_events","type":"Organization","site_admin":false},"repo":{"id":130013,"name":"akka","full_name":"akka/akka","owner":{"login":"akka","id":1496237,"avatar_url":"https://avatars.githubusercontent.com/u/1496237?v=3","gravatar_id":"","url":"https://api.github.com/users/akka","html_url":"https://github.com/akka","followers_url":"https://api.github.com/users/akka/followers","following_url":"https://api.github.com/users/akka/following{/other_user}","gists_url":"https://api.github.com/users/akka/gists{/gist_id}","starred_url":"https://api.github.com/users/akka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akka/subscriptions","organizations_url":"https://api.github.com/users/akka/orgs","repos_url":"https://api.github.com/users/akka/repos","events_url":"https://api.github.com/users/akka/events{/privacy}","received_events_url":"https://api.github.com/users/akka/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/akka/akka","description":"Akka Project","fork":false,"url":"https://api.github.com/repos/akka/akka","forks_url":"https://api.github.com/repos/akka/akka/forks","keys_url":"https://api.github.com/repos/akka/akka/keys{/key_id}","collaborators_url":"https://api.github.com/repos/akka/akka/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/akka/akka/teams","hooks_url":"https://api.github.com/repos/akka/akka/hooks","issue_events_url":"https://api.github.com/repos/akka/akka/issues/events{/number}","events_url":"https://api.github.com/repos/akka/akka/events","assignees_url":"https://api.github.com/repos/akka/akka/assignees{/user}","branches_url":"https://api.github.com/repos/akka/akka/branches{/branch}","tags_url":"https://api.github.com/repos/akka/akka/tags","blobs_url":"https://api.github.com/repos/akka/akka/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/akka/akka/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/akka/akka/git/refs{/sha}","trees_url":"https://api.github.com/repos/akka/akka/git/trees{/sha}","statuses_url":"https://api.github.com/repos/akka/akka/statuses/{sha}","languages_url":"https://api.github.com/repos/akka/akka/languages","stargazers_url":"https://api.github.com/repos/akka/akka/stargazers","contributors_url":"https://api.github.com/repos/akka/akka/contributors","subscribers_url":"https://api.github.com/repos/akka/akka/subscribers","subscription_url":"https://api.github.com/repos/akka/akka/subscription","commits_url":"https://api.github.com/repos/akka/akka/commits{/sha}","git_commits_url":"https://api.github.com/repos/akka/akka/git/commits{/sha}","comments_url":"https://api.github.com/repos/akka/akka/comments{/number}","issue_comment_url":"https://api.github.com/repos/akka/akka/issues/comments{/number}","contents_url":"https://api.github.com/repos/akka/akka/contents/{+path}","compare_url":"https://api.github.com/repos/akka/akka/compare/{base}...{head}","merges_url":"https://api.github.com/repos/akka/akka/merges","archive_url":"https://api.github.com/repos/akka/akka/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/akka/akka/downloads","issues_url":"https://api.github.com/repos/akka/akka/issues{/number}","pulls_url":"https://api.github.com/repos/akka/akka/pulls{/number}","milestones_url":"https://api.github.com/repos/akka/akka/milestones{/number}","notifications_url":"https://api.github.com/repos/akka/akka/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/akka/akka/labels{/name}","releases_url":"https://api.github.com/repos/akka/akka/releases{/id}","created_at":"2009-02-16T12:51:54Z","updated_at":"2015-04-21T09:30:12Z","pushed_at":"2015-04-21T10:36:31Z","git_url":"git://github.com/akka/akka.git","ssh_url":"git@github.com:akka/akka.git","clone_url":"https://github.com/akka/akka.git","svn_url":"https://github.com/akka/akka","homepage":"http://akka.io","size":247346,"stargazers_count":3839,"watchers_count":3839,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1097,"mirror_url":null,"open_issues_count":639,"forks":1097,"open_issues":639,"watchers":3839,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/akka/akka/pulls/17222"},"html":{"href":"https://github.com/akka/akka/pull/17222"},"issue":{"href":"https://api.github.com/repos/akka/akka/issues/17222"},"comments":{"href":"https://api.github.com/repos/akka/akka/issues/17222/comments"},"review_comments":{"href":"https://api.github.com/repos/akka/akka/pulls/17222/comments"},"review_comment":{"href":"https://api.github.com/repos/akka/akka/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/akka/akka/pulls/17222/commits"},"statuses":{"href":"https://api.github.com/repos/akka/akka/statuses/370d6d49114182742eadfc0ca1afc0cfbf3a96d4"}}}}