From f78c33f0238c7e4ee3170d84d1dd1e6803d823a4 Mon Sep 17 00:00:00 2001 From: Joseph Lawson Date: Wed, 14 Mar 2018 18:25:09 -0400 Subject: [PATCH] implement callbackWaitsForEmptyEventLoop (#105) * implement callbackWaitsForEmptyEventLoop per https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html ## The Context Object Properties (Node.js) The context object provides the following property that you can update: *callbackWaitsForEmptyEventLoop* > The default value is true. This property is useful only to modify the default behavior of the callback. By default, the callback will wait until the Node.js runtime event loop is empty before freezing the process and returning the results to the caller. You can set this property to false to request AWS Lambda to freeze the process soon after the callback is called, even if there are events in the event loop. AWS Lambda will freeze the process, any state data and the events in the Node.js event loop (any remaining events in the event loop processed when the Lambda function is called next and if AWS Lambda chooses to use the frozen process). For more information about callback, see Using the Callback Parameter. * use compound names for callback wait property --- .../src-deps/cljs_lambda/externs/context.js | 1 + cljs-lambda/src/cljs_lambda/context.cljs | 28 +++++++++++++++++-- cljs-lambda/src/cljs_lambda/local.cljs | 6 +++- cljs-lambda/test/cljs_lambda/test/util.cljs | 18 ++++++++++++ 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/cljs-lambda/src-deps/cljs_lambda/externs/context.js b/cljs-lambda/src-deps/cljs_lambda/externs/context.js index 099af07..5a9e73c 100644 --- a/cljs-lambda/src-deps/cljs_lambda/externs/context.js +++ b/cljs-lambda/src-deps/cljs_lambda/externs/context.js @@ -5,6 +5,7 @@ context.clientContext; context.logGroupName; context.logStreamName; context.functionName; +context.callbackWaitsForEmptyEventLoop; context.getMemoryLimitInMB = function() {}; context.getFunctionName = function() {}; diff --git a/cljs-lambda/src/cljs_lambda/context.cljs b/cljs-lambda/src/cljs_lambda/context.cljs index 747cae5..bc15f4f 100644 --- a/cljs-lambda/src/cljs_lambda/context.cljs +++ b/cljs-lambda/src/cljs_lambda/context.cljs @@ -26,7 +26,17 @@ associated with this context.") (environment [this] - "Retrieve a map of environment variables.")) + "Retrieve a map of environment variables.") + (waits? + [this] + "By default, the callback will wait until the Node.js runtime event loop is + empty before freezing the process and returning the results to the caller. + You can set this property to false to request AWS Lambda to freeze the + process soon after the callback is called, even if there are events in the + event loop.") + (set-wait! + [this tf] + "Set the callback-waits")) (defrecord ^:no-doc LambdaContext [js-handle] ContextHandle @@ -35,7 +45,21 @@ (msecs-remaining [this] (.getRemainingTimeInMillis js-handle)) (environment [this] - (json->edn js/process.env))) + (json->edn js/process.env)) + (waits? [this] + (.-callbackWaitsForEmptyEventLoop js-handle)) + (set-wait! [this tf] + (set! (.-callbackWaitsForEmptyEventLoop js-handle) tf))) + +(defn waits-on-event-loop? + [ctx] + "Returns state of context property callbackWaitsForEmptyEventLoop" + (waits? ctx)) + +(defn set-wait-on-event-loop! + "Set the context property callbackWaitsForEmptyEventLoop" + [ctx tf] + (set-wait! ctx tf)) (defn env "Retrieve an environment variable by name, defaulting to `nil` if not found. diff --git a/cljs-lambda/src/cljs_lambda/local.cljs b/cljs-lambda/src/cljs_lambda/local.cljs index 89f59ca..97522b2 100644 --- a/cljs-lambda/src/cljs_lambda/local.cljs +++ b/cljs-lambda/src/cljs_lambda/local.cljs @@ -16,7 +16,11 @@ (msecs-remaining [this] -1) (environment [this] - env)) + env) + (waits? [this] + true) + (set-wait! [this tf] + tf)) (defn- stringify-keys "Shallowly un-keyword/un-symbol the keys in m" diff --git a/cljs-lambda/test/cljs_lambda/test/util.cljs b/cljs-lambda/test/cljs_lambda/test/util.cljs index cd80db6..78e8536 100644 --- a/cljs-lambda/test/cljs_lambda/test/util.cljs +++ b/cljs-lambda/test/cljs_lambda/test/util.cljs @@ -143,3 +143,21 @@ ctx (local/->context {:env {'ENV_VAR "deftest-async env"}})] (p/then (invoke f nil ctx) (will= "deftest-async env")))) + +(deftest-async + waits + (let [f (lambda/async-lambda-fn + (fn [_ ctx] + (ctx/waits-on-event-loop? ctx)))] + (p/then + (invoke f) + (will= true)))) + +(deftest-async + set-waits + (let [f (lambda/async-lambda-fn + (fn [_ ctx] + (ctx/set-wait-on-event-loop! ctx false)))] + (p/then + (invoke f) + (will= false))))