funktor 0.4.7 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/.tool-versions +2 -0
  3. data/Gemfile.lock +7 -3
  4. data/funktor-testapp/.envrc +1 -0
  5. data/funktor-testapp/.gitignore +7 -0
  6. data/funktor-testapp/Gemfile +25 -0
  7. data/funktor-testapp/Gemfile.lock +51 -0
  8. data/funktor-testapp/app/services/job_flood.rb +38 -0
  9. data/funktor-testapp/app/workers/audit_worker.rb +49 -0
  10. data/funktor-testapp/app/workers/greetings_worker.rb +3 -0
  11. data/funktor-testapp/app/workers/hello_worker.rb +18 -0
  12. data/funktor-testapp/deploy-dev.sh +5 -0
  13. data/funktor-testapp/funktor_config/boot.rb +17 -0
  14. data/funktor-testapp/funktor_config/environment.yml +15 -0
  15. data/funktor-testapp/funktor_config/function_definitions/default_queue_handler.yml +11 -0
  16. data/funktor-testapp/funktor_config/function_definitions/incoming_job_handler.yml +11 -0
  17. data/funktor-testapp/funktor_config/function_definitions/job_activator.yml +8 -0
  18. data/funktor-testapp/funktor_config/function_definitions/random_job_generator.yml +18 -0
  19. data/funktor-testapp/funktor_config/function_definitions/single_thread_queue_handler.yml +11 -0
  20. data/funktor-testapp/funktor_config/funktor.yml +114 -0
  21. data/funktor-testapp/funktor_config/iam_permissions/activity_table.yml +5 -0
  22. data/funktor-testapp/funktor_config/iam_permissions/default_queue.yml +8 -0
  23. data/funktor-testapp/funktor_config/iam_permissions/incoming_job_queue.yml +8 -0
  24. data/funktor-testapp/funktor_config/iam_permissions/jobs_table.yml +5 -0
  25. data/funktor-testapp/funktor_config/iam_permissions/jobs_table_secondary_index.yml +8 -0
  26. data/funktor-testapp/funktor_config/iam_permissions/single_thread_queue.yml +8 -0
  27. data/funktor-testapp/funktor_config/iam_permissions/ssm.yml +5 -0
  28. data/funktor-testapp/funktor_config/package.yml +11 -0
  29. data/funktor-testapp/funktor_config/resources/activity_table.yml +22 -0
  30. data/funktor-testapp/funktor_config/resources/cloudwatch_dashboard.yml +804 -0
  31. data/funktor-testapp/funktor_config/resources/default_queue.yml +22 -0
  32. data/funktor-testapp/funktor_config/resources/incoming_job_queue.yml +22 -0
  33. data/funktor-testapp/funktor_config/resources/incoming_job_queue_user.yml +26 -0
  34. data/funktor-testapp/funktor_config/resources/jobs_table.yml +44 -0
  35. data/funktor-testapp/funktor_config/resources/single_thread_queue.yml +22 -0
  36. data/funktor-testapp/funktor_config/ruby_layer.yml +11 -0
  37. data/funktor-testapp/funktor_init.yml +61 -0
  38. data/funktor-testapp/lambda_event_handlers/default_queue_handler.rb +8 -0
  39. data/funktor-testapp/lambda_event_handlers/incoming_job_handler.rb +8 -0
  40. data/funktor-testapp/lambda_event_handlers/job_activator.rb +8 -0
  41. data/funktor-testapp/lambda_event_handlers/random_job_generator.rb +35 -0
  42. data/funktor-testapp/lambda_event_handlers/single_thread_queue_handler.rb +8 -0
  43. data/funktor-testapp/package-lock.json +248 -0
  44. data/funktor-testapp/package.json +8 -0
  45. data/funktor-testapp/serverless.yml +65 -0
  46. data/funktor.gemspec +1 -0
  47. data/lib/active_job/queue_adapters/funktor_adapter.rb +3 -3
  48. data/lib/funktor.rb +39 -7
  49. data/lib/funktor/activity_tracker.rb +102 -0
  50. data/lib/funktor/cli/bootstrap.rb +0 -1
  51. data/lib/funktor/cli/init.rb +13 -0
  52. data/lib/funktor/cli/templates/app/workers/hello_worker.rb +1 -1
  53. data/lib/funktor/cli/templates/funktor_config/environment.yml +4 -0
  54. data/lib/funktor/cli/templates/funktor_config/function_definitions/job_activator.yml +8 -0
  55. data/lib/funktor/cli/templates/funktor_config/funktor.yml +28 -2
  56. data/lib/funktor/cli/templates/funktor_config/iam_permissions/activity_table.yml +5 -0
  57. data/lib/funktor/cli/templates/funktor_config/iam_permissions/jobs_table.yml +5 -0
  58. data/lib/funktor/cli/templates/funktor_config/iam_permissions/jobs_table_secondary_index.yml +8 -0
  59. data/lib/funktor/cli/templates/funktor_config/resources/activity_table.yml +22 -0
  60. data/lib/funktor/cli/templates/funktor_config/resources/cloudwatch_dashboard.yml +10 -10
  61. data/lib/funktor/cli/templates/funktor_config/resources/jobs_table.yml +44 -0
  62. data/lib/funktor/cli/templates/funktor_init.yml.tt +2 -8
  63. data/lib/funktor/cli/templates/lambda_event_handlers/job_activator.rb +8 -0
  64. data/lib/funktor/cli/templates/lambda_event_handlers/work_queue_handler.rb +1 -1
  65. data/lib/funktor/cli/templates/serverless.yml +2 -2
  66. data/lib/funktor/counter.rb +4 -1
  67. data/lib/funktor/incoming_job_handler.rb +52 -12
  68. data/lib/funktor/job.rb +10 -5
  69. data/lib/funktor/job_activator.rb +98 -0
  70. data/lib/funktor/job_pusher.rb +0 -2
  71. data/lib/funktor/middleware/metrics.rb +8 -3
  72. data/lib/funktor/testing.rb +49 -47
  73. data/lib/funktor/version.rb +1 -1
  74. data/lib/funktor/{active_job_handler.rb → work_queue_handler.rb} +17 -15
  75. data/lib/funktor/worker.rb +0 -7
  76. metadata +69 -3
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "funktor-testapp",
3
+ "description": "",
4
+ "version": "0.1.0",
5
+ "devDependencies": {
6
+ "serverless-ruby-layer": "^1.4.0"
7
+ }
8
+ }
@@ -0,0 +1,65 @@
1
+ # Welcome to Funktor & Serverless!
2
+ #
3
+ # This file is the main config file for your service.
4
+ # It's already configured to run Funktor, you just have to deploy it.
5
+ #
6
+ # For more info about Funktor check the wiki:
7
+ # https://github.com/Octo-Labs/funktor/wiki
8
+ #
9
+ # For more about serverless, check their docs:
10
+ # docs.serverless.com
11
+ #
12
+ # Happy Coding!
13
+
14
+ # The name of your service. All your AWS resources will contain this name.
15
+ service: funktor-testapp
16
+
17
+ # This causes serverless to throw an error early if the config is bad, instead of waiting for CloudFormation to try and fail to deploy it.
18
+ configValidationMode: error
19
+
20
+ # Pin the serverless framework to the 2.x line
21
+ frameworkVersion: '2'
22
+
23
+ provider:
24
+ name: aws
25
+ runtime: ruby2.7
26
+ lambdaHashingVersion: 20201221
27
+ environment: ${file(funktor_config/environment.yml)}
28
+ versionFunctions: false # Reduces the amount of storage used since all Lambdas together are limited to 75GB
29
+ iamRoleStatements:
30
+ - ${file(funktor_config/iam_permissions/activity_table.yml)}
31
+ - ${file(funktor_config/iam_permissions/default_queue.yml)}
32
+ - ${file(funktor_config/iam_permissions/incoming_job_queue.yml)}
33
+ - ${file(funktor_config/iam_permissions/ssm.yml)}
34
+ - ${file(funktor_config/iam_permissions/single_thread_queue.yml)}
35
+ - ${file(funktor_config/iam_permissions/jobs_table.yml)}
36
+ - ${file(funktor_config/iam_permissions/jobs_table_secondary_index.yml)}
37
+
38
+
39
+ custom:
40
+ # Our stage is based on what is passed in when running serverless
41
+ # commands. Or fallsback to what we have set in the provider section.
42
+ stage: ${self:provider.stage, 'dev'}
43
+ funktor: ${file(funktor_config/funktor.yml)}
44
+ rubyLayer: ${file(funktor_config/ruby_layer.yml)}
45
+
46
+ package: ${file(funktor_config/package.yml)}
47
+
48
+ functions:
49
+ IncomingJobHandler: ${file(funktor_config/function_definitions/incoming_job_handler.yml)}
50
+ DefaultQueueHandler: ${file(funktor_config/function_definitions/default_queue_handler.yml)}
51
+ JobActivator: ${file(funktor_config/function_definitions/job_activator.yml)}
52
+ SingleThreadQueueHandler: ${file(funktor_config/function_definitions/single_thread_queue_handler.yml)}
53
+ RandomJobGenerator: ${file(funktor_config/function_definitions/random_job_generator.yml)}
54
+
55
+ resources:
56
+ - ${file(funktor_config/resources/activity_table.yml)}
57
+ - ${file(funktor_config/resources/incoming_job_queue_user.yml)}
58
+ - ${file(funktor_config/resources/cloudwatch_dashboard.yml)}
59
+ - ${file(funktor_config/resources/default_queue.yml)}
60
+ - ${file(funktor_config/resources/incoming_job_queue.yml)}
61
+ - ${file(funktor_config/resources/single_thread_queue.yml)}
62
+ - ${file(funktor_config/resources/jobs_table.yml)}
63
+
64
+ plugins:
65
+ - serverless-ruby-layer
data/funktor.gemspec CHANGED
@@ -30,6 +30,7 @@ Gem::Specification.new do |spec|
30
30
  spec.require_paths = ["lib"]
