This post looks at how to apply probability to Lambda functions on AWS using version weighting. It’s a useful idea for any scenario that introduces random logic into a serverless set up.
Schrodinger’s cat is a feline of absolute probability. The cat is in an indeterminate state, both dead and alive, until an observation is made. It is part of a thought experiment designed to elucidate indeterminacy in quantum physics. For our purposes, all we need to consider is that the cat has two possible observed states. We can then model a serverless cat as follows…
Lambda is AWS’s serverless function service. You write the function, AWS takes care of the rest, provisioning a container-like structure in the background to initialize and run the function on demand.
This is a simple Lambda function written in NodeJS. The function handler takes an event property and simply responds with a report that the cat is alive. Every time this function is run, the cat lives. This function is called ‘Cat’
When we test it, we get this result:
Every time Lambda code is updated, it can be deployed as a specific version. So a function can leave a historic trail of snapshots of the stages it went through in development. Any of these snapshot versions can be called by applications. This makes it useful, for example, to have different versions of the same Lambda for production, testing and development. Snapshots are not editable. You can only edit the most recent Lambda code, which is indicted by the $LATEST parameter.
So we can take the function above and version it as follows:
This is ‘Cat:1’. It is a living version of ‘Cat’ which has been saved for posterity. Note the warning that it cannot be edited. We can also give this version an alias, so it is more than just a number
Now the version snapshot number one is called ‘CatDetermination’
With two versions of the same function we can add a percentage weighting: 50/50, 60/40 etc. on both, under a single version. Once we have done this, AWS will apply the percentage weighting and run one or other of the functions according the result. This is where we can introduce serverless indeterminacy.
So let’s got back to $LATEST and kill the cat this time:
Now we can publish a second version, a kind of cat memento mori:
And, as before, we can give this version and alias:
So now we have two versions of the same Lambda, one returning a cat which is alive, the other returning a dead cat.
We can set up the indeterminacy by editing the alias of our first function and pairing the second to it with version weighting set at 50:50 as follows:
So now our serverless cat is in a purely indeterminate state, both alive and dead, until an observation is made. AWS will load balance traffic between both versions of the cat function at 50/50 probability.
AWS advise that alias weighting in Lambda version configuration is useful for reducing risk by introducing low probability for new functionality. For example, splitting say 90%-10% between a stable old version and a new version will amount to producing a ‘soft’ release. This could be useful as a supplement to pure canary testing, where a defined set of users may have already tested the new version. The soft release could be added as part of a CI/CD regime for microservices. New functionality can be monitored and traffic increasingly routed to it as it is found to work.
More broadly, however, alias weighting also introduces probabilistic choice at the FaaS level in distributed systems. This introduces potential for designing distributed systems with probability at their core. For example, it would be possible use alias weighting in the design of a text-based adventure game, or in a randomized route generator for guided tours. In these cases, users of the same application can enjoy a different experience on each session.