funktor 0.2.1 → 0.2.2
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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +35 -0
- data/.gitignore +2 -2
- data/Gemfile.lock +2 -2
- data/funktor.gemspec +1 -1
- data/lib/funktor.rb +0 -1
- data/lib/funktor/cli/bootstrap.rb +7 -7
- data/lib/funktor/cli/init.rb +80 -26
- data/lib/funktor/cli/templates/{handlers → app/handlers}/incoming_job_handler.rb +0 -0
- data/lib/funktor/cli/templates/{handlers/active_job_handler.rb → app/handlers/work_queue_handler.rb} +0 -0
- data/lib/funktor/cli/templates/{workers → app/workers}/hello_worker.rb +0 -0
- data/lib/funktor/cli/templates/config/environment.yml +4 -2
- data/lib/funktor/cli/templates/{function_definitions → config/function_definitions}/incoming_job_handler.yml +1 -1
- data/lib/funktor/cli/templates/config/function_definitions/work_queue_handler.yml +11 -0
- data/lib/funktor/cli/templates/config/funktor.yml +13 -8
- data/lib/funktor/cli/templates/{iam_permissions → config/iam_permissions}/incoming_job_queue.yml +0 -0
- data/lib/funktor/cli/templates/{iam_permissions → config/iam_permissions}/ssm.yml +0 -0
- data/lib/funktor/cli/templates/{iam_permissions/active_job_queue.yml → config/iam_permissions/work_queue.yml} +1 -1
- data/lib/funktor/cli/templates/config/package.yml +3 -2
- data/lib/funktor/cli/templates/{resources → config/resources}/cloudwatch_dashboard.yml +3 -3
- data/lib/funktor/cli/templates/{resources → config/resources}/incoming_job_queue.yml +0 -0
- data/lib/funktor/cli/templates/{resources → config/resources}/incoming_job_queue_user.yml +0 -0
- data/lib/funktor/cli/templates/config/resources/work_queue.yml +22 -0
- data/lib/funktor/cli/templates/funktor_init.yml.tt +72 -0
- data/lib/funktor/cli/templates/package.json +8 -1
- data/lib/funktor/cli/templates/serverless.yml +19 -12
- data/lib/funktor/incoming_job_handler.rb +11 -1
- data/lib/funktor/job.rb +4 -0
- data/lib/funktor/version.rb +1 -1
- data/lib/funktor/worker.rb +9 -0
- metadata +16 -18
- data/lib/funktor/cli/templates/function_definitions/active_job_handler.yml +0 -11
- data/lib/funktor/cli/templates/funktor.yml.tt +0 -51
- data/lib/funktor/cli/templates/resources/active_job_queue.yml +0 -22
- data/lib/funktor/deploy/cli.rb +0 -42
- data/lib/funktor/deploy/serverless.rb +0 -60
- data/lib/funktor/deploy/serverless_templates/serverless.yml +0 -156
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 38d383dcdafdb71a93c3ab881ec7772e8694fe0a8ca913a11a27ab634b068349
|
|
4
|
+
data.tar.gz: 92e17fab7ca35700c1721dbd9f674d14a1dd8a033486ed1af9d65236cad305cc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1643f95d5f02f83272c2304e6c22cda5c91bb39f4f109cd4d363d9b667294679dbfa4634962162193dd9c2ea90da57f21048a41d2b5710a80f19c91631136f8d
|
|
7
|
+
data.tar.gz: 559c5693bf8a958b22e0b6b189f72ca43d758701498ccb85c52c3cf3a9e7c2b148d26d17efdea72089328e393c1ad671b3d03b6f8dcee1ac39498fc6cf6f7535
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
|
2
|
+
# They are provided by a third-party and are governed by
|
|
3
|
+
# separate terms of service, privacy policy, and support
|
|
4
|
+
# documentation.
|
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
|
7
|
+
|
|
8
|
+
name: Ruby
|
|
9
|
+
|
|
10
|
+
on:
|
|
11
|
+
push:
|
|
12
|
+
branches: [ main ]
|
|
13
|
+
pull_request:
|
|
14
|
+
branches: [ main ]
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
test:
|
|
18
|
+
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
strategy:
|
|
21
|
+
matrix:
|
|
22
|
+
ruby-version: ['2.6', '2.7', '3.0']
|
|
23
|
+
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v2
|
|
26
|
+
- name: Set up Ruby
|
|
27
|
+
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
|
28
|
+
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
|
29
|
+
# uses: ruby/setup-ruby@v1
|
|
30
|
+
uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
|
|
31
|
+
with:
|
|
32
|
+
ruby-version: ${{ matrix.ruby-version }}
|
|
33
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
|
34
|
+
- name: Run tests
|
|
35
|
+
run: bundle exec rake
|
data/.gitignore
CHANGED
|
@@ -10,6 +10,6 @@
|
|
|
10
10
|
# rspec failure tracking
|
|
11
11
|
.rspec_status
|
|
12
12
|
|
|
13
|
-
# The funktor dir isn't a real part of the gem, it's where things
|
|
13
|
+
# The funktor app dir isn't a real part of the gem, it's where things
|
|
14
14
|
# get generated as I'm testing the gem locally. It doesn't need to be in git.
|
|
15
|
-
/funktor/
|
|
15
|
+
/myapp-funktor/
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
funktor (0.2.
|
|
4
|
+
funktor (0.2.2)
|
|
5
5
|
activesupport
|
|
6
6
|
aws-sdk-sqs (~> 1.37)
|
|
7
7
|
thor
|
|
@@ -41,7 +41,7 @@ GEM
|
|
|
41
41
|
minitest (5.14.4)
|
|
42
42
|
public_suffix (4.0.6)
|
|
43
43
|
rake (12.3.3)
|
|
44
|
-
rexml (3.2.
|
|
44
|
+
rexml (3.2.5)
|
|
45
45
|
rspec (3.10.0)
|
|
46
46
|
rspec-core (~> 3.10.0)
|
|
47
47
|
rspec-expectations (~> 3.10.0)
|
data/funktor.gemspec
CHANGED
|
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
|
31
31
|
|
|
32
32
|
spec.add_dependency 'aws-sdk-sqs', '~> 1.37'
|
|
33
33
|
spec.add_dependency "activesupport" # TODO - Can we build our own verison of cattr_accessor to avoid this?
|
|
34
|
-
spec.add_dependency "thor" #
|
|
34
|
+
spec.add_dependency "thor" # Thor drives the CLI
|
|
35
35
|
|
|
36
36
|
spec.add_development_dependency 'simplecov'
|
|
37
37
|
spec.add_development_dependency 'webmock'
|
data/lib/funktor.rb
CHANGED
|
@@ -3,16 +3,15 @@ module Funktor
|
|
|
3
3
|
class Bootstrap < Thor::Group
|
|
4
4
|
include Thor::Actions
|
|
5
5
|
|
|
6
|
+
argument :name, :type => :string, :desc => "The name of the app to initialize"
|
|
7
|
+
|
|
6
8
|
class_option :file, :aliases => "-f",
|
|
7
9
|
:type => :string, :desc => "The bootstrap file to generate.",
|
|
8
|
-
:default => "
|
|
9
|
-
class_option :directory, :aliases => "-d",
|
|
10
|
-
:type => :string, :desc => "The directory to initialize",
|
|
11
|
-
:default => "funktor"
|
|
10
|
+
:default => "funktor_init.yml"
|
|
12
11
|
|
|
13
12
|
desc <<~DESC
|
|
14
13
|
Description:
|
|
15
|
-
Bootstrap a new funktor application by generating a
|
|
14
|
+
Bootstrap a new funktor application by generating a funktor_init.yml file."
|
|
16
15
|
DESC
|
|
17
16
|
|
|
18
17
|
def self.source_root
|
|
@@ -20,13 +19,14 @@ module Funktor
|
|
|
20
19
|
end
|
|
21
20
|
|
|
22
21
|
def funktor_yml
|
|
22
|
+
# TODO - Should we camelize the app name before writing it into the config? (CloudFormation names get weird with underscores and dashes.)
|
|
23
23
|
puts funktor_file_target
|
|
24
|
-
template "templates/
|
|
24
|
+
template "templates/funktor_init.yml", funktor_file_target
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
private
|
|
28
28
|
def funktor_file_target
|
|
29
|
-
File.join
|
|
29
|
+
File.join name, options[:file]
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
end
|
data/lib/funktor/cli/init.rb
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
require 'active_support/core_ext/string/inflections'
|
|
3
|
+
|
|
1
4
|
module Funktor
|
|
2
5
|
module CLI
|
|
3
6
|
class Init < Thor::Group
|
|
4
7
|
include Thor::Actions
|
|
5
8
|
|
|
6
|
-
|
|
9
|
+
attr_accessor :work_queue_name
|
|
10
|
+
attr_accessor :work_queue_config
|
|
11
|
+
|
|
12
|
+
class_option :deployment_framework, :aliases => "-d",
|
|
7
13
|
:type => :string, :desc => "The deployment/provisioning framework to use.",
|
|
8
14
|
:default => "serverless"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
:
|
|
15
|
+
|
|
16
|
+
class_option :file, :aliases => "-f",
|
|
17
|
+
:type => :string, :desc => "The funktor init file.",
|
|
18
|
+
:default => "funktor.yml"
|
|
12
19
|
|
|
13
20
|
desc <<~DESC
|
|
14
21
|
Description:
|
|
@@ -20,59 +27,106 @@ module Funktor
|
|
|
20
27
|
end
|
|
21
28
|
|
|
22
29
|
def self.destination_root
|
|
23
|
-
|
|
30
|
+
name
|
|
24
31
|
end
|
|
25
32
|
|
|
26
33
|
def serverless_yml
|
|
27
|
-
template "serverless.yml", File.join(
|
|
34
|
+
template "serverless.yml", File.join("serverless.yml")
|
|
28
35
|
end
|
|
29
36
|
|
|
30
37
|
def funktor_config_yml
|
|
31
|
-
#template "funktor_config.yml", File.join(
|
|
32
|
-
template File.join("config", "funktor.yml"), File.join(
|
|
33
|
-
template File.join("config", "ruby_layer.yml"), File.join(
|
|
34
|
-
template File.join("config", "package.yml"), File.join(
|
|
35
|
-
template File.join("config", "environment.yml"), File.join(
|
|
38
|
+
#template "funktor_config.yml", File.join("funktor_config.yml")
|
|
39
|
+
template File.join("config", "funktor.yml"), File.join("config", "funktor.yml")
|
|
40
|
+
template File.join("config", "ruby_layer.yml"), File.join("config", "ruby_layer.yml")
|
|
41
|
+
template File.join("config", "package.yml"), File.join("config", "package.yml")
|
|
42
|
+
template File.join("config", "environment.yml"), File.join("config", "environment.yml")
|
|
36
43
|
end
|
|
37
44
|
|
|
38
45
|
def package_json
|
|
39
|
-
template "package.json", File.join(
|
|
46
|
+
template "package.json", File.join("package.json")
|
|
40
47
|
end
|
|
41
48
|
|
|
42
49
|
def gemfile
|
|
43
|
-
template "Gemfile", File.join(
|
|
50
|
+
template "Gemfile", File.join("Gemfile")
|
|
44
51
|
end
|
|
45
52
|
|
|
46
53
|
def gitignore
|
|
47
|
-
template "gitignore", File.join(
|
|
54
|
+
template "gitignore", File.join(".gitignore")
|
|
48
55
|
end
|
|
49
56
|
|
|
50
57
|
def resources
|
|
51
|
-
template File.join("resources", "incoming_job_queue.yml"), File.join(
|
|
52
|
-
template File.join("resources", "incoming_job_queue_user.yml"), File.join(
|
|
53
|
-
|
|
54
|
-
template File.join("resources", "cloudwatch_dashboard.yml"), File.join(
|
|
58
|
+
template File.join("config", "resources", "incoming_job_queue.yml"), File.join("config", "resources", "incoming_job_queue.yml")
|
|
59
|
+
template File.join("config", "resources", "incoming_job_queue_user.yml"), File.join("config", "resources", "incoming_job_queue_user.yml")
|
|
60
|
+
# TODO - Figure out how to make the dashboard aware of various queues...
|
|
61
|
+
template File.join("config", "resources", "cloudwatch_dashboard.yml"), File.join("config", "resources", "cloudwatch_dashboard.yml")
|
|
62
|
+
queues.each do |queue_details|
|
|
63
|
+
@work_queue_name = queue_details.keys.first
|
|
64
|
+
@work_queue_config = queue_details.values.first
|
|
65
|
+
template File.join("config", "resources", "work_queue.yml"), File.join("config", "resources", "#{work_queue_name.underscore}_queue.yml")
|
|
66
|
+
end
|
|
55
67
|
end
|
|
56
68
|
|
|
57
69
|
def iam_permissions
|
|
58
|
-
template File.join("iam_permissions", "ssm.yml"), File.join(
|
|
59
|
-
template File.join("iam_permissions", "incoming_job_queue.yml"), File.join(
|
|
60
|
-
|
|
70
|
+
template File.join("config", "iam_permissions", "ssm.yml"), File.join("config", "iam_permissions", "ssm.yml")
|
|
71
|
+
template File.join("config", "iam_permissions", "incoming_job_queue.yml"), File.join("config", "iam_permissions", "incoming_job_queue.yml")
|
|
72
|
+
queues.each do |queue_details|
|
|
73
|
+
@work_queue_name = queue_details.keys.first
|
|
74
|
+
@work_queue_config = queue_details.values.first
|
|
75
|
+
template File.join("config", "iam_permissions", "work_queue.yml"), File.join("config", "iam_permissions", "#{work_queue_name.underscore}_queue.yml")
|
|
76
|
+
end
|
|
61
77
|
end
|
|
62
78
|
|
|
63
79
|
def function_definitions
|
|
64
|
-
template File.join("function_definitions", "
|
|
65
|
-
|
|
80
|
+
template File.join("config", "function_definitions", "incoming_job_handler.yml"), File.join("config", "function_definitions", "incoming_job_handler.yml")
|
|
81
|
+
queues.each do |queue_details|
|
|
82
|
+
@work_queue_name = queue_details.keys.first
|
|
83
|
+
@work_queue_config = queue_details.values.first
|
|
84
|
+
template File.join("config", "function_definitions", "work_queue_handler.yml"), File.join("config", "function_definitions", "#{work_queue_name.underscore}_queue_handler.yml")
|
|
85
|
+
end
|
|
66
86
|
end
|
|
67
87
|
|
|
68
88
|
def lambda_handlers
|
|
69
|
-
template File.join("handlers", "
|
|
70
|
-
|
|
89
|
+
template File.join("app", "handlers", "incoming_job_handler.rb"), File.join("app", "handlers", "incoming_job_handler.rb")
|
|
90
|
+
queues.each do |queue_details|
|
|
91
|
+
@work_queue_name = queue_details.keys.first
|
|
92
|
+
@work_queue_config = queue_details.values.first
|
|
93
|
+
template File.join("app", "handlers", "work_queue_handler.rb"), File.join("app", "handlers", "#{work_queue_name.underscore}_queue_handler.rb")
|
|
94
|
+
end
|
|
71
95
|
end
|
|
72
96
|
|
|
73
97
|
def workers
|
|
74
|
-
template File.join("workers", "hello_worker.rb"), File.join(
|
|
98
|
+
template File.join("app", "workers", "hello_worker.rb"), File.join("app", "workers", "hello_worker.rb")
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
private
|
|
102
|
+
def funktor_config
|
|
103
|
+
@funktor_config ||= YAML.load_file options[:file]
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def name
|
|
107
|
+
funktor_config["appName"]
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def runtime
|
|
111
|
+
funktor_config["runtime"]
|
|
75
112
|
end
|
|
113
|
+
|
|
114
|
+
def queues
|
|
115
|
+
funktor_config["queues"]
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def queue_names
|
|
119
|
+
funktor_config["queues"].map{|queue_details| queue_details.keys.first }
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def work_queue_name
|
|
123
|
+
@work_queue_name
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def work_queue_config
|
|
127
|
+
@work_queue_config
|
|
128
|
+
end
|
|
129
|
+
|
|
76
130
|
end
|
|
77
131
|
end
|
|
78
132
|
end
|
|
File without changes
|
data/lib/funktor/cli/templates/{handlers/active_job_handler.rb → app/handlers/work_queue_handler.rb}
RENAMED
|
File without changes
|
|
File without changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
handler: handlers/incoming_job_handler.call
|
|
1
|
+
handler: app/handlers/incoming_job_handler.call
|
|
2
2
|
timeout: ${self:custom.funktor.incomingJobHandler.timeout, 30}
|
|
3
3
|
reservedConcurrency: ${self:custom.funktor.incomingJobHandler.reservedConcurrency, null}
|
|
4
4
|
provisionedConcurrency: ${self:custom.funktor.incomingJobHandler.provisionedConcurrency, null}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
handler: app/handlers/<%= work_queue_name.underscore %>_queue_handler.call
|
|
2
|
+
timeout: ${self:custom.funktor.<%= work_queue_name.camelize %>QueueHandler.timeout, 900}
|
|
3
|
+
reservedConcurrency: ${self:custom.funktor.<%= work_queue_name.camelize %>QueueHandler.reservedConcurrency, null}
|
|
4
|
+
provisionedConcurrency: ${self:custom.funktor.<%= work_queue_name.camelize %>QueueHandler.provisionedConcurrency, null}
|
|
5
|
+
memorySize: ${self:custom.funktor.<%= work_queue_name.camelize %>QueueHandler.memorySize, 256}
|
|
6
|
+
events:
|
|
7
|
+
- sqs:
|
|
8
|
+
arn:
|
|
9
|
+
Fn::GetAtt:
|
|
10
|
+
- <%= work_queue_name.camelize %>Queue
|
|
11
|
+
- Arn
|
|
@@ -3,7 +3,7 @@ incomingJobHandler:
|
|
|
3
3
|
# to a handler at one time, so you'll want this to be at least 10x the maximum time you
|
|
4
4
|
# expect to spend for one message. The incoming job handler usually will be pretty fast,
|
|
5
5
|
# but we default to a high number here to allow for the times when things go weird.
|
|
6
|
-
timeout:
|
|
6
|
+
timeout: 300
|
|
7
7
|
# reservedConcurrency represents the maximum number of concurrent executions.
|
|
8
8
|
# For the incoming job handler you probably don't want to limit it because you
|
|
9
9
|
# want to get things onto work queues as quickly as possible.
|
|
@@ -17,12 +17,13 @@ incomingJobHandler:
|
|
|
17
17
|
# but if you're seeing large delays at this stage it might help to bump it up.
|
|
18
18
|
memorySize: 256
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
<%- queue_names.each do |queue_name| -%>
|
|
21
|
+
<%= queue_name.camelize %>QueueHandler:
|
|
21
22
|
# timeout is how long the handler can possibly run. Up to 10 messages may be delivered
|
|
22
23
|
# to a handler at one time, so you'll want this to be at least 10x the maximum time you
|
|
23
24
|
# expect to spend for one message. The active job handler may be slow if your jobs are
|
|
24
25
|
# doing a lot of work, so we default to the maximum here.
|
|
25
|
-
timeout:
|
|
26
|
+
timeout: 300 # TODO pull this (and other values) from funktor_init.yml
|
|
26
27
|
# reservedConcurrency represents the maximum number of concurrent executions.
|
|
27
28
|
# For the active job handler you may want to limit it if you have resource limitations
|
|
28
29
|
# like database connections that you need to avoid exhausting.
|
|
@@ -36,16 +37,20 @@ activeJobHandler:
|
|
|
36
37
|
# required to actually do your jobs. You can choose an even higher number to increase
|
|
37
38
|
# the available CPU to make the jobs run faster.
|
|
38
39
|
memorySize: 256
|
|
40
|
+
<%- end -%>
|
|
41
|
+
|
|
39
42
|
|
|
40
43
|
|
|
41
44
|
|
|
42
45
|
# You shouldn't need to mess with these under most circumstances. But you could if you want to change
|
|
43
46
|
# the name of some of your resources in AWS.
|
|
44
47
|
incomingJobQueueName: ${self:service}-${self:custom.stage}-incoming-jobs
|
|
48
|
+
incomingDeadJobQueueName: ${self:service}-${self:custom.stage}-incoming-dead
|
|
45
49
|
incomingJobQueueAccessPolicyName: ${self:service}-${self:custom.stage}-incoming-job-queue-access
|
|
46
|
-
incomingDeadJobQueueName: ${self:service}-${self:custom.stage}-incoming-dead-jobs
|
|
47
|
-
activeJobQueueName: ${self:service}-${self:custom.stage}-active-jobs
|
|
48
|
-
activityQueueName: ${self:service}-${self:custom.stage}-activity
|
|
49
|
-
activityDeadQueueName: ${self:service}-${self:custom.stage}-activity-dead
|
|
50
|
-
deadJobQueueName: ${self:service}-${self:custom.stage}-dead-jobs
|
|
51
50
|
dashboardName: ${self:service}-${self:custom.stage}-dashboard
|
|
51
|
+
<%- queue_names.each do |queue_name| -%>
|
|
52
|
+
<%= queue_name.camelize %>QueueName: ${self:service}-${self:custom.stage}-<%= queue_name.underscore.dasherize %>
|
|
53
|
+
<%= queue_name.camelize %>DeadJobQueueName: ${self:service}-${self:custom.stage}-<%= queue_name.underscore.dasherize %>-dead
|
|
54
|
+
<%- end -%>
|
|
55
|
+
|
|
56
|
+
|
data/lib/funktor/cli/templates/{iam_permissions → config/iam_permissions}/incoming_job_queue.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
# TODO - Figure out how to allow individual packaging to work out of the box.
|
|
2
|
+
individually: false
|
|
1
3
|
include:
|
|
2
4
|
- Gemfile
|
|
3
5
|
- Gemfile.lock
|
|
4
|
-
-
|
|
5
|
-
- workers/**
|
|
6
|
+
- app/**
|
|
6
7
|
# Evertyting is excluded by default with serverless-ruby-layer, but you could use
|
|
7
8
|
# the lines below to exlude files that are inside an include path.
|
|
8
9
|
#exclude:
|
|
@@ -40,10 +40,10 @@ Resources:
|
|
|
40
40
|
"type": "metric",
|
|
41
41
|
"properties": {
|
|
42
42
|
"metrics": [
|
|
43
|
-
[ "AWS/SQS", "NumberOfMessagesReceived", "QueueName", "${self:custom.funktor.
|
|
43
|
+
[ "AWS/SQS", "NumberOfMessagesReceived", "QueueName", "${self:custom.funktor.DefaultQueueName}", { "label": "Received" } ],
|
|
44
44
|
[ ".", "NumberOfMessagesDeleted", ".", ".", { "label": "Handled" } ],
|
|
45
|
-
[ "AWS/Lambda", "Invocations", "FunctionName", "${self:service}-${self:provider.stage}-
|
|
46
|
-
[ "AWS/SQS", "ApproximateNumberOfMessagesVisible", "QueueName", "${self:custom.funktor.
|
|
45
|
+
[ "AWS/Lambda", "Invocations", "FunctionName", "${self:service}-${self:provider.stage}-DefaultQueueHandler", "Resource", "${self:service}-${self:provider.stage}-DefaultQueueHandler", { "label": "Handler Invocations" } ],
|
|
46
|
+
[ "AWS/SQS", "ApproximateNumberOfMessagesVisible", "QueueName", "${self:custom.funktor.DefaultQueueName}", { "label": "Pending?" } ],
|
|
47
47
|
[ ".", "ApproximateNumberOfMessagesNotVisible", ".", ".", { "label": "Backlog?" } ],
|
|
48
48
|
[ ".", "NumberOfMessagesSent", ".", ".", { "label": "Sent" } ],
|
|
49
49
|
[ ".", "ApproximateNumberOfMessagesDelayed", ".", ".", { "label": "Delayed" } ]
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Resources:
|
|
2
|
+
<%= work_queue_name.camelize %>Queue:
|
|
3
|
+
Type: AWS::SQS::Queue
|
|
4
|
+
Properties:
|
|
5
|
+
QueueName: ${self:custom.funktor.<%= work_queue_name.camelize %>QueueName}
|
|
6
|
+
VisibilityTimeout: 300
|
|
7
|
+
RedrivePolicy:
|
|
8
|
+
deadLetterTargetArn:
|
|
9
|
+
"Fn::GetAtt": [ <%= work_queue_name.camelize %>DeadLetterQueue, Arn ]
|
|
10
|
+
maxReceiveCount: 5
|
|
11
|
+
<%= work_queue_name.camelize %>DeadLetterQueue:
|
|
12
|
+
Type: AWS::SQS::Queue
|
|
13
|
+
Properties:
|
|
14
|
+
QueueName: ${self:custom.funktor.<%= work_queue_name.camelize %>DeadJobQueueName}
|
|
15
|
+
|
|
16
|
+
Outputs:
|
|
17
|
+
<%= work_queue_name.camelize %>QueueUrl:
|
|
18
|
+
Value:
|
|
19
|
+
Ref: <%= work_queue_name.camelize %>Queue
|
|
20
|
+
<%= work_queue_name.camelize %>DeadLetterQueueUrl:
|
|
21
|
+
Value:
|
|
22
|
+
Ref: <%= work_queue_name.camelize %>DeadLetterQueue
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# ℹ️ WARNING: This file doesn't control anything directly. It's used to allow you to set/maintain config options in a central place.
|
|
2
|
+
# When you make changes to this file you should run `funktor init` again to propagate the changes to the 'active' configuration files.
|
|
3
|
+
appName: <%= name %>
|
|
4
|
+
runtime: ruby2.7
|
|
5
|
+
|
|
6
|
+
# These values will be applied to any funktor handlers that don't specify custom values.
|
|
7
|
+
# TODO - These still need to be wired up to do anything.
|
|
8
|
+
handler_defaults:
|
|
9
|
+
# timeout is how long the handler can possibly run. Up to 10 messages may be delivered
|
|
10
|
+
# to a handler at one time, so you'll want this to be at least 10x the maximum time you
|
|
11
|
+
# expect to spend for one message. We default to a high number here to allow for the
|
|
12
|
+
# times when things go weird.
|
|
13
|
+
timeout: 900
|
|
14
|
+
|
|
15
|
+
# reservedConcurrency represents the maximum number of concurrent executions.
|
|
16
|
+
# Usually you'll want to leave this as null so that handlers can scale infinitely
|
|
17
|
+
# (within your account limits). If you need to restrict concurrency to prevent
|
|
18
|
+
# resource exhaustion you should do it at the queue level.
|
|
19
|
+
reservedConcurrency: null
|
|
20
|
+
|
|
21
|
+
# provisionedConcurrency represents the number of lambda functions that will always
|
|
22
|
+
# be available. You probably want to set this on individual queues if you're going
|
|
23
|
+
# to use it.
|
|
24
|
+
provisionedConcurrency: null
|
|
25
|
+
|
|
26
|
+
# Use memory_size to adjust the reousrces (both memory and CPU) available.
|
|
27
|
+
# We default to 256 as a reasonable trade off on saving money but getting
|
|
28
|
+
# reasonable performance.
|
|
29
|
+
memorySize: 256
|
|
30
|
+
|
|
31
|
+
# You can set the batch size. Max of 10_000 for normal queues, 10 for FIFO.
|
|
32
|
+
batchSize: 10
|
|
33
|
+
|
|
34
|
+
# How many seconds should AWS wait for a batch to fill up before executing lambda?
|
|
35
|
+
# For immediate execution set the batch size to 1.
|
|
36
|
+
maximumBatchingWindow : 1
|
|
37
|
+
|
|
38
|
+
# Visibility timeout should only come into play in the case of Funktor errors.
|
|
39
|
+
# Application level errors should be handled by Funktor retry mechanisms.
|
|
40
|
+
# The visibility timeout should be at least as long as the function timeout, and up to 6 times larger.
|
|
41
|
+
visibilityTimeout: 900
|
|
42
|
+
|
|
43
|
+
# Set log rentention to save money
|
|
44
|
+
logRetentionInDays: 30
|
|
45
|
+
|
|
46
|
+
# Incoming Job Handler
|
|
47
|
+
# TODO - These still need to be wired up to do anything.
|
|
48
|
+
incoming_job_handler:
|
|
49
|
+
# If your jobs are bursty AND time-sensitive you might want to have some lambdas pre-provisioned
|
|
50
|
+
# to quickly handle jobs at the beginning of a burst. Uncomment the line below if so.
|
|
51
|
+
# provisionedConcurrency: 4
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# TODO - These still need to be wired up to do anything.
|
|
55
|
+
queues:
|
|
56
|
+
- default:
|
|
57
|
+
# Set queue specific config options here
|
|
58
|
+
# memorySize: 512
|
|
59
|
+
# TODO - Is it advisable to use FIFO queuues with Funktor?
|
|
60
|
+
# TODO - Maybe this isn't really even supported by CloudFormation?
|
|
61
|
+
# fifo: false
|
|
62
|
+
- singleThread:
|
|
63
|
+
reservedConcurrency: 1
|
|
64
|
+
|
|
65
|
+
# TODO - Maybe this shouldn't be surfaced this early?
|
|
66
|
+
# TODO - This still needs to be wired up to do anything.
|
|
67
|
+
package:
|
|
68
|
+
patterns:
|
|
69
|
+
- Gemfile
|
|
70
|
+
- Gemfile.lock
|
|
71
|
+
- app/**
|
|
72
|
+
- config/**
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
# Happy Coding!
|
|
13
13
|
|
|
14
14
|
# The name of your service. All your AWS resources will contain this name.
|
|
15
|
-
service:
|
|
15
|
+
service: <%= name %>
|
|
16
16
|
|
|
17
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
18
|
configValidationMode: error
|
|
@@ -22,13 +22,16 @@ frameworkVersion: '2'
|
|
|
22
22
|
|
|
23
23
|
provider:
|
|
24
24
|
name: aws
|
|
25
|
-
runtime:
|
|
25
|
+
runtime: <%= runtime %>
|
|
26
26
|
lambdaHashingVersion: 20201221
|
|
27
27
|
environment: ${file(config/environment.yml)}
|
|
28
|
+
versionFunctions: false # Reduces the amount of storage used since all Lambdas together are limited to 75GB
|
|
28
29
|
iamRoleStatements:
|
|
29
|
-
- ${file(iam_permissions/ssm.yml)}
|
|
30
|
-
- ${file(iam_permissions/
|
|
31
|
-
|
|
30
|
+
- ${file(config/iam_permissions/ssm.yml)}
|
|
31
|
+
- ${file(config/iam_permissions/incoming_job_queue.yml)}
|
|
32
|
+
<%- queue_names.each do |queue_name| -%>
|
|
33
|
+
- ${file(config/iam_permissions/<%= queue_name.underscore %>_queue.yml)}
|
|
34
|
+
<%- end -%>
|
|
32
35
|
|
|
33
36
|
|
|
34
37
|
custom:
|
|
@@ -41,14 +44,18 @@ custom:
|
|
|
41
44
|
package: ${file(config/package.yml)}
|
|
42
45
|
|
|
43
46
|
functions:
|
|
44
|
-
incomingJobHandler: ${file(function_definitions/incoming_job_handler.yml)}
|
|
45
|
-
|
|
47
|
+
incomingJobHandler: ${file(config/function_definitions/incoming_job_handler.yml)}
|
|
48
|
+
<%- queue_names.each do |queue_name| -%>
|
|
49
|
+
<%= queue_name.camelize %>QueueHandler: ${file(config/function_definitions/<%= queue_name.underscore %>_queue_handler.yml)}
|
|
50
|
+
<%- end -%>
|
|
46
51
|
|
|
47
52
|
resources:
|
|
48
|
-
- ${file(resources/
|
|
49
|
-
- ${file(resources/
|
|
50
|
-
- ${file(resources/
|
|
51
|
-
|
|
53
|
+
- ${file(config/resources/incoming_job_queue.yml)}
|
|
54
|
+
- ${file(config/resources/incoming_job_queue_user.yml)}
|
|
55
|
+
- ${file(config/resources/cloudwatch_dashboard.yml)}
|
|
56
|
+
<%- queue_names.each do |queue_name| -%>
|
|
57
|
+
- ${file(config/resources/<%= queue_name.underscore %>_queue.yml)}
|
|
58
|
+
<%- end -%>
|
|
52
59
|
|
|
53
60
|
plugins:
|
|
54
|
-
-
|
|
61
|
+
- serverless-ruby-layer
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'aws-sdk-sqs'
|
|
2
|
+
require 'active_support/core_ext/string/inflections'
|
|
2
3
|
|
|
3
4
|
module Funktor
|
|
4
5
|
class IncomingJobHandler
|
|
@@ -26,10 +27,19 @@ module Funktor
|
|
|
26
27
|
ENV['FUNKTOR_ACTIVE_JOB_QUEUE']
|
|
27
28
|
end
|
|
28
29
|
|
|
30
|
+
def queue_for_job(job)
|
|
31
|
+
queue_name = job.queue || 'default'
|
|
32
|
+
queue_constant = "FUNKTOR_#{queue_name.underscore.upcase}_QUEUE"
|
|
33
|
+
puts "queue_constant = #{queue_constant}"
|
|
34
|
+
puts "ENV value = #{ENV[queue_constant]}"
|
|
35
|
+
ENV[queue_constant] || ENV['FUNKTOR_DEFAULT_QUEUE']
|
|
36
|
+
end
|
|
37
|
+
|
|
29
38
|
def push_to_active_job_queue(job)
|
|
39
|
+
puts "job = #{job.to_json}"
|
|
30
40
|
sqs_client.send_message({
|
|
31
41
|
# TODO : How to get this URL...
|
|
32
|
-
queue_url:
|
|
42
|
+
queue_url: queue_for_job(job),
|
|
33
43
|
message_body: job.to_json,
|
|
34
44
|
delay_seconds: job.delay
|
|
35
45
|
})
|
data/lib/funktor/job.rb
CHANGED
data/lib/funktor/version.rb
CHANGED
data/lib/funktor/worker.rb
CHANGED
|
@@ -28,6 +28,10 @@ module Funktor::Worker
|
|
|
28
28
|
get_funktor_options[:queue_url]
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
def custom_queue
|
|
32
|
+
get_funktor_options[:queue]
|
|
33
|
+
end
|
|
34
|
+
|
|
31
35
|
def queue_url
|
|
32
36
|
# TODO : Should this default to FUNKTOR_ACTIVE_JOB_QUEUE?
|
|
33
37
|
# Depends how e handle this in pro...?
|
|
@@ -73,10 +77,15 @@ module Funktor::Worker
|
|
|
73
77
|
@client ||= Aws::SQS::Client.new
|
|
74
78
|
end
|
|
75
79
|
|
|
80
|
+
def work_queue
|
|
81
|
+
(self.custom_queue || 'default').to_s
|
|
82
|
+
end
|
|
83
|
+
|
|
76
84
|
def build_job_payload(job_id, delay, *worker_params)
|
|
77
85
|
{
|
|
78
86
|
worker: self.name,
|
|
79
87
|
worker_params: worker_params,
|
|
88
|
+
queue: self.work_queue,
|
|
80
89
|
job_id: job_id,
|
|
81
90
|
delay: delay,
|
|
82
91
|
funktor_options: get_funktor_options
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: funktor
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jeremy Green
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-06-
|
|
11
|
+
date: 2021-06-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: aws-sdk-sqs
|
|
@@ -89,6 +89,7 @@ executables:
|
|
|
89
89
|
extensions: []
|
|
90
90
|
extra_rdoc_files: []
|
|
91
91
|
files:
|
|
92
|
+
- ".github/workflows/ruby.yml"
|
|
92
93
|
- ".gitignore"
|
|
93
94
|
- ".rspec"
|
|
94
95
|
- ".travis.yml"
|
|
@@ -114,29 +115,26 @@ files:
|
|
|
114
115
|
- lib/funktor/cli/generate/work_queue.rb
|
|
115
116
|
- lib/funktor/cli/init.rb
|
|
116
117
|
- lib/funktor/cli/templates/Gemfile
|
|
118
|
+
- lib/funktor/cli/templates/app/handlers/incoming_job_handler.rb
|
|
119
|
+
- lib/funktor/cli/templates/app/handlers/work_queue_handler.rb
|
|
120
|
+
- lib/funktor/cli/templates/app/workers/hello_worker.rb
|
|
117
121
|
- lib/funktor/cli/templates/config/environment.yml
|
|
122
|
+
- lib/funktor/cli/templates/config/function_definitions/incoming_job_handler.yml
|
|
123
|
+
- lib/funktor/cli/templates/config/function_definitions/work_queue_handler.yml
|
|
118
124
|
- lib/funktor/cli/templates/config/funktor.yml
|
|
125
|
+
- lib/funktor/cli/templates/config/iam_permissions/incoming_job_queue.yml
|
|
126
|
+
- lib/funktor/cli/templates/config/iam_permissions/ssm.yml
|
|
127
|
+
- lib/funktor/cli/templates/config/iam_permissions/work_queue.yml
|
|
119
128
|
- lib/funktor/cli/templates/config/package.yml
|
|
129
|
+
- lib/funktor/cli/templates/config/resources/cloudwatch_dashboard.yml
|
|
130
|
+
- lib/funktor/cli/templates/config/resources/incoming_job_queue.yml
|
|
131
|
+
- lib/funktor/cli/templates/config/resources/incoming_job_queue_user.yml
|
|
132
|
+
- lib/funktor/cli/templates/config/resources/work_queue.yml
|
|
120
133
|
- lib/funktor/cli/templates/config/ruby_layer.yml
|
|
121
|
-
- lib/funktor/cli/templates/
|
|
122
|
-
- lib/funktor/cli/templates/function_definitions/incoming_job_handler.yml
|
|
123
|
-
- lib/funktor/cli/templates/funktor.yml.tt
|
|
134
|
+
- lib/funktor/cli/templates/funktor_init.yml.tt
|
|
124
135
|
- lib/funktor/cli/templates/gitignore
|
|
125
|
-
- lib/funktor/cli/templates/handlers/active_job_handler.rb
|
|
126
|
-
- lib/funktor/cli/templates/handlers/incoming_job_handler.rb
|
|
127
|
-
- lib/funktor/cli/templates/iam_permissions/active_job_queue.yml
|
|
128
|
-
- lib/funktor/cli/templates/iam_permissions/incoming_job_queue.yml
|
|
129
|
-
- lib/funktor/cli/templates/iam_permissions/ssm.yml
|
|
130
136
|
- lib/funktor/cli/templates/package.json
|
|
131
|
-
- lib/funktor/cli/templates/resources/active_job_queue.yml
|
|
132
|
-
- lib/funktor/cli/templates/resources/cloudwatch_dashboard.yml
|
|
133
|
-
- lib/funktor/cli/templates/resources/incoming_job_queue.yml
|
|
134
|
-
- lib/funktor/cli/templates/resources/incoming_job_queue_user.yml
|
|
135
137
|
- lib/funktor/cli/templates/serverless.yml
|
|
136
|
-
- lib/funktor/cli/templates/workers/hello_worker.rb
|
|
137
|
-
- lib/funktor/deploy/cli.rb
|
|
138
|
-
- lib/funktor/deploy/serverless.rb
|
|
139
|
-
- lib/funktor/deploy/serverless_templates/serverless.yml
|
|
140
138
|
- lib/funktor/fake_job_queue.rb
|
|
141
139
|
- lib/funktor/incoming_job_handler.rb
|
|
142
140
|
- lib/funktor/job.rb
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
handler: handlers/active_job_handler.call
|
|
2
|
-
timeout: ${self:custom.funktor.activeJobHandler.timeout, 900}
|
|
3
|
-
reservedConcurrency: ${self:custom.funktor.activeJobHandler.reservedConcurrency, null}
|
|
4
|
-
provisionedConcurrency: ${self:custom.funktor.activeJobHandler.provisionedConcurrency, null}
|
|
5
|
-
memorySize: ${self:custom.funktor.activeJobHandler.memorySize, 256}
|
|
6
|
-
events:
|
|
7
|
-
- sqs:
|
|
8
|
-
arn:
|
|
9
|
-
Fn::GetAtt:
|
|
10
|
-
- ActiveJobQueue
|
|
11
|
-
- Arn
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# ℹ️ WARNING: This file doesn't control anything directly. It's used to allow you to set/maintain config options in a central place.
|
|
2
|
-
# When you make changes to this file you should run `funktor init` again to propagate the changes to the 'active' configuration files.
|
|
3
|
-
runtime: ruby2.7
|
|
4
|
-
|
|
5
|
-
# Incoming Job Handler
|
|
6
|
-
incoming_job_handler:
|
|
7
|
-
# Use memory_size to adjust the reousrces (both memory and CPU) available
|
|
8
|
-
# memory_size: 512
|
|
9
|
-
timeout_in_seconds: 20 # This handler might have to handle several incoming jobs at once
|
|
10
|
-
# WARNING : You probably don't want to limit concurrency on incoming jobs.
|
|
11
|
-
# concurrency: 100
|
|
12
|
-
|
|
13
|
-
# Delayed Job Activator
|
|
14
|
-
delayed_job_activator:
|
|
15
|
-
# Use memory_size to adjust the reousrces (both memory and CPU) available
|
|
16
|
-
# memory_size: 512
|
|
17
|
-
execution_schedule: rate(1 minute)
|
|
18
|
-
activation_window_in_seconds: 120 # Activate any jobs scheduled for the next two minutes
|
|
19
|
-
timeout_in_seconds: 300 # Allow an activation job to run for up to 5 minutes
|
|
20
|
-
concurrency: 1
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
queues:
|
|
24
|
-
default:
|
|
25
|
-
# Use memory_size to adjust the reousrces (both memory and CPU) available
|
|
26
|
-
# memory_size: 512
|
|
27
|
-
# You can set the batch size. Max of 10_000 for normal queues, 10 for FIFO.
|
|
28
|
-
# batch_size: 10
|
|
29
|
-
# How many seconds should AWS wait for a batch to fill up before executing lambda?
|
|
30
|
-
# For immediate execution set the batch size to 1.
|
|
31
|
-
# maximumBatchingWindow : 1
|
|
32
|
-
# A single handler can receive up to batch_size jobs at a time. Make sure timeout is long enough.
|
|
33
|
-
timeout_in_seconds: 300
|
|
34
|
-
# You might want to limit concurrency of executing jobs to stay within resource limits (like DB connections).
|
|
35
|
-
# concurrency: 10
|
|
36
|
-
# Visibility timeout should only come into play in the case of Funktor errors.
|
|
37
|
-
# Application level errors should be handled by Funktor retry mechanisms.
|
|
38
|
-
# The visibility timeout should be at least as long as the function timeout, and up to 6 times larger.
|
|
39
|
-
# visibility_timeout: 300
|
|
40
|
-
# TODO - Is it advisable to use FIFO queuues with Funktor?
|
|
41
|
-
# TODO - Maybe this isn't really even supported by CloudFormation?
|
|
42
|
-
# fifo: false
|
|
43
|
-
|
|
44
|
-
# TODO - Maybe this is handled in the Dockerfile?
|
|
45
|
-
package:
|
|
46
|
-
patterns:
|
|
47
|
-
- Gemfile
|
|
48
|
-
- Gemfile.lock
|
|
49
|
-
- ../app/**
|
|
50
|
-
- ../config/**
|
|
51
|
-
- ../lambda_handlers/**
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
Resources:
|
|
2
|
-
ActiveJobQueue:
|
|
3
|
-
Type: AWS::SQS::Queue
|
|
4
|
-
Properties:
|
|
5
|
-
QueueName: ${self:custom.funktor.activeJobQueueName}
|
|
6
|
-
VisibilityTimeout: 300
|
|
7
|
-
RedrivePolicy:
|
|
8
|
-
deadLetterTargetArn:
|
|
9
|
-
"Fn::GetAtt": [ ActiveJobDeadLetterQueue, Arn ]
|
|
10
|
-
maxReceiveCount: 5
|
|
11
|
-
ActiveJobDeadLetterQueue:
|
|
12
|
-
Type: AWS::SQS::Queue
|
|
13
|
-
Properties:
|
|
14
|
-
QueueName: ${self:custom.funktor.deadJobQueueName}
|
|
15
|
-
|
|
16
|
-
Outputs:
|
|
17
|
-
ActiveJobQueueUrl:
|
|
18
|
-
Value:
|
|
19
|
-
Ref: ActiveJobQueue
|
|
20
|
-
ActiveJobDeadLetterQueueUrl:
|
|
21
|
-
Value:
|
|
22
|
-
Ref: ActiveJobDeadLetterQueue
|
data/lib/funktor/deploy/cli.rb
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
require 'optparse'
|
|
2
|
-
require 'funktor/deploy/serverless'
|
|
3
|
-
|
|
4
|
-
module Funktor
|
|
5
|
-
module Deploy
|
|
6
|
-
class CLI
|
|
7
|
-
attr_reader :options
|
|
8
|
-
def initialize
|
|
9
|
-
@options = {
|
|
10
|
-
verbose: false,
|
|
11
|
-
file: 'funktor.yml',
|
|
12
|
-
tmp_dir_prefix: '.funktor',
|
|
13
|
-
stage: 'dev'
|
|
14
|
-
}
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def parse(argv = ARGV)
|
|
18
|
-
OptionParser.new do |opts|
|
|
19
|
-
opts.on('-v', '--verbose', 'Display verbose output') do |verbose|
|
|
20
|
-
options[:verbose] = verbose
|
|
21
|
-
end
|
|
22
|
-
opts.on('-f', '--file=FILE', 'The path to the funktor.yml file to deploy') do |file|
|
|
23
|
-
options[:file] = file
|
|
24
|
-
end
|
|
25
|
-
opts.on('-t', '--tmp_dir_prefix=TMP_DIR_PREFIX', 'The prefix for the tmp dir. The stage will be appended.') do |tmp_dir_prefix|
|
|
26
|
-
options[:tmp_dir_prefix] = tmp_dir_prefix
|
|
27
|
-
end
|
|
28
|
-
opts.on('-s', '--stage=STAGE', 'The stage to deploy to. Defaults to "dev"') do |stage|
|
|
29
|
-
options[:stage] = stage
|
|
30
|
-
end
|
|
31
|
-
opts.on('-h') { puts opts; exit }
|
|
32
|
-
opts.parse!(argv)
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def run
|
|
37
|
-
Funktor::Deploy::Serverless.new(**options).call
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
require 'yaml'
|
|
2
|
-
|
|
3
|
-
module Funktor
|
|
4
|
-
module Deploy
|
|
5
|
-
class Serverless
|
|
6
|
-
attr_accessor :file, :tmp_dir_prefix, :verbose, :stage
|
|
7
|
-
def initialize(file:, tmp_dir_prefix:, verbose:, stage:)
|
|
8
|
-
@file = file
|
|
9
|
-
@tmp_dir_prefix = tmp_dir_prefix
|
|
10
|
-
@verbose = verbose
|
|
11
|
-
@stage = stage
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def call
|
|
15
|
-
#puts "deploying file #{file} via tmp_dir_prefix #{tmp_dir_prefix} for stage #{stage}"
|
|
16
|
-
make_tmp_dir
|
|
17
|
-
create_serverless_file
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def funktor_data
|
|
21
|
-
@funktor_data ||= squash_hash(YAML.load_file(file))
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def squash_hash(hsh, stack=[])
|
|
25
|
-
hsh.reduce({}) do |res, (key, val)|
|
|
26
|
-
next_stack = [ *stack, key ]
|
|
27
|
-
if val.is_a?(Hash)
|
|
28
|
-
next res.merge(squash_hash(val, next_stack))
|
|
29
|
-
end
|
|
30
|
-
res.merge(next_stack.join(".").to_sym => val)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def make_tmp_dir
|
|
35
|
-
FileUtils.mkdir_p tmp_dir
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def tmp_dir
|
|
39
|
-
"#{tmp_dir_prefix}_#{stage}"
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def create_serverless_file
|
|
43
|
-
#puts "funktor_data = "
|
|
44
|
-
#puts funktor_data
|
|
45
|
-
template_source = File.open(serverless_file_source).read
|
|
46
|
-
file_content = template_source % funktor_data
|
|
47
|
-
File.open(serverless_file_destination, 'w') { |file| file.write(file_content) }
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def serverless_file_source
|
|
51
|
-
File.expand_path("../serverless_templates/serverless.yml", __FILE__)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def serverless_file_destination
|
|
55
|
-
File.join tmp_dir, 'serverless.yml'
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
# WARNING : You probably don't want to mess with this file directly.
|
|
2
|
-
service: %{stack_name}
|
|
3
|
-
# app and org for use with dashboard.serverless.com
|
|
4
|
-
#app: your-app-name
|
|
5
|
-
#org: your-org-name
|
|
6
|
-
|
|
7
|
-
frameworkVersion: '2'
|
|
8
|
-
|
|
9
|
-
provider:
|
|
10
|
-
name: aws
|
|
11
|
-
runtime: %{runtime}
|
|
12
|
-
lambdaHashingVersion: 20201221
|
|
13
|
-
ecr:
|
|
14
|
-
images:
|
|
15
|
-
funktorimage:
|
|
16
|
-
path: ./
|
|
17
|
-
# TODO : Expose buildArgs via funktor.yml?
|
|
18
|
-
buildArgs:
|
|
19
|
-
BUNDLE_GEM__FURY__IO: ${env:BUNDLE_GEM__FURY__IO}
|
|
20
|
-
# TODO : Expose environment to funktor.yml?
|
|
21
|
-
environment:
|
|
22
|
-
FUNKTOR_INCOMING_JOB_QUEUE:
|
|
23
|
-
Ref: IncomingJobQueue
|
|
24
|
-
FUNKTOR_ACTIVE_JOB_QUEUE:
|
|
25
|
-
Ref: ActiveJobQueue
|
|
26
|
-
FUNKTOR_DELAYED_JOB_TABLE:
|
|
27
|
-
Ref: DelayedJobTable
|
|
28
|
-
delayedJobTable:
|
|
29
|
-
Ref: DelayedJobTable
|
|
30
|
-
iamRoleStatements:
|
|
31
|
-
- Effect: Allow
|
|
32
|
-
Action:
|
|
33
|
-
- ssm:Get*
|
|
34
|
-
Resource:
|
|
35
|
-
- '*' # TODO : This should probably be more selective...
|
|
36
|
-
- Effect: Allow
|
|
37
|
-
Action:
|
|
38
|
-
- sqs:ReceiveMessage
|
|
39
|
-
- sqs:DeleteMessage
|
|
40
|
-
- sqs:SendMessage
|
|
41
|
-
- sqs:GetQueueAttributes
|
|
42
|
-
Resource:
|
|
43
|
-
- "Fn::GetAtt": [ ActiveJobQueue, Arn ]
|
|
44
|
-
- Effect: Allow
|
|
45
|
-
Action:
|
|
46
|
-
- sqs:ReceiveMessage
|
|
47
|
-
- sqs:DeleteMessage
|
|
48
|
-
- sqs:SendMessage
|
|
49
|
-
- sqs:GetQueueAttributes
|
|
50
|
-
Resource:
|
|
51
|
-
- "Fn::GetAtt": [ IncomingJobQueue, Arn ]
|
|
52
|
-
- Effect: Allow
|
|
53
|
-
Action:
|
|
54
|
-
- sqs:ReceiveMessage
|
|
55
|
-
- sqs:DeleteMessage
|
|
56
|
-
- sqs:SendMessage
|
|
57
|
-
- sqs:GetQueueAttributes
|
|
58
|
-
Resource:
|
|
59
|
-
- "Fn::GetAtt": [ ActivityQueue, Arn ]
|
|
60
|
-
- Effect: Allow
|
|
61
|
-
Action:
|
|
62
|
-
- dynamodb:PutItem
|
|
63
|
-
- dynamodb:DeleteItem
|
|
64
|
-
Resource:
|
|
65
|
-
- "Fn::GetAtt": [ DelayedJobTable, Arn ]
|
|
66
|
-
- Effect: Allow
|
|
67
|
-
Action:
|
|
68
|
-
- dynamodb:*
|
|
69
|
-
Resource:
|
|
70
|
-
- "Fn::GetAtt": [ StatsTable, Arn ]
|
|
71
|
-
- Effect: Allow
|
|
72
|
-
Action:
|
|
73
|
-
- dynamodb:Query
|
|
74
|
-
Resource:
|
|
75
|
-
Fn::Join:
|
|
76
|
-
- ""
|
|
77
|
-
- - "Fn::GetAtt": [ DelayedJobTable, Arn ]
|
|
78
|
-
- "/index/performAtIndex"
|
|
79
|
-
|
|
80
|
-
custom:
|
|
81
|
-
# Our stage is based on what is passed in when running serverless
|
|
82
|
-
# commands. Or fallsback to what we have set in the provider section.
|
|
83
|
-
stage: ${opt:stage, 'dev'}
|
|
84
|
-
incomingJobQueueName: ${self:service}-${self:custom.stage}-incoming-jobs
|
|
85
|
-
incomingJobQueueAccessPolicyName: ${self:service}-${self:custom.stage}-incoming-job-queue-access
|
|
86
|
-
incomingDeadJobQueueName: ${self:service}-${self:custom.stage}-incoming-dead-jobs
|
|
87
|
-
activeJobQueueName: ${self:service}-${self:custom.stage}-active-jobs
|
|
88
|
-
activityQueueName: ${self:service}-${self:custom.stage}-activity
|
|
89
|
-
activityDeadQueueName: ${self:service}-${self:custom.stage}-activity-dead
|
|
90
|
-
deadJobQueueName: ${self:service}-${self:custom.stage}-dead-jobs
|
|
91
|
-
delayedJobTableName: ${self:service}-${self:custom.stage}-delayed-jobs
|
|
92
|
-
statsTableName: ${self:service}-${self:custom.stage}-stats
|
|
93
|
-
dashboardName: ${self:service}-${self:custom.stage}-dashboard
|
|
94
|
-
|
|
95
|
-
# you can define service wide environment variables here
|
|
96
|
-
# environment:
|
|
97
|
-
# variable1: value1
|
|
98
|
-
|
|
99
|
-
functions:
|
|
100
|
-
# TODO - How could other functions be passed in from funktor.yml?
|
|
101
|
-
#random_job_generator:
|
|
102
|
-
##handler: lambda_handlers/random_job_generator.RandomJobGenerator.call
|
|
103
|
-
#image:
|
|
104
|
-
#name: funktorimage
|
|
105
|
-
#command:
|
|
106
|
-
#- lambda_handlers/random_job_generator.RandomJobGenerator.call
|
|
107
|
-
#timeout: 170
|
|
108
|
-
#reservedConcurrency: 0
|
|
109
|
-
#events:
|
|
110
|
-
#- schedule: rate(1 minute)
|
|
111
|
-
|
|
112
|
-
delayed_job_activator:
|
|
113
|
-
image:
|
|
114
|
-
name: funktorimage
|
|
115
|
-
command:
|
|
116
|
-
- lambda_handlers/delayed_job_activator.call
|
|
117
|
-
timeout: %{delayed_job_activator.timeout_in_seconds}
|
|
118
|
-
# TODO - handle memory and concurrency
|
|
119
|
-
#reservedConcurrency: 1
|
|
120
|
-
events:
|
|
121
|
-
- schedule: %{delayed_job_activator.execution_schedule}
|
|
122
|
-
|
|
123
|
-
incoming_job_handler:
|
|
124
|
-
image:
|
|
125
|
-
name: funktorimage
|
|
126
|
-
command:
|
|
127
|
-
- lambda_handlers/incoming_job_handler.call
|
|
128
|
-
timeout: %{incoming_job_handler.timeout_in_seconds}
|
|
129
|
-
events:
|
|
130
|
-
- sqs:
|
|
131
|
-
arn:
|
|
132
|
-
Fn::GetAtt:
|
|
133
|
-
- IncomingJobQueue
|
|
134
|
-
- Arn
|
|
135
|
-
|
|
136
|
-
# TODO - We need one of these per work queue
|
|
137
|
-
active_job_handler:
|
|
138
|
-
image:
|
|
139
|
-
name: funktorimage
|
|
140
|
-
command:
|
|
141
|
-
- lambda_handlers/active_job_handler.call
|
|
142
|
-
timeout: 300
|
|
143
|
-
events:
|
|
144
|
-
- sqs:
|
|
145
|
-
arn:
|
|
146
|
-
Fn::GetAtt:
|
|
147
|
-
- ActiveJobQueue
|
|
148
|
-
- Arn
|
|
149
|
-
|
|
150
|
-
# you can add CloudFormation resource templates here
|
|
151
|
-
resources:
|
|
152
|
-
- ${file(resources/sqs-queue.yml)}
|
|
153
|
-
- ${file(resources/sqs-incoming-user.yml)}
|
|
154
|
-
- ${file(resources/dynamodb-table.yml)}
|
|
155
|
-
- ${file(resources/cloudfront-dashboard.yml)}
|
|
156
|
-
|