Ruby SDK Version 2 and Memoization
Version 1 of the AWS SDK for Ruby (
aws-sdk gem) provides a higher-level abstraction for working with AWS resources. These resources can be used to get information about AWS objects and operate on them as well. For example:
AWS.ec2.instances.each do |i| puts i.instance_id + ' => ' + i.status.to_s end
The problem with the example above is if you do not enable memoization, it will make n + 1 requests to Amazon EC2. The first request retries a list of instances, and then it makes one more request per instance to fetch the status. An experienced AWS developer will know that all of this information can be retrieved in a single call to
DescribeInstances with Amazon EC2.
To address this issue, the v1 Ruby SDK introduced a feature called memoization which allows the SDK to used cached values inside a block.
# now only one request is made AWS.memoize do AWS.ec2.instances.each do |i| puts i.instance_id + ' => ' + i.status.to_s end end
For more background information you can read this blog post.
Memoization is Not Obvious
If you are unaware of this feature, your code will still execute, and will produce a correct response. Unfortunately, it is also likely that a large number of unnecessary requests will be made. These requests can significantly increase the execution time and can result in an account getting throttled. This usually results in a frustrating search for why extra requests are being made, which finally leads to
Memoization Removed in V2
In version 2 of the Ruby SDK (
aws-sdk-core gem), there is no
Aws.memoize method. Instead we chose a design that removes the need to provide this hook.
- Response objects have a
#dataattribute. Accessing response data will never trigger another request.
- The upcoming higher-level resource abstractions are also going to provide access to the data for a resource and an explicit
#refresh!method that will refresh the data on demand.
If you haven’t had a chance to take the version 2 Ruby SDK for a spin, I encourage you to try it out. It installs via a separate gem (
aws-sdk-core) and uses a separate namespace (
AWS) so that you can use it in the same process.
Also, please share any feedback or ideas!