Skip to content

Commit

Permalink
Adds post regarding memory freezing
Browse files Browse the repository at this point in the history
* fix rubocop problems
* removes dead links
* Cuz apparently there's some CA issues on the build servers
  * See here: gjtorikian/html-proofer#194
  • Loading branch information
jtslear committed Nov 4, 2016
1 parent 5a2ebb1 commit be03c5d
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 10 deletions.
17 changes: 9 additions & 8 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,17 @@ end
task :serve do
Rake::Task['clean'].invoke
puts 'Building site...'.yellow.bold
sh "cp _config.yml _config_dev.yml"
sh "sed -i -dev -e 's/^url:/#url:/' _config_dev.yml"
sh "jekyll build --config _config_dev.yml"
sh 'cp _config.yml _config_dev.yml'
sh "sed -i -e 's/^url:/#url:/' _config_dev.yml"
sh 'jekyll build --config _config_dev.yml'
puts 'Begining to serve site...'.yellow.bold
begin
sh "jekyll serve --config _config_dev.yml"
sh 'jekyll serve --config _config_dev.yml'
rescue SystemExit, Interrupt
sh "rm -rf _config_dev.yml"
sh "rm -rf _config_dev.yml-dev"
sh 'rm -rf _config_dev.yml'
sh 'rm -rf _config_dev.yml-dev'
exit 0
rescue Exception => e
rescue StandardError => e
puts e
end
end
Expand All @@ -57,7 +57,8 @@ task :html_proofer do
'./_site',
allow_hash_href: true,
url_ignore: [host_regex],
file_ignore: ['^vendor/.*']
file_ignore: ['^vendor/.*'],
only_4xx: true
).run
end

Expand Down
1 change: 0 additions & 1 deletion _posts/2013-03-22-tmux-compile-failure.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,3 @@ Resources:

