tz70s closed pull request #3757: Introduce configurable action blob size limit.
URL: https://github.com/apache/incubator-openwhisk/pull/3757
 
 
   

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 29dcc1b96a..b1bdb24d91 100644
--- a/ansible/roles/controller/tasks/deploy.yml
+++ b/ansible/roles/controller/tasks/deploy.yml
@@ -190,6 +190,10 @@
       "CONFIG_whisk_timeLimit_max": "{{ limit_action_time_max | default() }}"
       "CONFIG_whisk_timeLimit_std": "{{ limit_action_time_std | default() }}"
 
+      "CONFIG_whisk_action_blobSize": "{{ limit_action_blob_size | default() 
}}"
+      "CONFIG_akka_http_server_parsing_maxContentLength": "{{ 
limit_action_blob_size | default() }}"
+      "CONFIG_akka_http_client_parsing_maxContentLength": "{{ 
limit_action_blob_size | default() }}"
+
       "CONFIG_whisk_activation_payload_max":
         "{{ limit_activation_payload | default() }}"
 
diff --git a/ansible/roles/couchdb/tasks/deploy.yml 
b/ansible/roles/couchdb/tasks/deploy.yml
index b59c23d044..4f87357176 100644
--- a/ansible/roles/couchdb/tasks/deploy.yml
+++ b/ansible/roles/couchdb/tasks/deploy.yml
@@ -63,6 +63,19 @@
     force_basic_auth: yes
   when: (couchdb.version|version_compare('2.0','>=')) and (db.instances|int == 
1)
 
+- name: setup httpd request entity size limit for database
+  uri:
+    url: "{{ db_protocol }}://{{ ansible_host }}:{{ db_port 
}}/_node/couchdb@{{ ansible_host }}/_config/httpd/max_http_request_size"
+    method: PUT
+    body: >
+      "{{ limit_action_blob_size | default('50m') | human_to_bytes }}"
+    body_format: raw
+    status_code: 200
+    user: "{{ db_username }}"
+    password: "{{ db_password }}"
+    force_basic_auth: yes
+  when: (couchdb.version|version_compare('2.0','>=')) and (db.instances|int == 
1)
+
 - name: enable the cluster setup mode
   uri:
     url: "{{ db_protocol }}://{{ ansible_host }}:{{ db_port }}/_cluster_setup"
diff --git a/ansible/roles/invoker/tasks/deploy.yml 
b/ansible/roles/invoker/tasks/deploy.yml
index ee4a79aaf3..24d21f09ce 100644
--- a/ansible/roles/invoker/tasks/deploy.yml
+++ b/ansible/roles/invoker/tasks/deploy.yml
@@ -207,6 +207,9 @@
       "CONFIG_whisk_timeLimit_min": "{{ limit_action_time_min | default() }}"
       "CONFIG_whisk_timeLimit_max": "{{ limit_action_time_max | default() }}"
       "CONFIG_whisk_timeLimit_std": "{{ limit_action_time_std | default() }}"
+      "CONFIG_whisk_action_blobSize": "{{ limit_action_blob_size | default() 
}}"
+      "CONFIG_akka_http_server_parsing_maxContentLength": "{{ 
limit_action_blob_size | default() }}"
+      "CONFIG_akka_http_client_parsing_maxContentLength": "{{ 
limit_action_blob_size | default() }}"
       "CONFIG_whisk_activation_payload_max": "{{ limit_activation_payload | 
default() }}"
       "CONFIG_whisk_transactions_header": "{{ transactions.header }}"
 
