This is an automated email from the ASF dual-hosted git repository. pdesai pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-wskdeploy.git
The following commit(s) were added to refs/heads/master by this push: new fa006fc Account for variability in Account Limits from various provider impls. (#1048) fa006fc is described below commit fa006fc368fbb272944339c303e69d0d166ef026 Author: Matt Rutkowski <mrutk...@us.ibm.com> AuthorDate: Fri Apr 5 12:13:40 2019 -0500 Account for variability in Account Limits from various provider impls. (#1048) * Account for variability in Account Limits from various provider impls. * Account for variability in Account Limits from various provider impls. * Account for variability in Account Limits from various provider impls. * Account for variability in Account Limits from various provider impls. * Account for variability in Account Limits from various provider impls. * Account for variability in Account Limits from various provider impls. * Account for variability in Account Limits from various provider impls. * Account for variability in Account Limits from various provider impls. * Account for variability in Account Limits from various provider impls. * Account for variability in Account Limits from various provider impls. * Account for variability in Account Limits from various provider impls. --- parsers/manifest_parser_test.go | 5 +- specification/html/spec_actions.md | 104 +++++++++++---------- .../manifest_data_compose_actions_for_limits.yaml | 1 + utils/validation.go | 18 +++- wski18n/i18n_resources.go | 56 +++++------ wski18n/resources/en_US.all.json | 8 +- 6 files changed, 104 insertions(+), 88 deletions(-) diff --git a/parsers/manifest_parser_test.go b/parsers/manifest_parser_test.go index e7358f8..bc89472 100644 --- a/parsers/manifest_parser_test.go +++ b/parsers/manifest_parser_test.go @@ -994,9 +994,10 @@ func TestComposeActionsForLimits(t *testing.T) { for i := 0; i < len(actions); i++ { if actions[i].Action.Name == "hello1" { - assert.Nil(t, actions[i].Action.Limits, "Expected limit section to be empty but got %s", actions[i].Action.Limits) + assert.NotNil(t, actions[i].Action.Limits, "Expected limit section to not be empty but found it empty") + assert.Equal(t, 600000, *actions[i].Action.Limits.Timeout, "Failed to get Timeout") } else if actions[i].Action.Name == "hello2" { - assert.NotNil(t, actions[i].Action.Limits, "Expected limit section to be not empty but found it empty") + assert.NotNil(t, actions[i].Action.Limits, "Expected limit section to not be empty but found it empty") assert.Equal(t, 180, *actions[i].Action.Limits.Timeout, "Failed to get Timeout") assert.Equal(t, 128, *actions[i].Action.Limits.Memory, "Failed to get Memory") assert.Equal(t, 1, *actions[i].Action.Limits.Logsize, "Failed to get Logsize") diff --git a/specification/html/spec_actions.md b/specification/html/spec_actions.md index d3ad8e6..d35bc40 100644 --- a/specification/html/spec_actions.md +++ b/specification/html/spec_actions.md @@ -202,70 +202,72 @@ following file extensions are recognized and will be run on the latest version o <html> <table id="TABLE_LIMIT_KEYS"> - <tr> - <th>Limit Keyname</th> - <th>Allowed values</th> - <th>Default value</th> - <th>Valid Range</th> - <th>Description</th> - </tr> - <tr> - <td>timeout</td> - <td>scalar-unit.time</td> - <td>60000 ms</td> - <td>[100 ms, 300000 ms]</td> - <td>The per-invocation Action timeout. Default unit is assumed to be milliseconds (ms).</td> - </tr> - <tr> +<tr> + <th>Limit Keyname</th> + <th>Type</th> + <th>Default value <sup><a href="#limit-notes">1</a></sup></th> + <th>Default Range <sup><a href="#limit-notes">2</a></sup></th> + <th>Description</th> +</tr> +<tr> + <td>codeSize</td> + <td>scalar-unit.size</td> + <td>48 MB</td> + <td>[1, 48] MB<sup><a href="#limit-notes">3</a></sup></td> + <td>The maximum size of the Action code.</td> +</tr> +<tr> + <td>concurrentActivations</td> + <td>integer</td> + <td>1000</td> + <td>[1, 1000] <sup><a href="#limit-notes">3</a></sup></td> + <td>The maximum number of concurrent Action activations allowed (per-namespace).</td> +</tr> +<tr> + <td>logSize</td> + <td>scalar-unit.size</td> + <td>10 MB</td> + <td>[0, 10] MB</td> + <td>The action log size. Default unit is assumed to be in megabytes (MB).</td> +</tr> +<tr> <td>memorySize</td> <td>scalar-unit.size</td> <td>256 MB</td> - <td>[128 MB, 512 MB]</td> + <td>[128, 2048] MB</td> <td>The per-Action memory. Default unit is assumed to be in megabytes (MB).</p> </td> - </tr> - <tr> - <td>logSize</td> +</tr> +<tr> + <td>parameterSize</td> <td>scalar-unit.size</td> - <td>10 MB</td> - <td>[0 MB, 10 MB]</td> - <td>The action log size. Default unit is assumed to be in megabytes (MB).</td> - </tr> - <tr> - <td>concurrentActivations</td> - <td>integer</td> - <td>1000</td> - <td><i>See description</i></td> - <td>The maximum number of concurrent Action activations allowed (per-namespace). <p><i>Note: This value is not changeable via APIs at this time.</i></p></td> - </tr> - <tr> + <td>5 MB</td> + <td>[0, 5] MB <sup><a href="#limit-notes">3, 4</a></sup></td> + <td>The maximum size of all parameters (total) for an Action.</td> +</tr> +<tr> + <td>timeout</td> + <td>scalar-unit.time</td> + <td>60000 ms</td> + <td>[100, 600000] ms</td> + <td>The per-invocation Action timeout. Default unit is assumed to be milliseconds (ms).</td> +</tr> +<tr> <td>userInvocationRate</td> <td>integer</td> <td>5000</td> - <td><i>See description</i></td> - <td>The maximum number of Action invocations allowed per user, per minute. <p><i>Note: This value is not changeable via APIs at this time.</i></p></td> - </tr> - <tr> - <td>codeSize</td> - <td>scalar-unit.size</td> - <td>48 MB</td> - <td><i>See description</i></td> - <td>The maximum size of the Action code.<p><i>Note: This value is not changeable via APIs at this - time.</i></p></td> - </tr> - <tr> - <td>parameterSize</td> - <td>scalar-unit.size</td> - <td>1 MB</td> - <td><i>See description</i></td> - <td>The maximum size<p><i>Note: This value is not changeable via APIs at this time.</i></p></td> - </tr> + <td>[1, 5000] <sup><a href="#limit-notes">3</a></sup></td> + <td>The maximum number of Action invocations allowed per user, per minute.</td> +</tr> </table> </html> -#### Notes +#### Limit Notes -- The default values and ranges for limit configurations reflect the defaults for the OpenWhisk platform (open source code). These values may be changed over time to reflect the open source community consensus. +1. The default values and ranges for limit configurations reflect the defaults for the OpenWhisk platform (open source code). These values may be changed over time to reflect the open source community consensus. +2. Serverless providers that use Apache OpenWhisk MAY choose to enforce different defaults and value ranges for limits. +3. This limit is not currently user configurable. +4. The parameter size limit also applies to Triggers and Packages. ### Web Actions OpenWhisk can turn any Action into a 'web action' causing it to return HTTP content without use of an API Gateway. Simply supply a supported 'type' extension to indicate which content type is to be returned and identified in the HTTP header (e.g., _.json_, _.html_, _.text_ or _.http_). diff --git a/tests/dat/manifest_data_compose_actions_for_limits.yaml b/tests/dat/manifest_data_compose_actions_for_limits.yaml index f7eb1e5..993c17e 100644 --- a/tests/dat/manifest_data_compose_actions_for_limits.yaml +++ b/tests/dat/manifest_data_compose_actions_for_limits.yaml @@ -8,6 +8,7 @@ packages: function: ../src/integration/helloworld/actions/hello.js limits: timeout: 1 + timeout: 600000 hello2: function: ../src/integration/helloworld/actions/hello.js limits: diff --git a/utils/validation.go b/utils/validation.go index 59501c8..1b43623 100644 --- a/utils/validation.go +++ b/utils/validation.go @@ -140,9 +140,13 @@ func LimitsTimeoutValidation(timeout *int) bool { if timeout == nil { return true } - if *timeout < 100 || *timeout > 300000 { + if *timeout < 100 { + // Do not allow invalid limit to be added to API wskprint.PrintlnOpenWhiskWarning(wski18n.T(wski18n.ID_WARN_LIMITS_TIMEOUT)) return false + } else if *timeout > 600000 { + // Emit a warning, but allow to pass through to provider + wskprint.PrintlnOpenWhiskWarning(wski18n.T(wski18n.ID_WARN_LIMITS_TIMEOUT)) } return true } @@ -153,9 +157,13 @@ func LimitsMemoryValidation(memory *int) bool { if memory == nil { return true } - if *memory < 128 || *memory > 2048 { + if *memory < 128 { + // Do not allow invalid limit to be added to API wskprint.PrintlnOpenWhiskWarning(wski18n.T(wski18n.ID_WARN_LIMITS_MEMORY_SIZE)) return false + } else if *memory > 2048 { + // Emit a warning, but allow to pass through to provider + wskprint.PrintlnOpenWhiskWarning(wski18n.T(wski18n.ID_WARN_LIMITS_MEMORY_SIZE)) } return true } @@ -166,9 +174,13 @@ func LimitsLogsizeValidation(logsize *int) bool { if logsize == nil { return true } - if *logsize < 0 || *logsize > 10 { + if *logsize < 0 { + // Do not allow invalid limit to be added to API wskprint.PrintlnOpenWhiskWarning(wski18n.T(wski18n.ID_WARN_LIMITS_LOG_SIZE)) return false + } else if *logsize > 10 { + // Emit a warning, but allow to pass through to provider + wskprint.PrintlnOpenWhiskWarning(wski18n.T(wski18n.ID_WARN_LIMITS_LOG_SIZE)) } return true } diff --git a/wski18n/i18n_resources.go b/wski18n/i18n_resources.go index 164bc68..f9cba2f 100644 --- a/wski18n/i18n_resources.go +++ b/wski18n/i18n_resources.go @@ -92,12 +92,12 @@ func wski18nResourcesDe_deAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1520374115, 0)} + info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x3c\xfd\x6f\x1b\xb7\x92\xbf\xe7\xaf\x18\x14\x0f\x48\x0b\xd8\x72\xfb\x0e\x07\x1c\x8c\xcb\x01\xbe\xc4\xe9\xf3\x6b\x12\x1b\xb6\xd3\xa2\x97\x04\x1b\x6a\x77\x24\xf1\x79\x97\xdc\x92\x5c\x29\xaa\xa1\xff\xfd\x30\x43\x72\x77\x25\x6b\x3f\xa4\xa4\xb8\xcb\x2f\x91\xb4\xe4\x7c\x71\x38\xdf\xeb\x0f\xcf\x00\x1e\x9f\x01\x00\x7c\x27\xb3\xef\xce\xe1\xbb\xc2\xce\x93\xd2\xe0\x4c\x7e\x49\xd0\x18\x6d\xbe\x3b\xf1\x4f\x9d\x11 [...] +var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x3c\x6b\x6f\x1b\x39\x92\xdf\xe7\x57\x14\x06\x0b\xcc\x2c\x20\xcb\xd9\xc5\xe1\xb0\x30\x2e\x07\x78\x13\x67\xd6\x3b\x49\x6c\xd8\xce\x0c\xe6\x12\xa3\x43\x75\x97\x24\xae\xbb\xc9\x5e\x92\x2d\x45\x63\xe8\xbf\x1f\xaa\x48\x76\xb7\x64\xf5\x43\x4e\x06\x77\xf9\x12\x49\x24\xeb\xc5\x62\x3d\x49\x7f\xfc\x0e\xe0\xf1\x3b\x00\x80\xef\x65\xf6\xfd\x19\x7c\x5f\xd8\x45\x52\x1a\x9c\xcb\x2f\x09\x1a\xa3\xcd\xf7\x13\x3f\xea\x8c [...] func wski18nResourcesEn_usAllJsonBytes() ([]byte, error) { return bindataRead( @@ -112,7 +112,7 @@ func wski18nResourcesEn_usAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 20708, mode: os.FileMode(420), modTime: time.Unix(1539294171, 0)} + info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 20876, mode: os.FileMode(420), modTime: time.Unix(1554424542, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -132,7 +132,7 @@ func wski18nResourcesEs_esAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1520374115, 0)} + info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -152,7 +152,7 @@ func wski18nResourcesFr_frAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 101, mode: os.FileMode(420), modTime: time.Unix(1520374115, 0)} + info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 101, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -172,7 +172,7 @@ func wski18nResourcesIt_itAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1520374115, 0)} + info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -192,7 +192,7 @@ func wski18nResourcesJa_jaAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1520374115, 0)} + info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -212,7 +212,7 @@ func wski18nResourcesKo_krAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1520374115, 0)} + info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -232,7 +232,7 @@ func wski18nResourcesPt_brAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1520374115, 0)} + info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -252,7 +252,7 @@ func wski18nResourcesZh_hansAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1520374115, 0)} + info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -272,7 +272,7 @@ func wski18nResourcesZh_hantAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1520374115, 0)} + info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -329,14 +329,14 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ - "wski18n/resources/de_DE.all.json": wski18nResourcesDe_deAllJson, - "wski18n/resources/en_US.all.json": wski18nResourcesEn_usAllJson, - "wski18n/resources/es_ES.all.json": wski18nResourcesEs_esAllJson, - "wski18n/resources/fr_FR.all.json": wski18nResourcesFr_frAllJson, - "wski18n/resources/it_IT.all.json": wski18nResourcesIt_itAllJson, - "wski18n/resources/ja_JA.all.json": wski18nResourcesJa_jaAllJson, - "wski18n/resources/ko_KR.all.json": wski18nResourcesKo_krAllJson, - "wski18n/resources/pt_BR.all.json": wski18nResourcesPt_brAllJson, + "wski18n/resources/de_DE.all.json": wski18nResourcesDe_deAllJson, + "wski18n/resources/en_US.all.json": wski18nResourcesEn_usAllJson, + "wski18n/resources/es_ES.all.json": wski18nResourcesEs_esAllJson, + "wski18n/resources/fr_FR.all.json": wski18nResourcesFr_frAllJson, + "wski18n/resources/it_IT.all.json": wski18nResourcesIt_itAllJson, + "wski18n/resources/ja_JA.all.json": wski18nResourcesJa_jaAllJson, + "wski18n/resources/ko_KR.all.json": wski18nResourcesKo_krAllJson, + "wski18n/resources/pt_BR.all.json": wski18nResourcesPt_brAllJson, "wski18n/resources/zh_Hans.all.json": wski18nResourcesZh_hansAllJson, "wski18n/resources/zh_Hant.all.json": wski18nResourcesZh_hantAllJson, } @@ -380,18 +380,17 @@ type bintree struct { Func func() (*asset, error) Children map[string]*bintree } - var _bintree = &bintree{nil, map[string]*bintree{ "wski18n": &bintree{nil, map[string]*bintree{ "resources": &bintree{nil, map[string]*bintree{ - "de_DE.all.json": &bintree{wski18nResourcesDe_deAllJson, map[string]*bintree{}}, - "en_US.all.json": &bintree{wski18nResourcesEn_usAllJson, map[string]*bintree{}}, - "es_ES.all.json": &bintree{wski18nResourcesEs_esAllJson, map[string]*bintree{}}, - "fr_FR.all.json": &bintree{wski18nResourcesFr_frAllJson, map[string]*bintree{}}, - "it_IT.all.json": &bintree{wski18nResourcesIt_itAllJson, map[string]*bintree{}}, - "ja_JA.all.json": &bintree{wski18nResourcesJa_jaAllJson, map[string]*bintree{}}, - "ko_KR.all.json": &bintree{wski18nResourcesKo_krAllJson, map[string]*bintree{}}, - "pt_BR.all.json": &bintree{wski18nResourcesPt_brAllJson, map[string]*bintree{}}, + "de_DE.all.json": &bintree{wski18nResourcesDe_deAllJson, map[string]*bintree{}}, + "en_US.all.json": &bintree{wski18nResourcesEn_usAllJson, map[string]*bintree{}}, + "es_ES.all.json": &bintree{wski18nResourcesEs_esAllJson, map[string]*bintree{}}, + "fr_FR.all.json": &bintree{wski18nResourcesFr_frAllJson, map[string]*bintree{}}, + "it_IT.all.json": &bintree{wski18nResourcesIt_itAllJson, map[string]*bintree{}}, + "ja_JA.all.json": &bintree{wski18nResourcesJa_jaAllJson, map[string]*bintree{}}, + "ko_KR.all.json": &bintree{wski18nResourcesKo_krAllJson, map[string]*bintree{}}, + "pt_BR.all.json": &bintree{wski18nResourcesPt_brAllJson, map[string]*bintree{}}, "zh_Hans.all.json": &bintree{wski18nResourcesZh_hansAllJson, map[string]*bintree{}}, "zh_Hant.all.json": &bintree{wski18nResourcesZh_hantAllJson, map[string]*bintree{}}, }}, @@ -444,3 +443,4 @@ func _filePath(dir, name string) string { cannonicalName := strings.Replace(name, "\\", "/", -1) return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) } + diff --git a/wski18n/resources/en_US.all.json b/wski18n/resources/en_US.all.json index 9e78b70..96fb5da 100644 --- a/wski18n/resources/en_US.all.json +++ b/wski18n/resources/en_US.all.json @@ -421,19 +421,19 @@ }, { "id": "msg_warn_limit_changeable", - "translation": "Limit [{{.name}}] is currently not changeable. Ignoring...\n" + "translation": "Action Limit [{{.name}}] is currently not changeable. Ignoring...\n" }, { "id": "msg_warn_limits_log_size", - "translation": "logSize of limits in manifest should be an integer between 0 and 10.\n" + "translation": "Action limit: logSize may be outside the default range of [0, 10] MB. Please verify your provider supports this value.\n" }, { "id": "msg_warn_limits_memory_size", - "translation": "memorySize of limits in manifest should be an integer between 128 and 512.\n" + "translation": "Action limit: memorySize may be outside the default range of [128, 2048] MB. Please verify your provider supports this value.\n" }, { "id": "msg_warn_limits_timeout", - "translation": "timeout of limits in manifest should be an integer between 100 and 300000.\n" + "translation": "Action limit: timeout may be outside the default range of [100, 600000] milliseconds. Please verify your provider supports this value.\n" }, { "id": "msg_warn_whisk_properties",