31
31
 
32
32
  spec.add_dependency 'aws-sdk-sqs', '~> 1.37'
33
+ spec.add_dependency 'aws-sdk-dynamodb', '~> 1.62'
33
34
  spec.add_dependency "activesupport" # TODO - Can we build our own verison of cattr_accessor to avoid this?
34
35
  spec.add_dependency "thor" # Thor drives the CLI
35
36
 
@@ -39,11 +39,11 @@ module ActiveJob
39
39
  include Funktor::Worker
40
40
 
41
41
  def perform(job_data)
42
- puts "job_data = #{job_data.class} #{job_data}"
42
+ Funktor.logger.debug "job_data = #{job_data.class} #{job_data}"
43
43
  if job_data.is_a?(Array)
44
- puts "it's an array"
44
+ Funktor.logger.debug "it's an array"
45
45
  job_data = job_data.first
46
- puts "job_data = #{job_data.class} #{job_data}"
46
+ Funktor.logger.debug "job_data = #{job_data.class} #{job_data}"
47
47
  end
48
48
  Base.execute job_data
49
49
  end
data/lib/funktor.rb CHANGED
@@ -8,6 +8,8 @@ require 'funktor/logger'
8
8
  require 'funktor/worker'
9
9
  require 'funktor/middleware_chain'