diff --git a/ansible/roles/nginx/templates/nginx.conf.j2 
b/ansible/roles/nginx/templates/nginx.conf.j2
index a86593f26e..1e8787ef61 100644
--- a/ansible/roles/nginx/templates/nginx.conf.j2
+++ b/ansible/roles/nginx/templates/nginx.conf.j2
@@ -10,7 +10,7 @@ events {
 
 http {
 {# allow large uploads, need to thread proper limit into here #}
-    client_max_body_size 50M;
+    client_max_body_size {{ limit_action_blob_size | default('50m') | upper }};
 
     rewrite_log on;
 {# change log format to display the upstream information #}
diff --git a/common/scala/src/main/resources/application.conf 
b/common/scala/src/main/resources/application.conf
index feaa96095c..ee5544efe1 100644
--- a/common/scala/src/main/resources/application.conf
+++ b/common/scala/src/main/resources/application.conf
@@ -6,8 +6,15 @@ include "logging"
 
 akka.http {
     client {
-        parsing.illegal-header-warnings = off
-        parsing.max-chunk-size = 50m
+        request-timeout = 65s
+
+        idle-timeout = 70s
+
+        parsing {
+            illegal-header-warnings = off
+            max-chunk-size = 50m
+            max-content-length = 50m
+        }
     }
 
     host-connection-pool {
@@ -168,6 +175,11 @@ whisk {
         std = 256 m
     }
 
+    # action blob size limit configuration
+    action {
+        blob-size = 48 m
+    }
+
     # action log-limit configuration
     log-limit {
         min = 0 m
diff --git a/common/scala/src/main/scala/whisk/core/WhiskConfig.scala 
b/common/scala/src/main/scala/whisk/core/WhiskConfig.scala
index 0c937ae372..4ce02108d7 100644
--- a/common/scala/src/main/scala/whisk/core/WhiskConfig.scala
+++ b/common/scala/src/main/scala/whisk/core/WhiskConfig.scala
@@ -218,6 +218,7 @@ object ConfigKeys {
   val memory = "whisk.memory"
   val timeLimit = "whisk.time-limit"
   val logLimit = "whisk.log-limit"
+  val actionBlobSize = "whisk.action.blob-size"
   val activation = "whisk.activation"
   val activationPayload = s"$activation.payload"
   val userEvents = "whisk.user-events"
diff --git a/common/scala/src/main/scala/whisk/core/entity/Exec.scala 
b/common/scala/src/main/scala/whisk/core/entity/Exec.scala
index a281144a62..9f9c667b38 100644
--- a/common/scala/src/main/scala/whisk/core/entity/Exec.scala
+++ b/common/scala/src/main/scala/whisk/core/entity/Exec.scala
@@ -19,7 +19,6 @@ package whisk.core.entity
 
 import java.nio.charset.StandardCharsets
 
-import scala.language.postfixOps
 import scala.util.matching.Regex
 
 import spray.json._
@@ -29,6 +28,8 @@ import whisk.core.entity.ExecManifest._
 import whisk.core.entity.size.SizeInt
 import whisk.core.entity.size.SizeOptionString
 import whisk.core.entity.size.SizeString
+import whisk.core.ConfigKeys
+import pureconfig.loadConfigOrThrow
 
 /**
  * Exec encodes the executable details of an action. For black
@@ -212,7 +213,9 @@ protected[core] case class SequenceExecMetaData(components: 
Vector[FullyQualifie
 
 protected[core] object Exec extends ArgNormalizer[Exec] with 
DefaultJsonProtocol {
 
-  val sizeLimit = 48 MB
+  import whisk.core.entity.size.pureconfigReader
+
+  val sizeLimit = loadConfigOrThrow[ByteSize](ConfigKeys.actionBlobSize)
 
   // The possible values of the JSON 'kind' field for certain runtimes:
   // - Sequence because it is an intrinsic
@@ -342,7 +345,7 @@ protected[core] object Exec extends ArgNormalizer[Exec] 
with DefaultJsonProtocol
 
 protected[core] object ExecMetaDataBase extends 
ArgNormalizer[ExecMetaDataBase] with DefaultJsonProtocol {
 
-  val sizeLimit = 48 MB
+  val sizeLimit = Exec.sizeLimit
 
   // The possible values of the JSON 'kind' field for certain runtimes:
   // - Sequence because it is an intrinsic
diff --git 
a/core/invoker/src/main/scala/whisk/core/containerpool/docker/DockerContainerFactory.scala
 
b/core/invoker/src/main/scala/whisk/core/containerpool/docker/DockerContainerFactory.scala
index 3f2ee86406..c51eedb634 100644
--- 
a/core/invoker/src/main/scala/whisk/core/containerpool/docker/DockerContainerFactory.scala
+++ 
b/core/invoker/src/main/scala/whisk/core/containerpool/docker/DockerContainerFactory.scala
@@ -18,6 +18,7 @@
 package whisk.core.containerpool.docker
 
 import akka.actor.ActorSystem
+
 import scala.concurrent.Await
 import scala.concurrent.ExecutionContext
 import scala.concurrent.Future
@@ -30,11 +31,14 @@ import whisk.core.containerpool.ContainerFactoryProvider
 import whisk.core.entity.ByteSize
 import whisk.core.entity.ExecManifest
 import whisk.core.entity.InstanceId
+
 import scala.concurrent.duration._
 import java.util.concurrent.TimeoutException
+
 import pureconfig._
 import whisk.core.ConfigKeys
 import whisk.core.containerpool.ContainerArgsConfig
+import whisk.core.entity.Exec.sizeLimit
 
 case class DockerContainerFactoryConfig(useRunc: Boolean)
 
@@ -70,7 +74,7 @@ class DockerContainerFactory(instance: InstanceId,
       userProvidedImage = userProvidedImage,
       memory = memory,
       cpuShares = cpuShares,
-      environment = Map("__OW_API_HOST" -> config.wskApiHost),
+      environment = Map("__OW_API_HOST" -> config.wskApiHost, 
"__OW_ACTION_BLOB_SIZE" -> s"${sizeLimit.toMB}"),
       network = containerArgsConfig.network,
       dnsServers = containerArgsConfig.dnsServers,
       name = Some(name),
diff --git 
a/core/invoker/src/main/scala/whisk/core/containerpool/kubernetes/KubernetesContainerFactory.scala
 
b/core/invoker/src/main/scala/whisk/core/containerpool/kubernetes/KubernetesContainerFactory.scala
index e332b84861..4dfbe041ae 100644
--- 
a/core/invoker/src/main/scala/whisk/core/containerpool/kubernetes/KubernetesContainerFactory.scala
+++ 
b/core/invoker/src/main/scala/whisk/core/containerpool/kubernetes/KubernetesContainerFactory.scala
@@ -30,6 +30,7 @@ import whisk.common.TransactionId
 import whisk.core.containerpool.Container
 import whisk.core.containerpool.ContainerFactory
 import whisk.core.containerpool.ContainerFactoryProvider
+import whisk.core.entity.Exec.sizeLimit
 import whisk.core.entity.ByteSize
 import whisk.core.entity.ExecManifest.ImageName
 import whisk.core.entity.InstanceId
@@ -78,7 +79,7 @@ class KubernetesContainerFactory(label: String, config: 
WhiskConfig)(implicit ac
       image,
       userProvidedImage,
       memory,
-      environment = Map("__OW_API_HOST" -> config.wskApiHost),
+      environment = Map("__OW_API_HOST" -> config.wskApiHost, 
"__OW_ACTION_BLOB_SIZE" -> s"${sizeLimit.toMB}"),
       labels = Map("invoker" -> label))
   }
 }
diff --git a/docs/deploy.md b/docs/deploy.md
index 5fef484c57..6493e38aba 100644
--- a/docs/deploy.md
+++ b/docs/deploy.md
@@ -57,3 +57,30 @@ Using docker-runc obtains significantly better performance, 
but requires that th
 2017-09-29T20:15:54.551Z] [ERROR] [#sid_102] [RuncClient] code: 1, stdout: , 
stderr: json: cannot unmarshal object into Go value of type []string 
[marker:invoker_runc.pause_error:6830148:259]
 ```
 When a docker-runc operations results in an error, the container will be 
killed by the invoker.  This results in missed opportunities for container 
reuse and poor performance.  Setting INVOKER_USE_RUNC to false can be used as a 
workaround until proper usage of docker-runc can be configured for the 
deployment.
+
+# System configuration for large size actions.
+
+Notice that current OpenWhisk implementation is still not suitable to deal 
with large size action. The recommended way is to refactor applications into 
smaller granularities.
+
+To create a large size action, you have to build the system with large size 
tolerable limits.
+
+## Size limit
+
+Set `limit_action_code_size` for nginx, controller, invoker and database (only 
support couchdb, currently).
+
+## Timeout limit
+
+The timeout depends on how large the system resource is. Therefore, several 
timeout limits will be configured manually and separately. Here's some config 
you might need to set:
+
+* Internal http timeout: 
`akka.http.[client/server].[request-timeout/idle-timeout]`.
+* Database query timeout: i.e. `query_server_config.os_process_limit` in 
couchdb.
+* Nginx: `proxy_read_timeout`.
+* [Aaction invocation 
timeout](./reference.md#per-action-timeout-ms-default-60s)
+
+## System tunning
+
+Finally, you have to make sure the system have enough resources, including:
+
+* JVM heap size: `controller_heap` and `invoker_heap`.
+* If you are running OpenWhisk in sandboxed environment (i.e. VMs or Docker 
for mac), make sure the resource is allocate sufficiently.
+* [Action memory limit](./reference.md#per-action-memory-mb-default-256mb)
diff --git a/docs/reference.md b/docs/reference.md
index d23ed92b20..8324206cec 100644
--- a/docs/reference.md
+++ b/docs/reference.md
@@ -465,7 +465,7 @@ The following table lists the default limits for actions.
 | logs | a container is not allowed to write more than N MB to stdout | per 
action | MB | 10 |
 | concurrent | no more than N activations may be submitted per namespace 
either executing or queued for execution | per namespace | number | 100 |
 | minuteRate | no more than N activations may be submitted per namespace per 
minute | per namespace | number | 120 |
-| codeSize | the maximum size of the actioncode | not configurable, limit per 
action | MB | 48 |
+| codeSize | the maximum size of the actioncode | configurable during 
deployment, limit per action | MB | 48 |
 | parameters | the maximum size of the parameters that can be attached | not 
configurable, limit per action/package/trigger | MB | 1 |
 | result | the maximum size of the action result | not configurable, limit per 
action | MB | 1 |
 
@@ -484,8 +484,8 @@ The following table lists the default limits for actions.
 * A user can change the limit when creating or updating the action.
 * Logs that exceed the set limit are truncated and a warning is added as the 
last output of the activation to indicate that the activation exceeded the set 
log limit.
 
-### Per action artifact (MB) (Fixed: 48MB)
-* The maximum code size for the action is 48MB.
+### Per action artifact (MB) (Default: 48MB)
+* The maximum code size for the action is fixed on deployment.
 * It is recommended for a JavaScript action to use a tool to concatenate all 
source code including dependencies into a single bundled file.
 
 ### Per activation payload size (MB) (Fixed: 1MB)
diff --git 
a/tests/src/test/scala/whisk/core/containerpool/docker/test/DockerContainerFactoryTests.scala
 
b/tests/src/test/scala/whisk/core/containerpool/docker/test/DockerContainerFactoryTests.scala
index 31139dc802..90395f26ff 100644
--- 
a/tests/src/test/scala/whisk/core/containerpool/docker/test/DockerContainerFactoryTests.scala
+++ 
b/tests/src/test/scala/whisk/core/containerpool/docker/test/DockerContainerFactoryTests.scala
@@ -42,6 +42,7 @@ import whisk.core.containerpool.docker.RuncApi
 import whisk.core.entity.ExecManifest
 import whisk.core.entity.InstanceId
 import whisk.core.entity.size._
+import whisk.core.entity.Exec.sizeLimit
 
 @RunWith(classOf[JUnitRunner])
 class DockerContainerFactoryTests
@@ -81,6 +82,8 @@ class DockerContainerFactoryTests
           "net1",
           "-e",
           "__OW_API_HOST=://:",
+          "-e",
+          s"__OW_ACTION_BLOB_SIZE=${sizeLimit.toMB}",
           "--dns",
           "dns1",
           "--dns",


 

----------------------------------------------------------------
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