Skip to content

Support lambdas which stream responses #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lambda-warmer/lambda/lambda.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ import path from 'path';
const require = topLevelCreateRequire(import.meta.url);
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
import{LambdaClient as f,InvokeCommand as v}from"@aws-sdk/client-lambda";import{TextDecoder as u}from"util";var g=new f({}),p=new u;async function I(d,a){if(a<=0)return new Set;console.log(`Firing a batch of ${a} concurrent invocations...`);let c=Array.from({length:a},()=>{let e=new v({FunctionName:d,Payload:JSON.stringify({action:"warmer"})});return g.send(e)}),i=await Promise.allSettled(c),n=new Set;return i.forEach(e=>{if(e.status==="fulfilled"&&e.value.Payload)try{let o=p.decode(e.value.Payload),t=JSON.parse(o);t.instanceId&&n.add(t.instanceId)}catch(o){console.error("Error parsing payload from target function:",o)}else e.status==="rejected"&&console.error("Invocation failed:",e.reason.message)}),n}var S=async d=>{let{lambdaName:a,numInstancesStr:c,maxWavesStr:i}={lambdaName:process.env.LAMBDA_NAME,numInstancesStr:process.env.NUM_INSTANCES,maxWavesStr:process.env.MAX_WAVES};if(!a||!c)throw new Error("Env vars 'LAMBDA_NAME' and 'NUM_INSTANCES' are required.");let n=parseInt(c,10),e=parseInt(i||"5",10),o=0,t=0,s=new Set;for(let r=1;r<=e;r++){if(t=r,n-s.size<=0){console.log("Target met. No more waves needed.");break}console.log(`--- Wave ${r} of ${e} ---`);let l=await I(a,n);o+=n,l.forEach(m=>s.add(m)),console.log(`Wave ${r} complete. Found ${s.size} of ${n} unique instances.`)}return console.log(`Warming complete. Found ${s.size} unique instances from ${o} total invocations over ${t} waves.`),{statusCode:200,body:JSON.stringify({targetInstances:n,warmedInstances:s.size,totalInvocations:o,wavesCompleted:t,instanceIds:[...s]})}};import.meta.url===`file://${process.argv[1]}`&&(process.env.LAMBDA_NAME="infra-core-api-lambda",process.env.NUM_INSTANCES="3",process.env.MAX_WAVES="3",console.log(await S({})));export{S as handler};
import{LambdaClient as g,InvokeCommand as v,InvokeWithResponseStreamCommand as I}from"@aws-sdk/client-lambda";import{TextDecoder as p}from"util";var m=new g({}),u=new p;async function y(a,t){let i=Array.from({length:t},()=>m.send(new v({FunctionName:a,Payload:JSON.stringify({action:"warmer"})}))),l=await Promise.allSettled(i),s=new Set;return l.forEach(e=>{if(e.status==="fulfilled"&&e.value.Payload)try{let n=u.decode(e.value.Payload),r=JSON.parse(n);r.instanceId&&s.add(r.instanceId)}catch(n){console.error("Error parsing payload from standard function:",n)}else e.status==="rejected"&&console.error("Standard invocation failed:",e.reason.message)}),s}async function N(a,t){let i=Array.from({length:t},()=>m.send(new I({FunctionName:a,Payload:JSON.stringify({action:"warmer"})}))),l=await Promise.allSettled(i),s=new Set;for(let e of l)if(e.status==="fulfilled"&&e.value.EventStream)try{let n=[];for await(let o of e.value.EventStream)o.PayloadChunk&&o.PayloadChunk.Payload&&n.push(o.PayloadChunk.Payload);let r=u.decode(Buffer.concat(n)),c=JSON.parse(r);c.instanceId&&s.add(c.instanceId)}catch(n){console.error("Error processing stream from streaming function:",n)}else e.status==="rejected"&&console.error("Streaming invocation failed:",e.reason.message);return s}var w=async a=>{let{lambdaName:t,numInstancesStr:i,maxWavesStr:l,isStreaming:s}={lambdaName:process.env.LAMBDA_NAME,numInstancesStr:process.env.NUM_INSTANCES,maxWavesStr:process.env.MAX_WAVES,isStreaming:(process.env.IS_STREAMING||"false").toLowerCase()==="true"};if(!t||!i)throw new Error("Env vars 'LAMBDA_NAME' and 'NUM_INSTANCES' are required.");let e=parseInt(i,10),n=parseInt(l||"5",10),r=0,c=0,o=new Set;console.log(`Warming target: ${t} (Streaming: ${s})`);for(let d=1;d<=n;d++){if(c=d,e-o.size<=0){console.log("Target met. No more waves needed.");break}console.log(`-- - Wave ${d} of ${n} --- `);let f=s?await N(t,e):await y(t,e);r+=e,f.forEach(S=>o.add(S)),console.log(`Wave ${d} complete.Found ${o.size} of ${e} unique instances.`)}return console.log(`Warming complete.Found ${o.size} unique instances from ${r} total invocations over ${c} waves.`),{statusCode:200,body:JSON.stringify({targetInstances:e,warmedInstances:o.size,totalInvocations:r,wavesCompleted:c,instanceIds:[...o]})}};import.meta.url===`file://${process.argv[1]}`&&(process.env.LAMBDA_NAME="my-target-lambda-function-name",process.env.NUM_INSTANCES="3",process.env.MAX_WAVES="5",process.env.IS_STREAMING="false",console.log("Running warmer in local test mode..."),w({}).then(a=>{console.log(`
--- Final Result ---`),console.log(JSON.parse(a.body))}).catch(a=>{console.error("Local test run failed:",a)}));export{w as handler};
//# sourceMappingURL=lambda.mjs.map
6 changes: 3 additions & 3 deletions lambda-warmer/lambda/lambda.mjs.map
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"version": 3,
"sources": ["../../src/api/warmer/lambda.ts"],
"sourcesContent": ["import { LambdaClient, InvokeCommand } from \"@aws-sdk/client-lambda\";\nimport { TextDecoder } from \"util\";\n\nconst lambdaClient = new LambdaClient({});\nconst textDecoder = new TextDecoder();\n\n/**\n * Invokes a batch of lambdas concurrently and returns the unique instance IDs found.\n */\nasync function invokeBatch(\n lambdaName: string,\n count: number,\n): Promise<Set<string>> {\n if (count <= 0) {\n return new Set();\n }\n\n console.log(`Firing a batch of ${count} concurrent invocations...`);\n\n const invocationPromises = Array.from({ length: count }, () => {\n const command = new InvokeCommand({\n FunctionName: lambdaName,\n Payload: JSON.stringify({ action: \"warmer\" }),\n });\n return lambdaClient.send(command);\n });\n\n const results = await Promise.allSettled(invocationPromises);\n const foundInstanceIds = new Set<string>();\n\n results.forEach((result) => {\n if (result.status === \"fulfilled\" && result.value.Payload) {\n try {\n const payloadString = textDecoder.decode(result.value.Payload);\n const body = JSON.parse(payloadString);\n if (body.instanceId) {\n foundInstanceIds.add(body.instanceId);\n }\n } catch (e) {\n console.error(\"Error parsing payload from target function:\", e);\n }\n } else if (result.status === \"rejected\") {\n console.error(\"Invocation failed:\", result.reason.message);\n }\n });\n\n return foundInstanceIds;\n}\n\nexport const handler = async (event: {}) => {\n const { lambdaName, numInstancesStr, maxWavesStr } = {\n lambdaName: process.env.LAMBDA_NAME,\n numInstancesStr: process.env.NUM_INSTANCES,\n maxWavesStr: process.env.MAX_WAVES,\n };\n\n if (!lambdaName || !numInstancesStr) {\n throw new Error(\"Env vars 'LAMBDA_NAME' and 'NUM_INSTANCES' are required.\");\n }\n\n const numInstances = parseInt(numInstancesStr, 10);\n // Default to 5 waves if MAX_WAVES is not set\n const maxWaves = parseInt(maxWavesStr || \"5\", 10);\n\n let totalInvocations = 0;\n let wavesCompleted = 0;\n const uniqueInstanceIds = new Set<string>();\n\n for (let i = 1; i <= maxWaves; i++) {\n wavesCompleted = i;\n\n // Calculate how many more instances are needed\n const neededCount = numInstances - uniqueInstanceIds.size;\n if (neededCount <= 0) {\n console.log(\"Target met. No more waves needed.\");\n break;\n }\n\n console.log(`--- Wave ${i} of ${maxWaves} ---`);\n const newIds = await invokeBatch(lambdaName, numInstances);\n totalInvocations += numInstances;\n\n newIds.forEach((id) => uniqueInstanceIds.add(id));\n\n console.log(\n `Wave ${i} complete. Found ${uniqueInstanceIds.size} of ${numInstances} unique instances.`,\n );\n }\n\n console.log(\n `Warming complete. Found ${uniqueInstanceIds.size} unique instances from ${totalInvocations} total invocations over ${wavesCompleted} waves.`,\n );\n\n return {\n statusCode: 200,\n body: JSON.stringify({\n targetInstances: numInstances,\n warmedInstances: uniqueInstanceIds.size,\n totalInvocations,\n wavesCompleted,\n instanceIds: [...uniqueInstanceIds],\n }),\n };\n};\n\nif (import.meta.url === `file://${process.argv[1]}`) {\n process.env.LAMBDA_NAME = \"infra-core-api-lambda\";\n process.env.NUM_INSTANCES = \"3\";\n process.env.MAX_WAVES = \"3\"; // Configurable number of waves\n console.log(await handler({}));\n}\n"],
"mappings": ";;;;;;AAAA,OAAS,gBAAAA,EAAc,iBAAAC,MAAqB,yBAC5C,OAAS,eAAAC,MAAmB,OAE5B,IAAMC,EAAe,IAAIH,EAAa,CAAC,CAAC,EAClCI,EAAc,IAAIF,EAKxB,eAAeG,EACbC,EACAC,EACsB,CACtB,GAAIA,GAAS,EACX,OAAO,IAAI,IAGb,QAAQ,IAAI,qBAAqBA,CAAK,4BAA4B,EAElE,IAAMC,EAAqB,MAAM,KAAK,CAAE,OAAQD,CAAM,EAAG,IAAM,CAC7D,IAAME,EAAU,IAAIR,EAAc,CAChC,aAAcK,EACd,QAAS,KAAK,UAAU,CAAE,OAAQ,QAAS,CAAC,CAC9C,CAAC,EACD,OAAOH,EAAa,KAAKM,CAAO,CAClC,CAAC,EAEKC,EAAU,MAAM,QAAQ,WAAWF,CAAkB,EACrDG,EAAmB,IAAI,IAE7B,OAAAD,EAAQ,QAASE,GAAW,CAC1B,GAAIA,EAAO,SAAW,aAAeA,EAAO,MAAM,QAChD,GAAI,CACF,IAAMC,EAAgBT,EAAY,OAAOQ,EAAO,MAAM,OAAO,EACvDE,EAAO,KAAK,MAAMD,CAAa,EACjCC,EAAK,YACPH,EAAiB,IAAIG,EAAK,UAAU,CAExC,OAASC,EAAG,CACV,QAAQ,MAAM,8CAA+CA,CAAC,CAChE,MACSH,EAAO,SAAW,YAC3B,QAAQ,MAAM,qBAAsBA,EAAO,OAAO,OAAO,CAE7D,CAAC,EAEMD,CACT,CAEO,IAAMK,EAAU,MAAOC,GAAc,CAC1C,GAAM,CAAE,WAAAX,EAAY,gBAAAY,EAAiB,YAAAC,CAAY,EAAI,CACnD,WAAY,QAAQ,IAAI,YACxB,gBAAiB,QAAQ,IAAI,cAC7B,YAAa,QAAQ,IAAI,SAC3B,EAEA,GAAI,CAACb,GAAc,CAACY,EAClB,MAAM,IAAI,MAAM,0DAA0D,EAG5E,IAAME,EAAe,SAASF,EAAiB,EAAE,EAE3CG,EAAW,SAASF,GAAe,IAAK,EAAE,EAE5CG,EAAmB,EACnBC,EAAiB,EACfC,EAAoB,IAAI,IAE9B,QAASC,EAAI,EAAGA,GAAKJ,EAAUI,IAAK,CAKlC,GAJAF,EAAiBE,EAGGL,EAAeI,EAAkB,MAClC,EAAG,CACpB,QAAQ,IAAI,mCAAmC,EAC/C,KACF,CAEA,QAAQ,IAAI,YAAYC,CAAC,OAAOJ,CAAQ,MAAM,EAC9C,IAAMK,EAAS,MAAMrB,EAAYC,EAAYc,CAAY,EACzDE,GAAoBF,EAEpBM,EAAO,QAASC,GAAOH,EAAkB,IAAIG,CAAE,CAAC,EAEhD,QAAQ,IACN,QAAQF,CAAC,oBAAoBD,EAAkB,IAAI,OAAOJ,CAAY,oBACxE,CACF,CAEA,eAAQ,IACN,2BAA2BI,EAAkB,IAAI,0BAA0BF,CAAgB,2BAA2BC,CAAc,SACtI,EAEO,CACL,WAAY,IACZ,KAAM,KAAK,UAAU,CACnB,gBAAiBH,EACjB,gBAAiBI,EAAkB,KACnC,iBAAAF,EACA,eAAAC,EACA,YAAa,CAAC,GAAGC,CAAiB,CACpC,CAAC,CACH,CACF,EAEI,YAAY,MAAQ,UAAU,QAAQ,KAAK,CAAC,CAAC,KAC/C,QAAQ,IAAI,YAAc,wBAC1B,QAAQ,IAAI,cAAgB,IAC5B,QAAQ,IAAI,UAAY,IACxB,QAAQ,IAAI,MAAMR,EAAQ,CAAC,CAAC,CAAC",
"names": ["LambdaClient", "InvokeCommand", "TextDecoder", "lambdaClient", "textDecoder", "invokeBatch", "lambdaName", "count", "invocationPromises", "command", "results", "foundInstanceIds", "result", "payloadString", "body", "e", "handler", "event", "numInstancesStr", "maxWavesStr", "numInstances", "maxWaves", "totalInvocations", "wavesCompleted", "uniqueInstanceIds", "i", "newIds", "id"]
"sourcesContent": ["import {\n LambdaClient,\n InvokeCommand,\n InvokeWithResponseStreamCommand,\n} from \"@aws-sdk/client-lambda\";\nimport { TextDecoder } from \"util\";\n\n// --- AWS SDK Clients and Utilities ---\nconst lambdaClient = new LambdaClient({});\nconst textDecoder = new TextDecoder();\n\n// --- Invocation Logic for Standard Lambdas ---\n\n/**\n * Invokes a batch of standard (non-streaming) Lambdas concurrently.\n */\nasync function invokeStandardBatch(\n lambdaName: string,\n count: number,\n): Promise<Set<string>> {\n const invocationPromises = Array.from({ length: count }, () =>\n lambdaClient.send(\n new InvokeCommand({\n FunctionName: lambdaName,\n Payload: JSON.stringify({ action: \"warmer\" }),\n }),\n ),\n );\n\n const results = await Promise.allSettled(invocationPromises);\n const foundInstanceIds = new Set<string>();\n\n results.forEach((result) => {\n if (result.status === \"fulfilled\" && result.value.Payload) {\n try {\n const payloadString = textDecoder.decode(result.value.Payload);\n const body = JSON.parse(payloadString);\n if (body.instanceId) {\n foundInstanceIds.add(body.instanceId);\n }\n } catch (e) {\n console.error(\"Error parsing payload from standard function:\", e);\n }\n } else if (result.status === \"rejected\") {\n console.error(\"Standard invocation failed:\", result.reason.message);\n }\n });\n\n return foundInstanceIds;\n}\n\n// --- Invocation Logic for Streaming Lambdas ---\n\n/**\n * Invokes a batch of response-streaming Lambdas concurrently.\n */\nasync function invokeStreamingBatch(\n lambdaName: string,\n count: number,\n): Promise<Set<string>> {\n const invocationPromises = Array.from({ length: count }, () =>\n lambdaClient.send(\n new InvokeWithResponseStreamCommand({\n FunctionName: lambdaName,\n Payload: JSON.stringify({ action: \"warmer\" }),\n }),\n ),\n );\n\n const results = await Promise.allSettled(invocationPromises);\n const foundInstanceIds = new Set<string>();\n\n for (const result of results) {\n if (result.status === \"fulfilled\" && result.value.EventStream) {\n try {\n const chunks: Uint8Array[] = [];\n // Iterate over the EventStream to get data chunks\n for await (const event of result.value.EventStream) {\n if (event.PayloadChunk && event.PayloadChunk.Payload) {\n chunks.push(event.PayloadChunk.Payload);\n }\n }\n\n const payloadString = textDecoder.decode(Buffer.concat(chunks));\n const body = JSON.parse(payloadString);\n if (body.instanceId) {\n foundInstanceIds.add(body.instanceId);\n }\n } catch (e) {\n console.error(\"Error processing stream from streaming function:\", e);\n }\n } else if (result.status === \"rejected\") {\n console.error(\"Streaming invocation failed:\", result.reason.message);\n }\n }\n\n return foundInstanceIds;\n}\n\n// --- Main Lambda Handler ---\n\n/**\n * Main handler that warms a target Lambda function by invoking it multiple times.\n * It can handle both standard and response-streaming target functions.\n */\nexport const handler = async (event: {}) => {\n const { lambdaName, numInstancesStr, maxWavesStr, isStreaming } = {\n lambdaName: process.env.LAMBDA_NAME,\n numInstancesStr: process.env.NUM_INSTANCES,\n maxWavesStr: process.env.MAX_WAVES,\n isStreaming: (process.env.IS_STREAMING || \"false\").toLowerCase() === \"true\", // e.g., 'true' or 'false'\n };\n\n if (!lambdaName || !numInstancesStr) {\n throw new Error(\"Env vars 'LAMBDA_NAME' and 'NUM_INSTANCES' are required.\");\n }\n\n const numInstances = parseInt(numInstancesStr, 10);\n const maxWaves = parseInt(maxWavesStr || \"5\", 10);\n\n let totalInvocations = 0;\n let wavesCompleted = 0;\n const uniqueInstanceIds = new Set<string>();\n\n console.log(`Warming target: ${lambdaName} (Streaming: ${isStreaming})`);\n\n for (let i = 1; i <= maxWaves; i++) {\n wavesCompleted = i;\n const neededCount = numInstances - uniqueInstanceIds.size;\n if (neededCount <= 0) {\n console.log(\"Target met. No more waves needed.\");\n break;\n }\n\n console.log(`-- - Wave ${i} of ${maxWaves} --- `);\n\n // Choose the correct invoker function based on the flag\n const newIds = isStreaming\n ? await invokeStreamingBatch(lambdaName, numInstances)\n : await invokeStandardBatch(lambdaName, numInstances);\n\n totalInvocations += numInstances;\n\n newIds.forEach((id) => uniqueInstanceIds.add(id));\n\n console.log(\n `Wave ${i} complete.Found ${uniqueInstanceIds.size} of ${numInstances} unique instances.`,\n );\n }\n\n console.log(\n `Warming complete.Found ${uniqueInstanceIds.size} unique instances from ${totalInvocations} total invocations over ${wavesCompleted} waves.`,\n );\n\n return {\n statusCode: 200,\n body: JSON.stringify({\n targetInstances: numInstances,\n warmedInstances: uniqueInstanceIds.size,\n totalInvocations,\n wavesCompleted,\n instanceIds: [...uniqueInstanceIds],\n }),\n };\n};\n\n// --- Local Test Execution Block ---\n\n// This block runs only when the file is executed directly (e.g., `node index.js`)\nif (import.meta.url === `file://${process.argv[1]}`) {\n // --- Configuration for local testing ---\n process.env.LAMBDA_NAME = \"my-target-lambda-function-name\";\n process.env.NUM_INSTANCES = \"3\";\n process.env.MAX_WAVES = \"5\";\n process.env.IS_STREAMING = \"false\"; // Set to 'true' to test streaming\n\n console.log(\"Running warmer in local test mode...\");\n handler({}).then(result => {\n console.log(\"\\n--- Final Result ---\");\n console.log(JSON.parse(result.body));\n }).catch(error => {\n console.error(\"Local test run failed:\", error);\n });\n}\n"],
"mappings": ";;;;;;AAAA,OACE,gBAAAA,EACA,iBAAAC,EACA,mCAAAC,MACK,yBACP,OAAS,eAAAC,MAAmB,OAG5B,IAAMC,EAAe,IAAIJ,EAAa,CAAC,CAAC,EAClCK,EAAc,IAAIF,EAOxB,eAAeG,EACbC,EACAC,EACsB,CACtB,IAAMC,EAAqB,MAAM,KAAK,CAAE,OAAQD,CAAM,EAAG,IACvDJ,EAAa,KACX,IAAIH,EAAc,CAChB,aAAcM,EACd,QAAS,KAAK,UAAU,CAAE,OAAQ,QAAS,CAAC,CAC9C,CAAC,CACH,CACF,EAEMG,EAAU,MAAM,QAAQ,WAAWD,CAAkB,EACrDE,EAAmB,IAAI,IAE7B,OAAAD,EAAQ,QAASE,GAAW,CAC1B,GAAIA,EAAO,SAAW,aAAeA,EAAO,MAAM,QAChD,GAAI,CACF,IAAMC,EAAgBR,EAAY,OAAOO,EAAO,MAAM,OAAO,EACvDE,EAAO,KAAK,MAAMD,CAAa,EACjCC,EAAK,YACPH,EAAiB,IAAIG,EAAK,UAAU,CAExC,OAASC,EAAG,CACV,QAAQ,MAAM,gDAAiDA,CAAC,CAClE,MACSH,EAAO,SAAW,YAC3B,QAAQ,MAAM,8BAA+BA,EAAO,OAAO,OAAO,CAEtE,CAAC,EAEMD,CACT,CAOA,eAAeK,EACbT,EACAC,EACsB,CACtB,IAAMC,EAAqB,MAAM,KAAK,CAAE,OAAQD,CAAM,EAAG,IACvDJ,EAAa,KACX,IAAIF,EAAgC,CAClC,aAAcK,EACd,QAAS,KAAK,UAAU,CAAE,OAAQ,QAAS,CAAC,CAC9C,CAAC,CACH,CACF,EAEMG,EAAU,MAAM,QAAQ,WAAWD,CAAkB,EACrDE,EAAmB,IAAI,IAE7B,QAAWC,KAAUF,EACnB,GAAIE,EAAO,SAAW,aAAeA,EAAO,MAAM,YAChD,GAAI,CACF,IAAMK,EAAuB,CAAC,EAE9B,cAAiBC,KAASN,EAAO,MAAM,YACjCM,EAAM,cAAgBA,EAAM,aAAa,SAC3CD,EAAO,KAAKC,EAAM,aAAa,OAAO,EAI1C,IAAML,EAAgBR,EAAY,OAAO,OAAO,OAAOY,CAAM,CAAC,EACxDH,EAAO,KAAK,MAAMD,CAAa,EACjCC,EAAK,YACPH,EAAiB,IAAIG,EAAK,UAAU,CAExC,OAASC,EAAG,CACV,QAAQ,MAAM,mDAAoDA,CAAC,CACrE,MACSH,EAAO,SAAW,YAC3B,QAAQ,MAAM,+BAAgCA,EAAO,OAAO,OAAO,EAIvE,OAAOD,CACT,CAQO,IAAMQ,EAAU,MAAOD,GAAc,CAC1C,GAAM,CAAE,WAAAX,EAAY,gBAAAa,EAAiB,YAAAC,EAAa,YAAAC,CAAY,EAAI,CAChE,WAAY,QAAQ,IAAI,YACxB,gBAAiB,QAAQ,IAAI,cAC7B,YAAa,QAAQ,IAAI,UACzB,aAAc,QAAQ,IAAI,cAAgB,SAAS,YAAY,IAAM,MACvE,EAEA,GAAI,CAACf,GAAc,CAACa,EAClB,MAAM,IAAI,MAAM,0DAA0D,EAG5E,IAAMG,EAAe,SAASH,EAAiB,EAAE,EAC3CI,EAAW,SAASH,GAAe,IAAK,EAAE,EAE5CI,EAAmB,EACnBC,EAAiB,EACfC,EAAoB,IAAI,IAE9B,QAAQ,IAAI,mBAAmBpB,CAAU,gBAAgBe,CAAW,GAAG,EAEvE,QAASM,EAAI,EAAGA,GAAKJ,EAAUI,IAAK,CAGlC,GAFAF,EAAiBE,EACGL,EAAeI,EAAkB,MAClC,EAAG,CACpB,QAAQ,IAAI,mCAAmC,EAC/C,KACF,CAEA,QAAQ,IAAI,aAAaC,CAAC,OAAOJ,CAAQ,OAAO,EAGhD,IAAMK,EAASP,EACX,MAAMN,EAAqBT,EAAYgB,CAAY,EACnD,MAAMjB,EAAoBC,EAAYgB,CAAY,EAEtDE,GAAoBF,EAEpBM,EAAO,QAASC,GAAOH,EAAkB,IAAIG,CAAE,CAAC,EAEhD,QAAQ,IACN,QAAQF,CAAC,mBAAmBD,EAAkB,IAAI,OAAOJ,CAAY,oBACvE,CACF,CAEA,eAAQ,IACN,0BAA0BI,EAAkB,IAAI,0BAA0BF,CAAgB,2BAA2BC,CAAc,SACrI,EAEO,CACL,WAAY,IACZ,KAAM,KAAK,UAAU,CACnB,gBAAiBH,EACjB,gBAAiBI,EAAkB,KACnC,iBAAAF,EACA,eAAAC,EACA,YAAa,CAAC,GAAGC,CAAiB,CACpC,CAAC,CACH,CACF,EAKI,YAAY,MAAQ,UAAU,QAAQ,KAAK,CAAC,CAAC,KAE/C,QAAQ,IAAI,YAAc,iCAC1B,QAAQ,IAAI,cAAgB,IAC5B,QAAQ,IAAI,UAAY,IACxB,QAAQ,IAAI,aAAe,QAE3B,QAAQ,IAAI,sCAAsC,EAClDR,EAAQ,CAAC,CAAC,EAAE,KAAKP,GAAU,CACzB,QAAQ,IAAI;AAAA,qBAAwB,EACpC,QAAQ,IAAI,KAAK,MAAMA,EAAO,IAAI,CAAC,CACrC,CAAC,EAAE,MAAMmB,GAAS,CAChB,QAAQ,MAAM,yBAA0BA,CAAK,CAC/C,CAAC",
"names": ["LambdaClient", "InvokeCommand", "InvokeWithResponseStreamCommand", "TextDecoder", "lambdaClient", "textDecoder", "invokeStandardBatch", "lambdaName", "count", "invocationPromises", "results", "foundInstanceIds", "result", "payloadString", "body", "e", "invokeStreamingBatch", "chunks", "event", "handler", "numInstancesStr", "maxWavesStr", "isStreaming", "numInstances", "maxWaves", "totalInvocations", "wavesCompleted", "uniqueInstanceIds", "i", "newIds", "id", "error"]
}
1 change: 1 addition & 0 deletions lambda-warmer/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ resource "aws_lambda_function" "warmer_function" {
variables = {
LAMBDA_NAME = var.function_to_warm
NUM_INSTANCES = var.num_desired_warm_instances
IS_STREAMING = tostring(var.is_streaming_lambda)
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions lambda-warmer/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ variable "invoke_rate_string" {
default = "rate(4 minutes)"
}

variable "is_streaming_lambda" {
type = bool
description = "Set to true if the lambda streams its responses instead of buffering. By default, Lambdas buffer responses."
default = false
}

variable "num_desired_warm_instances" {
type = number
Expand Down