10
10
  require 'funktor/incoming_job_handler'
11
+ require 'funktor/job_activator'
12
+ require 'funktor/activity_tracker'
11
13
 
12
14
  require 'json'
13
15
 
@@ -33,14 +35,14 @@ module Funktor
33
35
  @job_pusher_chain
34
36
  end
35
37
 
36
- def self.configure_active_job_handler
38
+ def self.configure_work_queue_handler
37
39
  yield self
38
40
  end
39
41
 
40
- def self.active_job_handler_middleware
41
- @active_job_handler_chain ||= MiddlewareChain.new
42
- yield @active_job_handler_chain if block_given?
43
- @active_job_handler_chain
42
+ def self.work_queue_handler_middleware
43
+ @work_queue_handler_chain ||= MiddlewareChain.new
44
+ yield @work_queue_handler_chain if block_given?
45
+ @work_queue_handler_chain
44
46
  end
45
47
 
46
48
  # TODO - Maybe we don't need this either? Maybe this should be a super dumb thing that also
@@ -58,6 +60,18 @@ module Funktor
58
60
  @incoming_job_handler_chain
59
61
  end
60
62
 
63
+ # TODO - Does this actually make any sense? Should the JobActivator even know about
64
+ # jobs/classes? Maybe it should be super dumb and just push JSON blobs around?
65
+ def self.configure_job_activator
66
+ yield self
67
+ end
68
+
69
+ def self.job_activator_middleware
70
+ @job_activator_chain ||= MiddlewareChain.new
71
+ yield @job_activator_chain if block_given?
72
+ @job_activator_chain
73
+ end
74
+
61
75
  def self.parse_json(string)
