rabbah closed pull request #3148: Make memory limits as config variables
URL: https://github.com/apache/incubator-openwhisk/pull/3148
 
 
   

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/ansible/roles/controller/tasks/deploy.yml 
b/ansible/roles/controller/tasks/deploy.yml
index 5f9687ef7b..2400bf87bd 100644
--- a/ansible/roles/controller/tasks/deploy.yml
+++ b/ansible/roles/controller/tasks/deploy.yml
@@ -82,6 +82,10 @@
       "LIMITS_TRIGGERS_FIRES_PERMINUTE": "{{ limits.firesPerMinute }}"
       "LIMITS_ACTIONS_SEQUENCE_MAXLENGTH": "{{ limits.sequenceMaxLength }}"
 
+      "CONFIG_whisk_memory_min": "{{ limit_action_memory_min | default() }}"
+      "CONFIG_whisk_memory_max": "{{ limit_action_memory_max | default() }}"
+      "CONFIG_whisk_memory_std": "{{ limit_action_memory_std | default() }}"
+
       "RUNTIMES_MANIFEST": "{{ runtimesManifest | to_json }}"
       "CONTROLLER_LOCALBOOKKEEPING": "{{ controller.localBookkeeping }}"
       "AKKA_CLUSTER_SEED_NODES": "{{seed_nodes_list | join(' ') }}"
diff --git a/ansible/roles/invoker/tasks/deploy.yml 
b/ansible/roles/invoker/tasks/deploy.yml
index 3da0b30ef2..7199125669 100644
--- a/ansible/roles/invoker/tasks/deploy.yml
+++ b/ansible/roles/invoker/tasks/deploy.yml
@@ -155,6 +155,9 @@
         -e CONFIG_kamon_statsd_port='{{ metrics.kamon.port }}'
         -e CONFIG_whisk_spi_LogStoreProvider='{{ userLogs.spi }}'
         -e CONFIG_logback_log_level='{{ invoker.loglevel }}'
+        -e CONFIG_whisk_memory_min='{{ limit_action_memory_min | default() }}'
+        -e CONFIG_whisk_memory_max='{{ limit_action_memory_max | default() }}'
+        -e CONFIG_whisk_memory_std='{{ limit_action_memory_std | default() }}'
         -v /sys/fs/cgroup:/sys/fs/cgroup
         -v /run/runc:/run/runc
         -v {{ whisk_logs_dir }}/invoker{{ 
groups['invokers'].index(inventory_hostname) }}:/logs
diff --git a/common/scala/src/main/resources/application.conf 
b/common/scala/src/main/resources/application.conf
index 3ba04c845d..5556db6646 100644
--- a/common/scala/src/main/resources/application.conf
+++ b/common/scala/src/main/resources/application.conf
@@ -87,4 +87,11 @@ whisk {
         stride = 1
         stride = ${?CONTROLLER_INSTANCES}
     }
+
+    # action memory configuration
+    memory {
+        min = "128M"
+        max = "512M"
+        std = "256M"
+    }
 }
