This is an automated email from the ASF dual-hosted git repository.
rabbah pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk.git
The following commit(s) were added to refs/heads/master by this push:
new 607e4e0 Complete blocking activations immediately on active ack when
db polling is disabled. (#4230)
607e4e0 is described below
commit 607e4e08299c1322399fdb2dffb8ecb8248b33c0
Author: jiangpch <[email protected]>
AuthorDate: Thu Feb 7 04:08:00 2019 +0800
Complete blocking activations immediately on active ack when db polling is
disabled. (#4230)
---
.../core/controller/actions/PrimitiveActions.scala | 5 +-
.../core/controller/test/ActionsApiTests.scala | 4 -
.../core/controller/test/PollingFromDbTests.scala | 91 ++++++++++++++++++++++
3 files changed, 94 insertions(+), 6 deletions(-)
diff --git
a/core/controller/src/main/scala/org/apache/openwhisk/core/controller/actions/PrimitiveActions.scala
b/core/controller/src/main/scala/org/apache/openwhisk/core/controller/actions/PrimitiveActions.scala
index 1363f76..8338256 100644
---
a/core/controller/src/main/scala/org/apache/openwhisk/core/controller/actions/PrimitiveActions.scala
+++
b/core/controller/src/main/scala/org/apache/openwhisk/core/controller/actions/PrimitiveActions.scala
@@ -599,7 +599,8 @@ protected[actions] trait PrimitiveActions {
case Right(activation) => result.trySuccess(Right(activation))
case _ if (controllerActivationConfig.pollingFromDb) =>
pollActivation(docid, context, result, i => 1.seconds + (2.seconds *
i), maxRetries = 4)
- case _ =>
+ case Left(activationId) =>
+ result.trySuccess(Left(activationId)) // complete the future
immediately if it's configured to not poll db for blocking activations
}
if (controllerActivationConfig.pollingFromDb) {
@@ -653,7 +654,7 @@ protected[actions] trait PrimitiveActions {
/** Max atomic action count allowed for sequences */
private lazy val actionSequenceLimit = whiskConfig.actionSequenceLimit.toInt
- private val controllerActivationConfig =
+ protected val controllerActivationConfig =
loadConfigOrThrow[ControllerActivationConfig](ConfigKeys.controllerActivation)
}
diff --git
a/tests/src/test/scala/org/apache/openwhisk/core/controller/test/ActionsApiTests.scala
b/tests/src/test/scala/org/apache/openwhisk/core/controller/test/ActionsApiTests.scala
index 761a09b..eea2409 100644
---
a/tests/src/test/scala/org/apache/openwhisk/core/controller/test/ActionsApiTests.scala
+++
b/tests/src/test/scala/org/apache/openwhisk/core/controller/test/ActionsApiTests.scala
@@ -36,12 +36,9 @@ import org.apache.openwhisk.core.entitlement.Collection
import org.apache.openwhisk.http.ErrorResponse
import org.apache.openwhisk.http.Messages
import org.apache.openwhisk.core.database.UserContext
-import org.apache.openwhisk.core.ConfigKeys
-import org.apache.openwhisk.core.controller.actions.ControllerActivationConfig
import akka.http.scaladsl.model.headers.RawHeader
import org.apache.commons.lang3.StringUtils
import org.apache.openwhisk.core.entity.Attachments.Inline
-import pureconfig.loadConfigOrThrow
/**
* Tests Actions API.
@@ -68,7 +65,6 @@ class ActionsApiTests extends ControllerTestCommon with
WhiskActionsApi {
def aname() = MakeName.next("action_tests")
val actionLimit = Exec.sizeLimit
val parametersLimit = Parameters.sizeLimit
- val controllerActivationConfig =
loadConfigOrThrow[ControllerActivationConfig](ConfigKeys.controllerActivation)
//// GET /actions
it should "return empty list when no actions exist" in {
diff --git
a/tests/src/test/scala/org/apache/openwhisk/core/controller/test/PollingFromDbTests.scala
b/tests/src/test/scala/org/apache/openwhisk/core/controller/test/PollingFromDbTests.scala
new file mode 100644
index 0000000..d0166f4
--- /dev/null
+++
b/tests/src/test/scala/org/apache/openwhisk/core/controller/test/PollingFromDbTests.scala
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.openwhisk.core.controller.test
+
+import java.time.Instant
+
+import scala.concurrent.duration.DurationInt
+import org.junit.runner.RunWith
+import org.scalatest.junit.JUnitRunner
+import akka.http.scaladsl.model.StatusCodes._
+import
akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport.sprayJsonUnmarshaller
+import akka.http.scaladsl.server.Route
+import org.apache.openwhisk.common.TransactionId
+import org.apache.openwhisk.core.WhiskConfig
+import org.apache.openwhisk.core.connector.ActivationMessage
+import spray.json._
+import spray.json.DefaultJsonProtocol._
+import org.apache.openwhisk.core.controller.WhiskActionsApi
+import org.apache.openwhisk.core.entity._
+import org.apache.openwhisk.core.controller.actions.ControllerActivationConfig
+
+import scala.concurrent.{ExecutionContext, Future}
+
+/**
+ * Tests PollingFromDb configuration.
+ *
+ * Unit tests of the controller service as a standalone component.
+ * These tests exercise a fresh instance of the service object in memory --
these
+ * tests do NOT communication with a whisk deployment.
+ *
+ *
+ * @Idioglossia
+ * "using Specification DSL to write unit tests, as in should, must, not, be"
+ * "using Specs2RouteTest DSL to chain HTTP requests for unit testing, as in
~>"
+ */
+@RunWith(classOf[JUnitRunner])
+class PollingFromDbTests extends ControllerTestCommon with WhiskActionsApi {
+
+ val creds = WhiskAuthHelpers.newIdentity()
+ val namespace = EntityPath(creds.subject.asString)
+ val collectionPath = s"/${EntityPath.DEFAULT}/${collection.path}"
+ def aname() = MakeName.next("action_tests")
+ override protected val controllerActivationConfig =
ControllerActivationConfig(false)
+
+ override val loadBalancer = new
AlwaysReturnLeftLoadBalancerService(whiskConfig)
+
+ it should "complete blocking activation request immediately when a Left is
returned and pollingFromDb is set to false" in {
+ implicit val tid = transid()
+ val timeLimit = TimeLimit(1.minute)
+ val action = WhiskAction(namespace, aname(), jsDefault("??"), limits =
ActionLimits(timeLimit))
+ val activationId = activationIdFactory.make()
+ val start = Instant.now
+ put(entityStore, action)
+ Post(s"$collectionPath/${action.name}?blocking=true") ~>
Route.seal(routes(creds)) ~> check {
+ status should be(Accepted)
+ val duration = Instant.now.toEpochMilli - start.toEpochMilli
+ duration should be < timeLimit.millis.toLong
+ val response = responseAs[JsObject]
+ response should be(JsObject("activationId" ->
JsString(activationId.asString)))
+ }
+ }
+}
+
+class AlwaysReturnLeftLoadBalancerService(config: WhiskConfig)(implicit ec:
ExecutionContext)
+ extends DegenerateLoadBalancerService(config) {
+
+ override def activeActivationsFor(namespace: UUID): Future[Int] =
Future.successful(0)
+ override def totalActiveActivations: Future[Int] = Future.successful(0)
+
+ override def publish(action: ExecutableWhiskActionMetaData, msg:
ActivationMessage)(
+ implicit transid: TransactionId): Future[Future[Either[ActivationId,
WhiskActivation]]] = {
+ Future.successful(Future.successful(Left(msg.activationId)))
+ }
+
+ override def invokerHealth() = Future.successful(IndexedSeq.empty)
+}