62
76
  JSON.parse(string)
63
77
  end
@@ -95,13 +109,31 @@ module Funktor
95
109
 
96
110
  @logger = logger
97
111
  end
112
+
113
+ # We have a raw_logger that doesn't add timestamps and what not. This is used to publish
114
+ # CloudWatch metrics that can be used in dashboards.
115
+ def self.raw_logger
116
+ @raw_logger ||= Funktor::Logger.new($stdout, level: options[:log_level], formatter: proc {|severity, datetime, progname, msg|
117
+ "#{msg}\n"
118
+ })
119
+ end
120
+
121
+ def self.raw_logger=(raw_logger)
122
+ if raw_logger.nil?
123
+ self.raw_logger.level = Logger::FATAL
124
+ return self.raw_logger
125
+ end
126
+
127
+ @raw_logger = raw_logger
128
+ end
98
129
  end
99
130
 
100
- # TODO - Should we require this by default or let people opt in?
101
131
  # TODO - Is it a code smell that we need to include these at the bottom, after
102
132
  # the main Funktor module is defined?
133
+ #
134
+ # TODO - Should we require metrics by default or let people opt in?
103
135
  require 'funktor/middleware/metrics'
104
136
  require 'funktor/error_handler'
105
- require 'funktor/active_job_handler'
137
+ require 'funktor/work_queue_handler'
106
138
 
107
139
  require 'funktor/rails' if defined?(::Rails::Engine)
