This is an automated email from the ASF dual-hosted git repository.
chetanm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwhisk.git
The following commit(s) were added to refs/heads/master by this push:
new 5de865c Retry NoHttpResponseException for standalone mode in
ApacheContainerClient (#4644)
5de865c is described below
commit 5de865c271ab6e82deacdf4d8dcd2f5025c02d97
Author: Chetan Mehrotra <[email protected]>
AuthorDate: Wed Sep 25 09:56:07 2019 +0530
Retry NoHttpResponseException for standalone mode in ApacheContainerClient
(#4644)
Adding a new setting to enable retry of NoHttpResponseException based on
configuration.
This setting is enabled in standalone mode to workaround some Docker
network issue where first call of `/init` fails due to this exception. Same
init passes upon retry
---
common/scala/src/main/resources/application.conf | 8 ++++++++
.../org/apache/openwhisk/core/WhiskConfig.scala | 2 ++
.../ApacheBlockingContainerClient.scala | 12 +++++++++++-
core/standalone/src/main/resources/standalone.conf | 3 +++
.../openwhisk/standalone/StandaloneServerTests.scala | 20 --------------------
5 files changed, 24 insertions(+), 21 deletions(-)
diff --git a/common/scala/src/main/resources/application.conf
b/common/scala/src/main/resources/application.conf
index f89a646..cfa7845 100644
--- a/common/scala/src/main/resources/application.conf
+++ b/common/scala/src/main/resources/application.conf
@@ -449,6 +449,14 @@ whisk {
# for details
require-api-key-annotation = true
}
+
+ apache-client {
+ # By default Apache HTTP Client would not retry
NoHttpResponseException cases
+ # For some setups like Standalone mode this setting may need to be
enabled
+ # to work around some Docker network issue
+ # In general this setting should be left to its default disabled state
+ retry-no-http-response-exception = false
+ }
}
#placeholder for test overrides so that tests can override defaults in
application.conf (todo: move all defaults to reference.conf)
test {
diff --git
a/common/scala/src/main/scala/org/apache/openwhisk/core/WhiskConfig.scala
b/common/scala/src/main/scala/org/apache/openwhisk/core/WhiskConfig.scala
index 3b8e13f..b6fa765 100644
--- a/common/scala/src/main/scala/org/apache/openwhisk/core/WhiskConfig.scala
+++ b/common/scala/src/main/scala/org/apache/openwhisk/core/WhiskConfig.scala
@@ -263,4 +263,6 @@ object ConfigKeys {
val whiskConfig = "whisk.config"
val swaggerUi = "whisk.swagger-ui"
+
+ val apacheClientConfig = "whisk.apache-client"
}
diff --git
a/common/scala/src/main/scala/org/apache/openwhisk/core/containerpool/ApacheBlockingContainerClient.scala
b/common/scala/src/main/scala/org/apache/openwhisk/core/containerpool/ApacheBlockingContainerClient.scala
index f56d1eb..2cef635 100644
---
a/common/scala/src/main/scala/org/apache/openwhisk/core/containerpool/ApacheBlockingContainerClient.scala
+++
b/common/scala/src/main/scala/org/apache/openwhisk/core/containerpool/ApacheBlockingContainerClient.scala
@@ -22,7 +22,7 @@ import java.nio.charset.StandardCharsets
import java.time.Instant
import org.apache.commons.io.IOUtils
-import org.apache.http.HttpHeaders
+import org.apache.http.{HttpHeaders, NoHttpResponseException}
import org.apache.http.client.config.RequestConfig
import org.apache.http.client.methods.{HttpPost, HttpRequestBase}
import org.apache.http.client.utils.{HttpClientUtils, URIBuilder}
@@ -34,9 +34,11 @@ import
org.apache.http.impl.conn.PoolingHttpClientConnectionManager
import org.apache.http.util.EntityUtils
import spray.json._
import org.apache.openwhisk.common.{Logging, TransactionId}
+import org.apache.openwhisk.core.ConfigKeys
import org.apache.openwhisk.core.entity.ActivationResponse._
import org.apache.openwhisk.core.entity.ByteSize
import org.apache.openwhisk.core.entity.size.SizeLong
+import pureconfig.loadConfigOrThrow
import scala.annotation.tailrec
import scala.concurrent._
@@ -149,6 +151,11 @@ protected class ApacheBlockingContainerClient(hostname:
String,
//
// NoRouteToHostException: route to target host is not known (yet).
case t: NoRouteToHostException => Failure(RetryableConnectionError(t))
+
+ //In general with NoHttpResponseException it cannot be said if server
has processed the request or not
+ //For some cases like in standalone mode setup it should be fine to retry
+ case t: NoHttpResponseException if
ApacheBlockingContainerClient.clientConfig.retryNoHttpResponseException =>
+ Failure(RetryableConnectionError(t))
} match {
case Success(response) => response
case Failure(t: RetryableConnectionError) if retry =>
@@ -201,7 +208,10 @@ protected class ApacheBlockingContainerClient(hostname:
String,
.build
}
+case class ApacheClientConfig(retryNoHttpResponseException: Boolean)
+
object ApacheBlockingContainerClient {
+ val clientConfig: ApacheClientConfig =
loadConfigOrThrow[ApacheClientConfig](ConfigKeys.apacheClientConfig)
/** A helper method to post one single request to a connection. Used for
container tests. */
def post(host: String, port: Int, endPoint: String, content: JsValue)(
diff --git a/core/standalone/src/main/resources/standalone.conf
b/core/standalone/src/main/resources/standalone.conf
index 2887356..4d3463b 100644
--- a/core/standalone/src/main/resources/standalone.conf
+++ b/core/standalone/src/main/resources/standalone.conf
@@ -115,4 +115,7 @@ whisk {
]
}
}
+ apache-client {
+ retry-no-http-response-exception = true
+ }
}
diff --git
a/tests/src/test/scala/org/apache/openwhisk/standalone/StandaloneServerTests.scala
b/tests/src/test/scala/org/apache/openwhisk/standalone/StandaloneServerTests.scala
index 5699ec1..725033c 100644
---
a/tests/src/test/scala/org/apache/openwhisk/standalone/StandaloneServerTests.scala
+++
b/tests/src/test/scala/org/apache/openwhisk/standalone/StandaloneServerTests.scala
@@ -18,31 +18,11 @@
package org.apache.openwhisk.standalone
import common.WskProps
-import org.apache.commons.lang3.SystemUtils
import org.junit.runner.RunWith
-import org.scalatest.Pending
import org.scalatest.junit.JUnitRunner
import system.basic.WskRestBasicTests
@RunWith(classOf[JUnitRunner])
class StandaloneServerTests extends WskRestBasicTests with
StandaloneServerFixture {
override implicit val wskprops = WskProps().copy(apihost = serverUrl)
-
- //Following tests always fail on Mac but pass when standalone server is
running on Linux
- //It looks related to how networking works on Mac for Docker container
- //For now ignoring there failure
- private val ignoredTestsOnMac = Set(
- "Wsk Action REST should create, and invoke an action that utilizes a
docker container",
- "Wsk Action REST should create, and invoke an action that utilizes
dockerskeleton with native zip",
- "Wsk Action REST should create and invoke a blocking action resulting in
an application error response",
- "Wsk Action REST should create an action, and invoke an action that
returns an empty JSON object")
-
- override def withFixture(test: NoArgTest) = {
- val outcome = super.withFixture(test)
- val result = if (outcome.isFailed && SystemUtils.IS_OS_MAC &&
ignoredTestsOnMac.contains(test.name)) {
- println(s"Ignoring known failed test for Mac [${test.name}]")
- Pending
- } else outcome
- result
- }
}