AWS Developer Tools Blog

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 #memoize.

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 #data attribute. 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 vs. AWS) so that you can use it in the same process.

Also, please share any feedback or ideas!