@@ -0,0 +1,102 @@
1
+ require 'json'
2
+ require 'aws-sdk-dynamodb'
3
+
4
+ module Funktor
5
+ class ActivityTracker
6
+
7
+ INCR_KEYS = {
8
+ incoming: 'incoming',
9
+ queued: 'queued',
10
+ scheduled: 'scheduled',
11
+ processingStarted: 'processing',
12
+ processingComplete: 'complete',
13
+ processingFailed: 'failed',
14
+ bailingOut: 'failed',
15
+ retrying: 'retries',
16
+ retryActivated: 'queued',
17
+ scheduledJobActivated: 'queued'
18
+ #scheduledJobPushedToActive: 'active',
19
+ #activeJobPushed: 'active',
20
+ #scheduledJobPushed: 'scheduled'
21
+ }
22
+
23
+ DECR_KEYS = {
24
+ incoming: nil,
25
+ queued: nil,
26
+ scheduled: nil,
27
+ processingStarted: 'queued',
28
+ processingComplete: 'processing',
29
+ processingFailed: nil,
30
+ bailingOut: 'processing',
31
+ retrying: 'processing',
32
+ retryActivated: 'retries',
33
+ scheduledJobActivated: 'scheduled'
34
+ #scheduledJobPushedToActive: 'scheduled',
35
+ #activeJobPushed: nil,
36
+ #scheduledJobPushed: nil
37
+ }
38
+
39
+ def track(activity, job)
40
+ Funktor.logger.debug "starting track activity for #{activity}"
41
+ incrKey = nil || INCR_KEYS[activity.to_sym]
42
+ decrKey = nil || DECR_KEYS[activity.to_sym]
43
+ if incrKey
44
+ increment_key(incrKey)
45
+ end
46
+ if decrKey
47
+ decrement_key(decrKey)
48
+ end
49
+ Funktor.logger.debug "ending track activity for #{activity}"
50
+ end
51
+
52
+ def increment_key(key)
53
+ #put_metric_to_stdout(key, 1)
54
+ dynamodb_client.update_item({
55
+ table_name: ENV['FUNKTOR_ACTIVITY_TABLE'],
56
+ key: { category: 'stat', statName: key },
57
+ expression_attribute_values:{ ":start": 0, ":inc": 1 },
58
+ update_expression: "SET stat_value = if_not_exists(stat_value, :start) + :inc",
59
+ })
60
+ end
61
+
62
+ def decrement_key(key)
63
+ #put_metric_to_stdout(key, -1)
64
+ dynamodb_client.update_item({
65
+ table_name: ENV['FUNKTOR_ACTIVITY_TABLE'],
66
+ key: { category: 'stat', statName: key },
67
+ expression_attribute_values:{ ":start": 0, ":inc": 1 },
68
+ update_expression: "SET stat_value = if_not_exists(stat_value, :start) - :inc",
69
+ })
70
+ end
71
+
72
+ def dynamodb_client
73
+ @dynamodb_client ||= ::Aws::DynamoDB::Client.new
74
+ end
75
+
76
+ def put_metric_to_stdout(key, value)
77
+ data = {
78
+ "_aws": {
79
+ "Timestamp": Time.now.strftime('%s%3N').to_i,
80
+ "CloudWatchMetrics": [
81
+ {
82
+ "Namespace": "rails-lambda-experiment",
83
+ "Dimensions": [["functionVersion"]],
84
+ "Metrics": [ # CPU, Memory, Duration, etc...
85
+ {
86
+ "Name": key,
87
+ "Unit": "Count"
88
+ }
89
+ ]
90
+ }
91
+ ]
92
+ },
93
+ "functionVersion": "LATEST",
94
+ #"count": value,
95
+ #"requestId": "989ffbf8-9ace-4817-a57c-e4dd734019ee"
96
+ }
97
+ data[key] = value
98
+ puts(data.to_json)
99
+ end
100
+
101
+ end
102
+ end
@@ -24,7 +24,6 @@ module Funktor
24
24
 
25
25
  def funktor_yml
26
26
  # TODO - Should we camelize the app name before writing it into the config? (CloudFormation names get weird with underscores and dashes.)
27
- puts funktor_file_target
28
27
  template "templates/funktor_init.yml", funktor_file_target
29
28
  end
30
29
 
@@ -65,6 +65,8 @@ module Funktor
65
65
  @work_queue_config = queue_details.values.first
66
66
  template File.join("funktor_config", "resources", "work_queue.yml"), File.join("funktor_config", "resources", "#{work_queue_name.underscore}_queue.yml")
67
67
  end
68
+ template File.join("funktor_config", "resources", "jobs_table.yml"), File.join("funktor_config", "resources", "jobs_table.yml")
69
+ template File.join("funktor_config", "resources", "activity_table.yml"), File.join("funktor_config", "resources", "activity_table.yml")
68
70
  end
69
71
 
70
72
  def iam_permissions
@@ -75,10 +77,14 @@ module Funktor
75
77
  @work_queue_config = queue_details.values.first
76
78
  template File.join("funktor_config", "iam_permissions", "work_queue.yml"), File.join("funktor_config", "iam_permissions", "#{work_queue_name.underscore}_queue.yml")
77
79
  end