* [Tmux at SourceForge](https://tmux.github.io/)
* [libevent](http://libevent.org/)
* [libevent-2.0.so.5: cannot open shared object file: No such file or directory](http://www.nigeldunn.com/2011/12/11/libevent-2-0-so-5-cannot-open-shared-object-file-no-such-file-or-directory/)
1 change: 0 additions & 1 deletion _posts/2013-06-06-restricting-sudo-access.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ visudo is very powerful and if not done properly it can break sudo or provide un

* [sudo...sudoers](http://www.sudo.ws/sudoers.man.html)
* [serverfault...how-to-disable-sudoer-from-editing-etc-sudoers-file](http://serverfault.com/questions/308198/how-to-disable-sudoer-from-editing-etc-sudoers-file)
* [nixcraft...sudo-exclude-commands-disable-sudo-su-bash-shell](http://nixcraft.com/networking-firewalls-security/15132-sudo-exclude-commands-disable-sudo-su-bash-shell.html)

### Side Bar:
A sudoer still has the capability to compile or rpm a different shell.  From which gets around this entire setup.  Darn.
Expand Down
113 changes: 113 additions & 0 deletions _posts/2016-11-04-serverless-freeze-demonstration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
---
layout: dark-post
title: Demonstrating Memory Behavior for AWS Lambda Function Freezing
type: post
published: true
status: published
categories: []
tags:
- serverless
- aws
- lambda
- functions as a service
- faas
---

AWS indicates that when a function is executed, there are some things that get
leftover between runs. The execution environment, which AWS indicates is a
container model, contains everything necessary to run the function. After a
function is invoked for the first time, it will "freeze" this environment such
that it can quickly be called a second time, which will help improve the
performance of subsequent runs by avoiding the initialization step of getting
your code out into this execution environment. This container reuse, however,
can be a benefit or a downside depending on how you write your function. One of
these is related to the memory usage of an execution environment.

Say you have the following code:

```js
'use strict';

var arrayA = [];
var arrayB = [];

module.exports.test = (event, context, callback) => {
var arrayC = [];
var arrayD = [];

arrayA.push("A");
arrayB.push("B");
arrayC.push("C");
arrayD.push("D");

console.log("Array A:", arrayA);
console.log("Array B:", arrayB);
console.log("Array C:", arrayC);
console.log("Array D:", arrayD);

arrayA = [];
arrayC = [];

callback(null);
};
```

We initialize 2 empty arrays, arrayA and arrayB, outside of the handler. When the function
is run, these two arrays will remain in memory when the function is frozen.
Inside of the hander we've got 2 more empty arrays, arrayC and arrayD. During the
execution of the function we simply push a string item to it and for testing, we
clear our arrays arrayA and arrayC. Let's look at what this does when AWS invokes this
function three times:

```bash
serverless-freezing-demonstration % serverless invoke -f test -s dev -l
null
--------------------------------------------------------------------
START RequestId: 778bcf95-a285-11e6-aa5a Version: $LATEST
2016-11-04 07:54:40.248 778bcf95-a285-11e6-aa5a Array A: [ 'A' ]
2016-11-04 07:54:40.284 778bcf95-a285-11e6-aa5a Array B: [ 'B' ]
2016-11-04 07:54:40.284 778bcf95-a285-11e6-aa5a Array C: [ 'C' ]
2016-11-04 07:54:40.284 778bcf95-a285-11e6-aa5a Array D: [ 'D' ]
END RequestId: 778bcf95-a285-11e6-aa5a
REPORT RequestId: 778bcf95-a285-11e6-aa5a Duration: 37.54 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 14 MB

serverless-freezing-demonstration % serverless invoke -f test -s dev -l
null
--------------------------------------------------------------------
START RequestId: 7b760204-a285-11e6-bf4a Version: $LATEST
2016-11-04 07:54:46.714 7b760204-a285-11e6-bf4a Array A: [ 'A' ]
2016-11-04 07:54:46.714 7b760204-a285-11e6-bf4a Array B: [ 'B', 'B' ]
2016-11-04 07:54:46.714 7b760204-a285-11e6-bf4a Array C: [ 'C' ]
2016-11-04 07:54:46.714 7b760204-a285-11e6-bf4a Array D: [ 'D' ]
END RequestId: 7b760204-a285-11e6-bf4a
REPORT RequestId: 7b760204-a285-11e6-bf4a Duration: 0.68 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 14 MB

serverless-freezing-demonstration % serverless invoke -f test -s dev -l
null
--------------------------------------------------------------------
START RequestId: 7ecbbbed-a285-11e6-99ff Version: $LATEST
2016-11-04 07:54:52.288 7ecbbbed-a285-11e6-99ff Array A: [ 'A' ]
2016-11-04 07:54:52.289 7ecbbbed-a285-11e6-99ff Array B: [ 'B', 'B', 'B' ]
2016-11-04 07:54:52.289 7ecbbbed-a285-11e6-99ff Array C: [ 'C' ]
2016-11-04 07:54:52.289 7ecbbbed-a285-11e6-99ff Array D: [ 'D' ]
END RequestId: 7ecbbbed-a285-11e6-99ff
REPORT RequestId: 7ecbbbed-a285-11e6-99ff Duration: 0.52 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 14 MB
```
You'll notice in the first run, we have pushed one object to all four arrays. In
the second run, arrayB has a second object in the array, and in the third run, a
third object is added to arrayB. arrayA doesn't exhibit this behavior
because it is reinitialized to an empty array prior to stopping the function. arrayC and arrayD
technically get reinitialized at every run.

With this small demo, we can see some value and some potential headache when
created incorrectly. This could be a great strategy if we need to do
something expensive, such as setup a database connection. Inside of the
handler, we can call upon that object to reconnect to the database without
needing to go through the heavy lifting every single time.

To avoid leaking memory, we would want to ensure as much data as possible is
located within the handler to minimize problems.

### Recommended Reading:
* [How Does AWS Lambda Run My Code? The Container
Model](http://docs.aws.amazon.com/lambda/latest/dg/lambda-introduction-function.html#topic3)

0 comments on commit be03c5d

Please sign in to comment.