Skip to content

Commit 8be1505

Browse files
bdoyle0182Brendan Doylerabbah
authored
add system config options for success / failure levels to write blocking / non-blocking activations to db (#5169)
* add config option to disable successful non-blocking activation writes to db * fix check * feedback * fix tests * rebase * feedback * update config precedence * Apply suggestions from code review Co-authored-by: rodric rabbah <[email protected]> Co-authored-by: Brendan Doyle <[email protected]> Co-authored-by: rodric rabbah <[email protected]>
1 parent e172168 commit 8be1505

File tree

16 files changed

+220
-55
lines changed

16 files changed

+220
-55
lines changed

common/scala/src/main/resources/application.conf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,10 +438,19 @@ whisk {
438438
# uniqueName + displayName 253 (max pod name length in Kube)
439439
serdes-overhead = 6068 // 3034 bytes of metadata * 2 for extra headroom
440440

441+
# DEPRECATED, use store-blocking-result-level
441442
# Disables database store for blocking + successful activations
442443
# invocations made with `X-OW-EXTRA-LOGGING: on` header, will force the activation to be stored
443444
disable-store-result = false
444445

446+
# Result level to store in db for blocking activations (STORE_ALWAYS, STORE_FAILURES, STORE_FAILURES_NOT_APPLICATION_ERRORS)
447+
# invocations made with `X-OW-EXTRA-LOGGING: on` header, will force the activation to be stored
448+
store-blocking-result-level = "STORE_ALWAYS"
449+
450+
# Result level to store in db for non-blocking activations (STORE_ALWAYS, STORE_FAILURES, STORE_FAILURES_NOT_APPLICATION_ERRORS)
451+
# invocations made with `X-OW-EXTRA-LOGGING: on` header, will force the activation to be stored
452+
store-non-blocking-result-level = "STORE_ALWAYS"
453+
445454
# Enable metadata logging of activations not stored in the database
446455
unstored-logs-enabled = false
447456
}

common/scala/src/main/scala/org/apache/openwhisk/core/WhiskConfig.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,10 @@ object ConfigKeys {
286286
val sharedPackageExecuteOnly = s"whisk.shared-packages-execute-only"
287287
val swaggerUi = "whisk.swagger-ui"
288288

289+
/* DEPRECATED: disableStoreResult is deprecated for storeBlockingResultLevel */
289290
val disableStoreResult = s"$activation.disable-store-result"
291+
val storeBlockingResultLevel = s"$activation.store-blocking-result-level"
292+
val storeNonBlockingResultLevel = s"$activation.store-non-blocking-result-level"
290293
val unstoredLogsEnabled = s"$activation.unstored-logs-enabled"
291294

292295
val apacheClientConfig = "whisk.apache-client"

common/scala/src/main/scala/org/apache/openwhisk/core/database/ActivationStore.scala

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
package org.apache.openwhisk.core.database
1919

2020
import java.time.Instant
21-
2221
import akka.actor.ActorSystem
2322
import akka.http.scaladsl.model.HttpRequest
2423
import spray.json.JsObject
@@ -33,32 +32,52 @@ import scala.concurrent.Future
3332
case class UserContext(user: Identity, request: HttpRequest = HttpRequest())
3433

3534
trait ActivationStore {
35+
val logging: Logging
3636

37+
/* DEPRECATED: disableStoreResult config is now deprecated replaced with blocking activation store level (storeBlockingResultLevel) */
3738
protected val disableStoreResultConfig = loadConfigOrThrow[Boolean](ConfigKeys.disableStoreResult)
39+
protected val storeBlockingResultLevelConfig = {
40+
try {
41+
ActivationStoreLevel.valueOf(loadConfigOrThrow[String](ConfigKeys.storeBlockingResultLevel))
42+
} catch {
43+
case _: Exception =>
44+
val disableStoreResultConfig = loadConfigOrThrow[Boolean](ConfigKeys.disableStoreResult)
45+
logging.warn(
46+
this,
47+
s"The config ${ConfigKeys.disableStoreResult} being used is deprecated. Please use the replacement config ${ConfigKeys.storeBlockingResultLevel}")
48+
if (disableStoreResultConfig) ActivationStoreLevel.STORE_FAILURES else ActivationStoreLevel.STORE_ALWAYS
49+
}
50+
}
51+
protected val storeNonBlockingResultLevelConfig =
52+
ActivationStoreLevel.valueOf(loadConfigOrThrow[String](ConfigKeys.storeNonBlockingResultLevel))
3853
protected val unstoredLogsEnabledConfig = loadConfigOrThrow[Boolean](ConfigKeys.unstoredLogsEnabled)
3954

4055
/**
4156
* Checks if an activation should be stored in database and stores it.
4257
*
4358
* @param activation activation to store
4459
* @param isBlockingActivation is activation blocking
60+
* @param blockingStoreLevel do not store activation if successful and blocking
61+
* @param nonBlockingStoreLevel do not store activation if successful and non-blocking
4562
* @param context user and request context
4663
* @param transid transaction ID for request
4764
* @param notifier cache change notifier
4865
* @return Future containing DocInfo related to stored activation
4966
*/
5067
def storeAfterCheck(activation: WhiskActivation,
5168
isBlockingActivation: Boolean,
52-
disableStore: Option[Boolean],
69+
blockingStoreLevel: Option[ActivationStoreLevel.Value],
70+
nonBlockingStoreLevel: Option[ActivationStoreLevel.Value],
5371
context: UserContext)(implicit transid: TransactionId,
5472
notifier: Option[CacheChangeNotification],
5573
logging: Logging): Future[DocInfo] = {
5674
if (context.user.limits.storeActivations.getOrElse(true) &&
5775
shouldStoreActivation(
58-
activation.response.isSuccess,
76+
activation.response,
5977
isBlockingActivation,
6078
transid.meta.extraLogging,
61-
disableStore.getOrElse(disableStoreResultConfig))) {
79+
blockingStoreLevel.getOrElse(storeBlockingResultLevelConfig),
80+
nonBlockingStoreLevel.getOrElse(storeNonBlockingResultLevelConfig))) {
6281

6382
store(activation, context)
6483
} else {
@@ -183,17 +202,29 @@ trait ActivationStore {
183202
* - an activation in debug mode
184203
* - activation stores is not disabled via a configuration parameter
185204
*
186-
* @param isSuccess is successful activation
205+
* @param activationResponse to check
187206
* @param isBlocking is blocking activation
188207
* @param debugMode is logging header set to "on" for the invocation
189-
* @param disableStore is disable store configured
208+
* @param blockingStoreLevel level of activation status to store for blocking invocations
209+
* @param nonBlockingStoreLevel level of activation status to store for blocking invocations
190210
* @return Should the activation be stored to the database
191211
*/
192-
private def shouldStoreActivation(isSuccess: Boolean,
212+
private def shouldStoreActivation(activationResponse: ActivationResponse,
193213
isBlocking: Boolean,
194214
debugMode: Boolean,
195-
disableStore: Boolean): Boolean = {
196-
!isSuccess || !isBlocking || debugMode || !disableStore
215+
blockingStoreLevel: ActivationStoreLevel.Value,
216+
nonBlockingStoreLevel: ActivationStoreLevel.Value): Boolean = {
217+
def shouldStoreOnLevel(storageLevel: ActivationStoreLevel.Value): Boolean = {
218+
storageLevel match {
219+
case ActivationStoreLevel.STORE_ALWAYS => true
220+
case ActivationStoreLevel.STORE_FAILURES => !activationResponse.isSuccess
221+
case ActivationStoreLevel.STORE_FAILURES_NOT_APPLICATION_ERRORS =>
222+
activationResponse.isContainerError || activationResponse.isWhiskError
223+
}
224+
}
225+
226+
debugMode || (isBlocking && shouldStoreOnLevel(blockingStoreLevel)) || (!isBlocking && shouldStoreOnLevel(
227+
nonBlockingStoreLevel))
197228
}
198229
}
199230

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.openwhisk.core.database
19+
20+
object ActivationStoreLevel extends Enumeration {
21+
type ActivationStoreLevel = Value
22+
val STORE_ALWAYS, STORE_FAILURES, STORE_FAILURES_NOT_APPLICATION_ERRORS = Value
23+
24+
def valueOf(value: String): Value = {
25+
values
26+
.find(_.toString == value.toUpperCase())
27+
.getOrElse(throw new IllegalArgumentException(s"Invalid log level: $value"))
28+
}
29+
}

common/scala/src/main/scala/org/apache/openwhisk/core/database/ArtifactActivationStore.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import org.apache.openwhisk.core.entity._
2727
import scala.concurrent.Future
2828
import scala.util.{Failure, Success}
2929

30-
class ArtifactActivationStore(actorSystem: ActorSystem, logging: Logging) extends ActivationStore {
30+
class ArtifactActivationStore(actorSystem: ActorSystem, override val logging: Logging) extends ActivationStore {
3131

3232
implicit val executionContext = actorSystem.dispatcher
3333

common/scala/src/main/scala/org/apache/openwhisk/core/database/elasticsearch/ElasticSearchActivationStore.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ case class ElasticSearchActivationStoreConfig(protocol: String,
5757
class ElasticSearchActivationStore(
5858
httpFlow: Option[Flow[(HttpRequest, Promise[HttpResponse]), (Try[HttpResponse], Promise[HttpResponse]), Any]] = None,
5959
elasticSearchConfig: ElasticSearchActivationStoreConfig,
60-
useBatching: Boolean = false)(implicit actorSystem: ActorSystem, logging: Logging)
60+
useBatching: Boolean = false)(implicit actorSystem: ActorSystem, override val logging: Logging)
6161
extends ActivationStore {
6262

6363
import com.sksamuel.elastic4s.http.ElasticDsl._

common/scala/src/main/scala/org/apache/openwhisk/core/database/memory/NoopActivationStore.scala

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,16 @@
1818
package org.apache.openwhisk.core.database.memory
1919

2020
import java.time.Instant
21-
2221
import akka.actor.ActorSystem
23-
import org.apache.openwhisk.common.{Logging, TransactionId, WhiskInstants}
24-
import org.apache.openwhisk.core.database.{
25-
ActivationStore,
26-
ActivationStoreProvider,
27-
CacheChangeNotification,
28-
UserContext
29-
}
22+
import org.apache.openwhisk.common.{Logging, PrintStreamLogging, TransactionId, WhiskInstants}
23+
import org.apache.openwhisk.core.database.{ActivationStore, ActivationStoreProvider, CacheChangeNotification, UserContext}
3024
import org.apache.openwhisk.core.entity.{ActivationId, DocInfo, EntityName, EntityPath, Subject, WhiskActivation}
3125
import spray.json.{JsNumber, JsObject}
3226

3327
import scala.concurrent.Future
3428

3529
object NoopActivationStore extends ActivationStore with WhiskInstants {
30+
override val logging = new PrintStreamLogging()
3631
private val emptyInfo = DocInfo("foo")
3732
private val emptyCount = JsObject("activations" -> JsNumber(0))
3833
private val dummyActivation = WhiskActivation(

core/controller/src/main/scala/org/apache/openwhisk/core/controller/Triggers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ trait WhiskTriggersApi extends WhiskCollectionAPI {
161161
triggerActivation
162162
}
163163
.map { activation =>
164-
activationStore.storeAfterCheck(activation, false, None, context)
164+
activationStore.storeAfterCheck(activation, false, None, None, context)
165165
}
166166

167167
respondWithActivationIdHeader(triggerActivationId) {

core/controller/src/main/scala/org/apache/openwhisk/core/controller/actions/PrimitiveActions.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,10 @@ protected[actions] trait PrimitiveActions {
600600
}
601601
}
602602

603-
activationStore.storeAfterCheck(activation, blockingComposition, None, context)(transid, notifier = None, logging)
603+
activationStore.storeAfterCheck(activation, blockingComposition, None, None, context)(
604+
transid,
605+
notifier = None,
606+
logging)
604607

605608
activation
606609
}

core/controller/src/main/scala/org/apache/openwhisk/core/controller/actions/SequenceActions.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ protected[actions] trait SequenceActions {
181181
}
182182
}
183183

184-
activationStore.storeAfterCheck(seqActivation, blockingSequence, None, context)(
184+
activationStore.storeAfterCheck(seqActivation, blockingSequence, None, None, context)(
185185
transid,
186186
notifier = None,
187187
logging)

0 commit comments

Comments
 (0)