80
+ template File.join("funktor_config", "iam_permissions", "jobs_table.yml"), File.join("funktor_config", "iam_permissions", "jobs_table.yml")
81
+ template File.join("funktor_config", "iam_permissions", "jobs_table_secondary_index.yml"), File.join("funktor_config", "iam_permissions", "jobs_table_secondary_index.yml")
82
+ template File.join("funktor_config", "iam_permissions", "activity_table.yml"), File.join("funktor_config", "iam_permissions", "activity_table.yml")
78
83
  end
79
84
 
80
85
  def function_definitions
81
86
  template File.join("funktor_config", "function_definitions", "incoming_job_handler.yml"), File.join("funktor_config", "function_definitions", "incoming_job_handler.yml")
87
+ template File.join("funktor_config", "function_definitions", "job_activator.yml"), File.join("funktor_config", "function_definitions", "job_activator.yml")
82
88
  queues.each do |queue_details|
83
89
  @work_queue_name = queue_details.keys.first
84
90
  @work_queue_config = queue_details.values.first
@@ -88,6 +94,7 @@ module Funktor
88
94
 
89
95
  def lambda_handlers
90
96
  template File.join("lambda_event_handlers", "incoming_job_handler.rb"), File.join("lambda_event_handlers", "incoming_job_handler.rb")
97
+ template File.join("lambda_event_handlers", "job_activator.rb"), File.join("lambda_event_handlers", "job_activator.rb")
91
98
  queues.each do |queue_details|
92
99
  @work_queue_name = queue_details.keys.first
93
100
  @work_queue_config = queue_details.values.first
@@ -170,6 +177,12 @@ module Funktor
170
177
  "null" # When we parse yaml 'null' gets turned to nil, which comes out as an empty string in the template
171
178
  end
172
179
 
180
+ def activator_config_value(config_name)
181
+ funktor_config.dig("jobActivator", config_name) ||
182
+ funktor_config.dig("handlerDefaults", config_name) ||
183
+ "null" # When we parse yaml 'null' gets turned to nil, which comes out as an empty string in the template
184
+ end
185
+
173
186
  def queue_config_value(queue_name, config_name)
174
187
  queue_config(queue_name)&.dig(config_name) ||
175
188
  funktor_config.dig("handlerDefaults", config_name) ||
@@ -2,7 +2,7 @@ class HelloWorker
2
2
  include Funktor::Worker
3
3
 
4
4
  def perform(*args)
5
- puts "Greetings from the HelloWorker!"
5
+ Funktor.logger.debug "Greetings from the HelloWorker!"
6
6
  end
7
7
  end
8
8
 
@@ -9,3 +9,7 @@ FUNKTOR_INCOMING_JOB_QUEUE:
9
9
  FUNKTOR_<%= queue_name.underscore.upcase %>_QUEUE:
10
10
  Ref: <%= queue_name.camelize %>Queue
11
11
  <%- end -%>
12
+ FUNKTOR_ACTIVITY_TABLE:
13
+ Ref: ActivityTable
14
+ FUNKTOR_JOBS_TABLE:
15
+ Ref: JobsTable
@@ -0,0 +1,8 @@
1
+ handler: lambda_event_handlers/job_activator.call
2
+ timeout: ${self:custom.funktor.JobActivator.timeout, 30}
3
+ reservedConcurrency: ${self:custom.funktor.JobActivator.reservedConcurrency, null}
4
+ provisionedConcurrency: ${self:custom.funktor.JobActivator.provisionedConcurrency, null}
5
+ memorySize: ${self:custom.funktor.JobActivator.memorySize, 256}
6
+ #reservedConcurrency: 1
7
+ events:
8
+ - schedule: rate(1 minute)
@@ -21,6 +21,31 @@ IncomingJobHandler:
21
21
  visibilityTimeout: <%= incoming_config_value 'visibilityTimeout' %>
22
22
  logRetentionInDays: <%= incoming_config_value 'logRetentionInDays' %>
23
23
 
