forked from rubyonjets/jets
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request rubyonjets#206 from tongueroo/global-memoist
cache aws service clients globally for lambda performance
- Loading branch information
Showing
2 changed files
with
70 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# We cache the clients globally to avoid re-instantiating them again after the initial Lambda cold start. | ||
# | ||
# Based on: https://hashrocket.com/blog/posts/implementing-a-macro-in-ruby-for-memoization | ||
# Except we use a global variable for the cache. So we'll use the same client across | ||
# all instances as well as across Lambda executions after the cold-start. Example: | ||
# | ||
# class Foo | ||
# def s3 | ||
# Aws::S3::Client.new | ||
# end | ||
# global_memoize :s3 | ||
# end | ||
# | ||
# foo1 = Foo.new | ||
# foo2 = Foo.new | ||
# foo1.s3 | ||
# foo2.s3 # same client as foo1 | ||
# | ||
# A prewarmed request after a cold-start will still use the same s3 client instance since it uses the | ||
# global variable $__memo_methods as the cache. | ||
# | ||
module Jets::AwsServices | ||
module GlobalMemoist | ||
def self.included(klass) | ||
klass.extend(Macros) | ||
end | ||
|
||
module Macros | ||
def global_memoize(*methods) | ||
const_defined?(:"GlobalMemoist#{self.object_id}") ? | ||
const_get(:"GlobalMemoist#{self.object_id}") : const_set(:"GlobalMemoist#{self.object_id}", Module.new) | ||
mod = const_get(:"GlobalMemoist#{self.object_id}") | ||
|
||
mod.class_eval do | ||
methods.each do |method| | ||
define_method(method) do |skip_cache = false| | ||
$__memo_methods ||= {} | ||
if $__memo_methods.include?(method) && !skip_cache | ||
$__memo_methods[method] | ||
else | ||
$__memo_methods[method] = super() | ||
end | ||
end | ||
end | ||
end | ||
prepend mod | ||
end | ||
|
||
def global_memoize_class_method(*methods) | ||
singleton_class.class_eval do | ||
include GlobalMemoist | ||
global_memoize(*methods) | ||
end | ||
end | ||
end | ||
end | ||
end |