You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@openwhisk.apache.org by GitBox <gi...@apache.org> on 2018/08/16 18:27:13 UTC

[GitHub] csantanapr closed pull request #3969: use KeepAlive(false) (SocketOption) instead of Connection:close (HTTP header)

csantanapr closed pull request #3969: use KeepAlive(false) (SocketOption) instead of Connection:close (HTTP header)
URL: https://github.com/apache/incubator-openwhisk/pull/3969
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/common/scala/src/main/scala/whisk/core/containerpool/AkkaContainerClient.scala b/common/scala/src/main/scala/whisk/core/containerpool/AkkaContainerClient.scala
index a133989758..1b53931662 100644
--- a/common/scala/src/main/scala/whisk/core/containerpool/AkkaContainerClient.scala
+++ b/common/scala/src/main/scala/whisk/core/containerpool/AkkaContainerClient.scala
@@ -27,7 +27,6 @@ import akka.http.scaladsl.model.MediaTypes
 import akka.http.scaladsl.model.MessageEntity
 import akka.http.scaladsl.model.StatusCodes
 import akka.http.scaladsl.model.headers.Accept
-import akka.http.scaladsl.model.headers.Connection
 import akka.http.scaladsl.unmarshalling.Unmarshal
 import akka.stream.StreamTcpException
 import akka.stream.scaladsl.Sink
@@ -56,6 +55,7 @@ import whisk.http.PoolingRestClient
  * It allows to POST a JSON object and receive JSON object back; that is the
  * content type and the accept headers are both 'application/json.
  * This implementation uses the akka http host-level client API.
+ * NOTE: Keepalive is disabled to prevent issues with paused containers
  *
  * @param hostname the host name
  * @param port the port
@@ -71,7 +71,7 @@ protected class AkkaContainerClient(
   maxResponse: ByteSize,
   queueSize: Int,
   retryInterval: FiniteDuration = 100.milliseconds)(implicit logging: Logging, as: ActorSystem)
-    extends PoolingRestClient("http", hostname, port, queueSize, timeout = Some(timeout))
+    extends PoolingRestClient("http", hostname, port, queueSize, timeout = Some(timeout), keepAlive = Some(false))
     with ContainerClient {
 
   def close() = Await.result(shutdown(), 30.seconds)
@@ -93,12 +93,8 @@ protected class AkkaContainerClient(
 
     //create the request
     val req = Marshal(body).to[MessageEntity].map { b =>
-      //DO NOT reuse the connection
-      //For details on Connection: Close handling, see:
-      // - https://doc.akka.io/docs/akka-http/current/common/http-model.html#http-headers
-      // - http://github.com/akka/akka-http/tree/v10.1.3/akka-http-core/src/test/scala/akka/http/impl/engine/rendering/ResponseRendererSpec.scala#L470-L571
       HttpRequest(HttpMethods.POST, endpoint, entity = b)
-        .withHeaders(Connection("close"), Accept(MediaTypes.`application/json`))
+        .withHeaders(Accept(MediaTypes.`application/json`))
     }
 
     retryingRequest(req, timeout, retry)
diff --git a/common/scala/src/main/scala/whisk/http/PoolingRestClient.scala b/common/scala/src/main/scala/whisk/http/PoolingRestClient.scala
index 909fffb629..1edade155d 100644
--- a/common/scala/src/main/scala/whisk/http/PoolingRestClient.scala
+++ b/common/scala/src/main/scala/whisk/http/PoolingRestClient.scala
@@ -24,6 +24,7 @@ import akka.http.scaladsl.marshalling._
 import akka.http.scaladsl.model._
 import akka.http.scaladsl.settings.ConnectionPoolSettings
 import akka.http.scaladsl.unmarshalling._
+import akka.io.Tcp.SO
 import akka.stream.{ActorMaterializer, OverflowStrategy, QueueOfferResult}
 import akka.stream.scaladsl.{Flow, _}
 import spray.json._
@@ -45,16 +46,19 @@ class PoolingRestClient(
   port: Int,
   queueSize: Int,
   httpFlow: Option[Flow[(HttpRequest, Promise[HttpResponse]), (Try[HttpResponse], Promise[HttpResponse]), Any]] = None,
-  timeout: Option[FiniteDuration] = None)(implicit system: ActorSystem) {
+  timeout: Option[FiniteDuration] = None,
+  keepAlive: Option[Boolean] = None)(implicit system: ActorSystem) {
   require(protocol == "http" || protocol == "https", "Protocol must be one of { http, https }.")
 
   protected implicit val context: ExecutionContext = system.dispatcher
   protected implicit val materializer: ActorMaterializer = ActorMaterializer()
 
-  //if specified, override the ClientConnection idle-timeout value
+  //if specified, override the ClientConnection idle-timeout and keepalive socket option value
   private val timeoutSettings = {
-    val ps = ConnectionPoolSettings(system.settings.config)
-    timeout.map(t => ps.withUpdatedConnectionSettings(_.withIdleTimeout(t))).getOrElse(ps)
+    ConnectionPoolSettings(system.settings.config).withUpdatedConnectionSettings { s =>
+      val t = timeout.map(t => s.withIdleTimeout(t)).getOrElse(s)
+      keepAlive.map(k => t.withSocketOptions(SO.KeepAlive(k) :: Nil)).getOrElse(t)
+    }
   }
 
   // Creates or retrieves a connection pool for the host.


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services