diff --git a/common/scala/src/main/scala/whisk/core/WhiskConfig.scala 
b/common/scala/src/main/scala/whisk/core/WhiskConfig.scala
index c9fc5031bd..0967c07b9f 100644
--- a/common/scala/src/main/scala/whisk/core/WhiskConfig.scala
+++ b/common/scala/src/main/scala/whisk/core/WhiskConfig.scala
@@ -243,6 +243,8 @@ object ConfigKeys {
   val kafka = "whisk.kafka"
   val kafkaTopics = s"$kafka.topics"
 
+  val memory = "whisk.memory"
+
   val db = "whisk.db"
 
   val docker = "whisk.docker"
diff --git a/common/scala/src/main/scala/whisk/core/entity/Limits.scala 
b/common/scala/src/main/scala/whisk/core/entity/Limits.scala
index 81a9902827..a2294e0d3d 100644
--- a/common/scala/src/main/scala/whisk/core/entity/Limits.scala
+++ b/common/scala/src/main/scala/whisk/core/entity/Limits.scala
@@ -37,7 +37,7 @@ protected[entity] abstract class Limits {
  * Limits on a specific action. Includes the following properties
  * {
  *   timeout: maximum duration in msecs an action is allowed to consume in 
[100 msecs, 5 minutes],
- *   memory: maximum memory in megabytes an action is allowed to consume in 
[128 MB, 512 MB],
+ *   memory: maximum memory in megabytes an action is allowed to consume 
within system limit, default [128 MB, 512 MB],
  *   logs: maximum logs line in megabytes an action is allowed to generate [10 
MB]
  * }
  *
diff --git a/common/scala/src/main/scala/whisk/core/entity/MemoryLimit.scala 
b/common/scala/src/main/scala/whisk/core/entity/MemoryLimit.scala
index a1c251740a..929bb166c3 100644
--- a/common/scala/src/main/scala/whisk/core/entity/MemoryLimit.scala
+++ b/common/scala/src/main/scala/whisk/core/entity/MemoryLimit.scala
@@ -27,10 +27,14 @@ import spray.json.JsValue
 import spray.json.RootJsonFormat
 import spray.json.deserializationError
 import whisk.core.entity.size.SizeInt
+import whisk.core.ConfigKeys
+import pureconfig._
+
+case class MemoryLimitConfig(min: String, max: String, std: String)
 
 /**
- * MemoyLimit encapsulates allowed memory for an action. The limit must be 
within a
- * permissible range (currently [128MB, 512MB]).
+ * MemoryLimit encapsulates allowed memory for an action. The limit must be 
within a
+ * permissible range (by default [128MB, 512MB]).
  *
  * It is a value type (hence == is .equals, immutable and cannot be assigned 
null).
  * The constructor is private so that argument requirements are checked and 
normalized
@@ -41,12 +45,14 @@ import whisk.core.entity.size.SizeInt
 protected[entity] class MemoryLimit private (val megabytes: Int) extends 
AnyVal {}
 
 protected[core] object MemoryLimit extends ArgNormalizer[MemoryLimit] {
-  protected[core] val MIN_MEMORY = 128 MB
-  protected[core] val MAX_MEMORY = 512 MB
-  protected[core] val STD_MEMORY = 256 MB
+  private val memoryConfig = 
loadConfigOrThrow[MemoryLimitConfig](ConfigKeys.memory)
+
+  protected[core] val minMemory = ByteSize.fromString(memoryConfig.min)
+  protected[core] val maxMemory = ByteSize.fromString(memoryConfig.max)
+  protected[core] val stdMemory = ByteSize.fromString(memoryConfig.std)
 
-  /** Gets TimeLimit with default duration */
-  protected[core] def apply(): MemoryLimit = MemoryLimit(STD_MEMORY)
+  /** Gets MemoryLimit with default value */
+  protected[core] def apply(): MemoryLimit = MemoryLimit(stdMemory)
 
   /**
    * Creates MemoryLimit for limit, iff limit is within permissible range.
@@ -57,8 +63,8 @@ protected[core] object MemoryLimit extends 
ArgNormalizer[MemoryLimit] {
    */
   @throws[IllegalArgumentException]
   protected[core] def apply(megabytes: ByteSize): MemoryLimit = {
-    require(megabytes >= MIN_MEMORY, s"memory $megabytes below allowed 
threshold of $MIN_MEMORY")
-    require(megabytes <= MAX_MEMORY, s"memory $megabytes exceeds allowed 
threshold of $MAX_MEMORY")
+    require(megabytes >= minMemory, s"memory $megabytes below allowed 
threshold of $minMemory")
+    require(megabytes <= maxMemory, s"memory $megabytes exceeds allowed 
threshold of $maxMemory")
     new MemoryLimit(megabytes.toMB.toInt);
   }
 
diff --git a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala 
b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
index 963eb4c67c..a2ed63420d 100644
--- a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
+++ b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
@@ -717,7 +717,7 @@ class WskBasicUsageTests extends TestHelpers with 
WskTestHelpers {
         // Limits to assert, standard values if CLI omits certain values
         val limits = JsObject(
           "timeout" -> timeout.getOrElse(STD_DURATION).toMillis.toJson,
-          "memory" -> memory.getOrElse(STD_MEMORY).toMB.toInt.toJson,
+          "memory" -> memory.getOrElse(stdMemory).toMB.toInt.toJson,
           "logs" -> logs.getOrElse(STD_LOGSIZE).toMB.toInt.toJson)
 
         val name = "ActionLimitTests" + Instant.now.toEpochMilli
@@ -747,7 +747,7 @@ class WskBasicUsageTests extends TestHelpers with 
WskTestHelpers {
       // Assert for valid permutations that the values are set correctly
       for {
         time <- Seq(None, Some(MIN_DURATION), Some(MAX_DURATION))
-        mem <- Seq(None, Some(MIN_MEMORY), Some(MAX_MEMORY))
+        mem <- Seq(None, Some(minMemory), Some(maxMemory))
         log <- Seq(None, Some(MIN_LOGSIZE), Some(MAX_LOGSIZE))
       } testLimit(time, mem, log)
 
diff --git a/tests/src/test/scala/whisk/core/entity/test/SchemaTests.scala 
b/tests/src/test/scala/whisk/core/entity/test/SchemaTests.scala
index 504db38c0e..ffe78cd0d2 100644
--- a/tests/src/test/scala/whisk/core/entity/test/SchemaTests.scala
+++ b/tests/src/test/scala/whisk/core/entity/test/SchemaTests.scala
@@ -601,16 +601,16 @@ class SchemaTests extends FlatSpec with BeforeAndAfter 
with ExecHelpers with Mat
     val json = Seq[JsValue](
       JsObject(
         "timeout" -> TimeLimit.STD_DURATION.toMillis.toInt.toJson,
-        "memory" -> MemoryLimit.STD_MEMORY.toMB.toInt.toJson,
+        "memory" -> MemoryLimit.stdMemory.toMB.toInt.toJson,
         "logs" -> LogLimit.STD_LOGSIZE.toMB.toInt.toJson),
       JsObject(
         "timeout" -> TimeLimit.STD_DURATION.toMillis.toInt.toJson,
-        "memory" -> MemoryLimit.STD_MEMORY.toMB.toInt.toJson,
+        "memory" -> MemoryLimit.stdMemory.toMB.toInt.toJson,
         "logs" -> LogLimit.STD_LOGSIZE.toMB.toInt.toJson,
         "foo" -> "bar".toJson),
       JsObject(
         "timeout" -> TimeLimit.STD_DURATION.toMillis.toInt.toJson,
-        "memory" -> MemoryLimit.STD_MEMORY.toMB.toInt.toJson))
+        "memory" -> MemoryLimit.stdMemory.toMB.toInt.toJson))
     val limits = json.map(ActionLimits.serdes.read)
     assert(limits(0) == ActionLimits())
     assert(limits(1) == ActionLimits())
@@ -626,19 +626,19 @@ class SchemaTests extends FlatSpec with BeforeAndAfter 
with ExecHelpers with Mat
       JsObject(),
       JsNull,
       JsObject("timeout" -> TimeLimit.STD_DURATION.toMillis.toInt.toJson),
-      JsObject("memory" -> MemoryLimit.STD_MEMORY.toMB.toInt.toJson),
+      JsObject("memory" -> MemoryLimit.stdMemory.toMB.toInt.toJson),
       JsObject("logs" -> (LogLimit.STD_LOGSIZE.toMB.toInt + 1).toJson),
       JsObject(
         "TIMEOUT" -> TimeLimit.STD_DURATION.toMillis.toInt.toJson,
-        "MEMORY" -> MemoryLimit.STD_MEMORY.toMB.toInt.toJson),
+        "MEMORY" -> MemoryLimit.stdMemory.toMB.toInt.toJson),
       JsObject(
         "timeout" -> (TimeLimit.STD_DURATION.toMillis.toDouble + .01).toJson,
-        "memory" -> (MemoryLimit.STD_MEMORY.toMB.toDouble + .01).toJson),
+        "memory" -> (MemoryLimit.stdMemory.toMB.toDouble + .01).toJson),
       JsObject("timeout" -> null, "memory" -> null),
       JsObject("timeout" -> JsNull, "memory" -> JsNull),
       JsObject(
         "timeout" -> TimeLimit.STD_DURATION.toMillis.toString.toJson,
-        "memory" -> MemoryLimit.STD_MEMORY.toMB.toInt.toString.toJson))
+        "memory" -> MemoryLimit.stdMemory.toMB.toInt.toString.toJson))
 
     limits.foreach { p =>
       a[DeserializationException] should be thrownBy 
ActionLimits.serdes.read(p)
@@ -674,7 +674,7 @@ class SchemaTests extends FlatSpec with BeforeAndAfter with 
ExecHelpers with Mat
       LogLimit())
     an[IllegalArgumentException] should be thrownBy ActionLimits(
       TimeLimit(),
-      MemoryLimit(MemoryLimit.MIN_MEMORY - 1.B),
+      MemoryLimit(MemoryLimit.minMemory - 1.B),
       LogLimit())
     an[IllegalArgumentException] should be thrownBy ActionLimits(
       TimeLimit(),
@@ -687,7 +687,7 @@ class SchemaTests extends FlatSpec with BeforeAndAfter with 
ExecHelpers with Mat
       LogLimit())
     an[IllegalArgumentException] should be thrownBy ActionLimits(
       TimeLimit(),
-      MemoryLimit(MemoryLimit.MAX_MEMORY + 1.B),
+      MemoryLimit(MemoryLimit.maxMemory + 1.B),
       LogLimit())
     an[IllegalArgumentException] should be thrownBy ActionLimits(
       TimeLimit(),


 

----------------------------------------------------------------
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:
[email protected]


With regards,
Apache Git Services

Reply via email to