Class: Jets::Preheat

Inherits:
Object
  • Object
show all
Extended by:
Memoist
Includes:
AwsServices
Defined in:
lib/jets/preheat.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from AwsServices

#apigateway, #aws_lambda, #aws_options, #cfn, #dynamodb, #logs, #s3, #s3_resource, #sns, #sqs, #sts

Methods included from AwsServices::StackStatus

#lookup, #stack_exists?, #stack_in_progress?

Methods included from AwsServices::GlobalMemoist

included

Constructor Details

#initialize(options) ⇒ Preheat

Returns a new instance of Preheat.



19
20
21
22
23
# File 'lib/jets/preheat.rb', line 19

def initialize(options)
  @options = options # passed to Call.new options
  @options[:mute_output] = true if @options[:mute_output].nil?
  @options[:lambda_proxy] = false # do not transform controller event from {"event": "1"} to {"queryStringParameters":{"_prewarm":"1"}}
end

Class Method Details

.warm(function_name, options = {}) ⇒ Object

Examples:

Jets::Preheat.warm("posts_controller-index")
Jets::Preheat.warm("jets-preheat_job-warm")


11
12
13
# File 'lib/jets/preheat.rb', line 11

def self.warm(function_name, options={})
  Preheat.new(options).warm(function_name)
end

.warm_all(options = {}) ⇒ Object



15
16
17
# File 'lib/jets/preheat.rb', line 15

def self.warm_all(options={})
  Preheat.new(options).warm_all
end

Instance Method Details

#all_functionsObject

Returns:

[
  "posts_controller-index",
  "posts_controller-show",
  ...
]


94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/jets/preheat.rb', line 94

def all_functions
  parent_stack = cfn.describe_stack_resources(stack_name: Jets::Names.parent_stack_name)
  parent_resources = parent_stack.stack_resources.select do |resource|
    resource.logical_resource_id =~ /Controller$/ # only controller functions
  end
  physical_resource_ids = parent_resources.map(&:physical_resource_id)
  resources = physical_resource_ids.inject([]) do |acc, physical_resource_id|
    stack_resources = cfn.describe_stack_resources(stack_name: physical_resource_id).stack_resources
    stack_resources.each do |stack_resource|
      acc << stack_resource if stack_resource.logical_resource_id.ends_with?('LambdaFunction') # only functions
    end
    acc
  end
  resources.map(&:physical_resource_id) # function names
end

#classesObject



111
112
113
114
115
116
117
118
119
120
121
# File 'lib/jets/preheat.rb', line 111

def classes
  Jets::Commands::Build.app_files.map do |path|
    next if path.include?("preheat_job.rb") # dont want to cause an infinite loop, just in case
    next unless path =~ %r{app/controllers} # only prewarm controllers

    class_path = path.sub(%r{.*app/\w+/},'').sub(/\.rb$/,'')
    class_name = class_path.camelize
    # IE: PostsController
    class_name.constantize # load app/**/* class definition
  end.compact
end

#warm(function_name) ⇒ Object

Makes remote call to the Lambda function.



26
27
28
# File 'lib/jets/preheat.rb', line 26

def warm(function_name)
  Jets::Commands::Call.new(function_name, '{"_prewarm": "1"}', @options).run unless Jets.env.test?
end

#warm_allObject

Loop through all methods for each class and makes special prewarm call to each method.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/jets/preheat.rb', line 31

def warm_all
  threads = []
  all_functions.each do |function_name|
    next if function_name.include?('jets-public_controller') # handled by warm_public_controller_more
    next if function_name.include?('jets-rack_controller') # handled by warm_rack_controller_more
    threads << Thread.new do
      warm(function_name)
    end
  end
  threads.each { |t| t.join }

  # Warm the these controllers more since they can be hit more often
  warm_public_controller_more
  warm_rack_controller_more

  # return the funciton names so we can see in the Lambda console
  # the functions being prewarmed
  all_functions
end

#warm_public_controller_moreObject



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/jets/preheat.rb', line 51

def warm_public_controller_more
  function_name = 'jets-public_controller-show' # key function name
  return unless all_functions.include?(function_name)

  public_ratio = Jets.config.prewarm.public_ratio
  return if public_ratio == 0

  puts "Prewarming the public controller extra at a ratio of #{public_ratio}" unless @options[:mute]

  threads = []
  public_ratio.times do
    threads << Thread.new do
      warm(function_name)
    end
  end
  threads.each { |t| t.join }
end

#warm_rack_controller_moreObject



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/jets/preheat.rb', line 69

def warm_rack_controller_more
  return unless Jets.rack?
  function_name = 'jets-rack_controller-process' # key function name
  return unless all_functions.include?(function_name)

  rack_ratio = Jets.config.prewarm.rack_ratio
  return if rack_ratio == 0

  puts "Prewarming the rack controller extra at a ratio of #{rack_ratio}" unless @options[:mute]

  threads = []
  rack_ratio.times do
    threads << Thread.new do
      warm(function_name)
    end
  end
  threads.each { |t| t.join }
end