24
+ JobActivator:
25
+ # timeout is how long the handler can possibly run. Up to 10 messages may be delivered
26
+ # to a handler at one time, so you'll want this to be at least 10x the maximum time you
27
+ # expect to spend for one message. The job activator usually will be pretty fast,
28
+ # but we default to a high number here to allow for the times when things go weird.
29
+ timeout: <%= activator_config_value 'timeout' %>
30
+ # reservedConcurrency represents the maximum number of concurrent executions.
31
+ # For the job activator you probably don't want to limit it because you
32
+ # want to get things onto work queues as quickly as possible when they're ready.
33
+ reservedConcurrency: <%= activator_config_value 'reservedConcurrency' %>
34
+ # provisionedConcurrency represents the number of lambda functions that will always
35
+ # be available. For the job activator you probably don't need to set this
36
+ # since it will be running on a schedule
37
+ provisionedConcurrency: <%= activator_config_value 'provisionedConcurrency' %>
38
+ # Use memory_size to adjust the reousrces (both memory and CPU) available.
39
+ # For the job activator you probably don't need this to be too large,
40
+ # but if you're seeing large delays at this stage it might help to bump it up.
41
+ memorySize: <%= activator_config_value 'memorySize' %>
42
+ batchSize: <%= activator_config_value 'batchSize' %>
43
+ maximumBatchingWindow: <%= activator_config_value 'maximumBatchingWindow' %>
44
+ visibilityTimeout: <%= activator_config_value 'visibilityTimeout' %>
45
+ logRetentionInDays: <%= activator_config_value 'logRetentionInDays' %>
46
+
47
+
48
+
24
49
  <%- queue_names.each do |queue_name| -%>
25
50
  <%= queue_name.camelize %>QueueHandler:
26
51
  # timeout is how long the handler can possibly run. Up to 10 messages may be delivered
@@ -61,5 +86,6 @@ DashboardName: ${self:service}-${self:custom.stage}-dashboard
61
86
  <%= queue_name.camelize %>DeadJobQueueName: ${self:service}-${self:custom.stage}-<%= queue_name.underscore.dasherize %>-dead
62
87
  <%= queue_name.camelize %>QueueHandlerName: ${self:service}-${self:custom.stage}-<%= queue_name.camelize %>QueueHandler
63
88
  <%- end -%>
64
-
65
-
89
+ JobsTableName: ${self:service}-${self:custom.stage}-jobs
90
+ ActivityTableName: ${self:service}-${self:custom.stage}-activity
91
+ JobActivatorName: ${self:service}-${self:custom.stage}-JobActivator
@@ -0,0 +1,5 @@
1
+ Effect: Allow
2
+ Action:
3
+ - dynamodb:*
4
+ Resource:
5
+ - "Fn::GetAtt": [ ActivityTable, Arn ]
@@ -0,0 +1,5 @@
1
+ Effect: Allow
2
+ Action:
3
+ - dynamodb:*
4
+ Resource:
5
+ - "Fn::GetAtt": [ JobsTable, Arn ]
@@ -0,0 +1,8 @@
1
+ Effect: Allow
2
+ Action:
3
+ - dynamodb:Query
4
+ Resource:
5
+ Fn::Join:
6
+ - ""
7
+ - - "Fn::GetAtt": [ JobsTable, Arn ]
8
+ - "/index/performAtIndex"
@@ -0,0 +1,22 @@
1
+ Resources:
2
+ ActivityTable:
3
+ Type: AWS::DynamoDB::Table
4
+ Properties:
5
+ # Generate a name based on the stage
6
+ TableName: ${self:custom.funktor.ActivityTableName}
7
+ BillingMode: PAY_PER_REQUEST
8
+ AttributeDefinitions:
9
+ - AttributeName: category
10
+ AttributeType: S
11
+ - AttributeName: statName
12
+ AttributeType: S
13
+ KeySchema:
14
+ - AttributeName: category
15
+ KeyType: HASH
16
+ - AttributeName: statName
17
+ KeyType: RANGE
18
+
19
+ Outputs:
20
+ ActivityTable:
21
+ Value:
22
+ Ref: ActivityTable