kuby-sidekiq 0.3.0 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 16ba8d64983f10c83431ce728402e36c40664b0ba89ff55f5c3677fc2291bcfe
4
- data.tar.gz: 158df48cc2d19408fe295fb745f561a8a93858cfec765fac3fdb6a06fe2cee8e
3
+ metadata.gz: 96b955437e20df29e41ac12d18bcb7ae804af4858a35e58c1a29b54b76b16ee7
4
+ data.tar.gz: 183546d8e03bba59e1baa60e253a6abf682dfbbb1d450e5c550109016e7f1c5f
5
5
  SHA512:
6
- metadata.gz: 26e27f3fc64531c064e70596d384e2d6279c63141ea0f7f1c481dbccbd144a8749927878bd1b11e64a19644e2144d02c974e2fd133981ac282b2a5bc9672f7ac
7
- data.tar.gz: 6b9f8ab50e6d994d7bbd2d8874ce1c84e7d21d41491e98017eac61d6f38b40cfef34331423b62b7bcc9027da82318aa09255c847c9cbcb286276ac64a463bfe7
6
+ metadata.gz: 64178547f2fa845ab5879cbe39d6d98d62e2fb56d8433fbc7748e69e93eff3502cd1c503ca563a270a233ee6b5d7cfe4145962817597eb1f52111daffe26a17f
7
+ data.tar.gz: 85516c3f5ba4c5f87ddf0e46dd13fe159eccf2d4ab86685840d7ff3e7ba3df3574df477ff498b6eea8ad0fd6a0b2bcbd1f2f22accdb568ac4f55de19a93c176a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 0.5.0
2
+ * Support for multiple configurable Sidekiq processes (#2, @zhall0624)
3
+
4
+ ## 0.4.0
5
+ * Use kuby-redis v0.2, which uses the Spotahome Redis operator instead of KubeDB.
6
+
1
7
  ## 0.3.0
2
8
  * Conform to new plugin architecture.
3
9
  * Accept `environment` instead of `definition` instances.
data/Gemfile CHANGED
@@ -6,6 +6,7 @@ gem 'kuby-core', path: '../kuby-core'
6
6
  gem 'sidekiq', '>= 6'
7
7
 
8
8
  group :development, :test do
9
+ gem 'sorbet-runtime'
9
10
  gem 'pry-byebug'
10
11
  gem 'rake'
11
12
  end
data/README.md ADDED
@@ -0,0 +1,106 @@
1
+ **NOTE**: The documentation below refers to an unreleased version of kuby-sidekiq.
2
+
3
+ ## kuby-sidekiq
4
+
5
+ Sidekiq plugin for [Kuby](https://github.com/getkuby/kuby-core).
6
+
7
+ ## Intro
8
+
9
+ The Sidekiq plugin makes it easy to run a deployment of Sidekiq workers for your Rails app. Behind the scenes it uses [kuby-redis](https://github.com/getkuby/kuby-redis) to stand up an instance of Redis and Kubernetes deployments to start the desired number of workers.
10
+
11
+ ## Configuration
12
+
13
+ Add the kuby-sidekiq and [sidekiq](https://github.com/mperham/sidekiq) gems to your Gemfile and run `bundle install`.
14
+
15
+ Require the plugin in your kuby.rb file and configure it, eg:
16
+
17
+ ```ruby
18
+ require 'kuby/sidekiq'
19
+
20
+ Kuby.define(:production) do
21
+ kubernetes do
22
+
23
+ add_plugin(:sidekiq) do
24
+ replicas 2 # run two workers
25
+ end
26
+
27
+ end
28
+ end
29
+ ```
30
+
31
+ Next, run the setup command, eg:
32
+
33
+ ```bash
34
+ bundle exec kuby -e production setup
35
+ ```
36
+
37
+ ## Connecting to Redis
38
+
39
+ Add a Sidekiq initializer to your Rails app and tell Sidekiq how to connect to Redis:
40
+
41
+ ```ruby
42
+ # config/initializers/sidekiq.rb
43
+
44
+ if Rails.env.production?
45
+ require 'kuby'
46
+
47
+ Kuby.load!
48
+
49
+ Sidekiq.configure_server do |config|
50
+ config.redis = Kuby.environment.kubernetes.plugin(:sidekiq).connection_params
51
+ end
52
+
53
+ Sidekiq.configure_client do |config|
54
+ config.redis = Kuby.environment.kubernetes.plugin(:sidekiq).connection_params
55
+ end
56
+ end
57
+ ```
58
+
59
+ ### Build and Deploy
60
+
61
+ Now that Sidekiq has been installed and configured, build, push, and deploy your app the usual way, eg:
62
+
63
+ ```bash
64
+ bundle exec kuby -e production build
65
+ bundle exec kuby -e production push
66
+ bundle exec kuby -e production deploy
67
+ ```
68
+
69
+ ## Advanced Configuration
70
+
71
+ If you have a more complex setup for Sidekiq you can specify the processes you need to create. The options method allow you to
72
+ provide command line arguments to Sidekiq in order to either specify a non-default `sidekiq.yml` file or queues for a process to
73
+ run. The process name is required.
74
+
75
+ ```ruby
76
+ require 'kuby/sidekiq'
77
+
78
+ Kuby.define(:production) do
79
+ kubernetes do
80
+
81
+ add_plugin(:sidekiq) do
82
+ replicas 2 # sets the default number of replicas for each process
83
+
84
+
85
+ process('default') # sidekiq uses sidekiq.yml by default and has 2 replicas
86
+
87
+ process('slow_process') do
88
+ options ['-C', 'config/slow_sidekiq.yml']
89
+ replicas 4 # override default number of replicas
90
+ end
91
+
92
+ process('queue_processor') do
93
+ options ['-q', 'critical', '-q', 'less_critical']
94
+ end
95
+ end
96
+ end
97
+ end
98
+ ```
99
+
100
+ ## License
101
+
102
+ Licensed under the MIT license. See LICENSE for details.
103
+
104
+ ## Authors
105
+
106
+ * Cameron C. Dutro: http://github.com/camertron
data/Rakefile CHANGED
@@ -2,6 +2,7 @@ require 'bundler'
2
2
  require 'rspec/core/rake_task'
3
3
  require 'rubygems/package_task'
4
4
 
5
+ require 'sorbet-runtime'
5
6
  require 'kuby/sidekiq'
6
7
 
7
8
  Bundler::GemHelper.install_tasks
data/kuby-sidekiq.gemspec CHANGED
@@ -12,8 +12,9 @@ Gem::Specification.new do |s|
12
12
 
13
13
  s.platform = Gem::Platform::RUBY
14
14
 
15
- s.add_dependency 'kuby-kube-db', '~> 0.4'
16
- s.add_dependency 'kube-dsl', '~> 0.3'
15
+ s.add_dependency 'kuby-core', '>= 0.16.0', '< 1.0'
16
+ s.add_dependency 'kube-dsl', '~> 0.7'
17
+ s.add_dependency 'kuby-redis', '~> 0.2'
17
18
 
18
19
  s.require_path = 'lib'
19
20
  s.files = Dir['{lib,spec}/**/*', 'Gemfile', 'LICENSE', 'CHANGELOG.md', 'README.md', 'Rakefile', 'kuby-sidekiq.gemspec']
@@ -1,4 +1,6 @@
1
1
  require 'securerandom'
2
+ require 'kuby/redis'
3
+ require_relative 'sidekiq_process'
2
4
 
3
5
  module Kuby
4
6
  module Sidekiq
@@ -7,33 +9,55 @@ module Kuby
7
9
 
8
10
  ROLE = 'worker'.freeze
9
11
 
10
- value_fields :replicas
12
+ value_field :replicas, default: 1
11
13
 
12
- def url
13
- @url ||= "redis://#{redis.metadata.name}:6379/0"
14
+ def processes
15
+ @processes ||= []
14
16
  end
15
17
 
16
- def after_initialize
17
- @replicas = 1
18
+ def connection_params
19
+ redis_instance.connection_params
20
+ end
21
+
22
+ def configure(&block)
23
+ instance_eval(&block) if block
18
24
  end
19
25
 
20
26
  def after_configuration
27
+ if processes.empty?
28
+ processes << SidekiqProcess.new(plugin: self, default_replicas: replicas)
29
+ end
30
+
31
+ environment.kubernetes.add_plugin(:redis) do
32
+ instance :sidekiq do
33
+ custom_config (custom_config || []).concat(['maxmemory-policy noeviction'])
34
+ end
35
+ end
36
+
21
37
  return unless rails_app
22
38
 
23
- deployment.spec.template.spec.container(:worker).merge!(
24
- rails_app.deployment.spec.template.spec.container(:web), fields: [:env_from]
25
- )
39
+ processes.each do |process|
40
+ process.deployment.spec.template.spec.container(:worker).merge!(
41
+ rails_app.deployment.spec.template.spec.container(:web), fields: [:env_from]
42
+ )
43
+
44
+ if rails_app.manage_database? && database = Kuby::Plugins::RailsApp::Database.get(rails_app)
45
+ database.plugin.configure_pod_spec(process.deployment.spec.template.spec)
46
+ end
47
+ end
26
48
  end
27
49
 
28
50
  def before_deploy(manifest)
29
- image_with_tag = "#{docker.metadata.image_url}:#{kubernetes.tag}"
30
-
31
- deployment do
32
- spec do
33
- template do
34
- spec do
35
- container(:worker) do
36
- image image_with_tag
51
+ image_with_tag = "#{docker.image.image_url}:#{kubernetes.tag || Kuby::Docker::LATEST_TAG}"
52
+
53
+ processes.each do |process|
54
+ process.deployment do
55
+ spec do
56
+ template do
57
+ spec do
58
+ container(:worker) do
59
+ image image_with_tag
60
+ end
37
61
  end
38
62
  end
39
63
  end
@@ -42,11 +66,7 @@ module Kuby
42
66
  end
43
67
 
44
68
  def resources
45
- @resources ||= [
46
- service_account,
47
- deployment,
48
- redis
49
- ]
69
+ @resources ||= [service_account, *processes.map(&:deployment)]
50
70
  end
51
71
 
52
72
  def service_account(&block)
@@ -68,103 +88,15 @@ module Kuby
68
88
  @service_account
69
89
  end
70
90
 
71
- def deployment(&block)
72
- context = self
73
-
74
- @deployment ||= KubeDSL.deployment do
75
- metadata do
76
- name "#{context.selector_app}-sidekiq-#{ROLE}"
77
- namespace context.namespace.metadata.name
78
-
79
- labels do
80
- add :app, context.selector_app
81
- add :role, ROLE
82
- end
83
- end
84
-
85
- spec do
86
- replicas context.replicas
87
-
88
- selector do
89
- match_labels do
90
- add :app, context.selector_app
91
- add :role, ROLE
92
- end
93
- end
94
-
95
- strategy do
96
- type 'RollingUpdate'
97
-
98
- rolling_update do
99
- max_surge '25%'
100
- max_unavailable 0
101
- end
102
- end
103
-
104
- template do
105
- metadata do
106
- labels do
107
- add :app, context.selector_app
108
- add :role, ROLE
109
- end
110
- end
111
-
112
- spec do
113
- container(:worker) do
114
- name "#{context.selector_app}-sidekiq-#{ROLE}"
115
- image_pull_policy 'IfNotPresent'
116
- command %w(bundle exec sidekiq)
117
- end
118
-
119
- image_pull_secret do
120
- name context.kubernetes.registry_secret.metadata.name
121
- end
122
-
123
- restart_policy 'Always'
124
- service_account_name context.service_account.metadata.name
125
- end
126
- end
127
- end
128
- end
129
-
130
- @deployment.instance_eval(&block) if block
131
- @deployment
132
- end
133
-
134
- def redis(&block)
135
- context = self
136
-
137
- @redis ||= Kuby::KubeDB.redis do
138
- api_version 'kubedb.com/v1alpha1'
139
-
140
- metadata do
141
- name "#{context.selector_app}-sidekiq-redis"
142
- namespace context.kubernetes.namespace.metadata.name
143
- end
144
-
145
- spec do
146
- version '5.0.3-v1'
147
- storage_type 'Durable'
148
-
149
- storage do
150
- storage_class_name context.storage_class_name
151
- access_modes ['ReadWriteOnce']
152
-
153
- resources do
154
- requests do
155
- add :storage, '1Gi'
156
- end
157
- end
158
- end
159
- end
91
+ def process(name, &block)
92
+ SidekiqProcess.new(name: name, plugin: self, default_replicas: replicas).tap do |process|
93
+ process.instance_eval(&block) if block
94
+ processes << process
160
95
  end
161
-
162
- @redis.instance_eval(&block) if block
163
- @redis
164
96
  end
165
97
 
166
- def storage_class_name
167
- kubernetes.provider.storage_class_name
98
+ def redis_instance
99
+ kubernetes.plugin(:redis).instance(:sidekiq)
168
100
  end
169
101
 
170
102
  def kubernetes
@@ -0,0 +1,89 @@
1
+ require 'securerandom'
2
+
3
+ module Kuby
4
+ module Sidekiq
5
+ # This class creates a deployment for a Sidekiq Process. A process is a single instance
6
+ # of Sidekiq. Each instance can be provided command line options to specify concurrency,
7
+ # config files or queues.
8
+ # https://github.com/sidekiq/sidekiq/wiki/Best-Practices#4-use-precise-terminology
9
+ class SidekiqProcess
10
+ extend ::KubeDSL::ValueFields
11
+
12
+ ROLE='worker'
13
+
14
+ attr_reader :plugin, :name, :default_replicas
15
+
16
+ value_field :replicas, default: nil
17
+ value_field :options, default: []
18
+
19
+ def initialize(name: 'default', plugin:, default_replicas:)
20
+ @name = name
21
+ @plugin = plugin
22
+ @default_replicas = default_replicas
23
+ end
24
+
25
+ def deployment(&block)
26
+ context = self
27
+
28
+ @deployment ||= KubeDSL.deployment do
29
+ metadata do
30
+ name "#{context.plugin.selector_app}-sidekiq-#{ROLE}-#{context.name}"
31
+ namespace context.plugin.namespace.metadata.name
32
+
33
+ labels do
34
+ add :app, context.plugin.selector_app
35
+ add :role, ROLE
36
+ end
37
+ end
38
+
39
+ spec do
40
+ replicas (context.replicas || context.default_replicas)
41
+
42
+ selector do
43
+ match_labels do
44
+ add :app, context.plugin.selector_app
45
+ add :role, ROLE
46
+ end
47
+ end
48
+
49
+ strategy do
50
+ type 'RollingUpdate'
51
+
52
+ rolling_update do
53
+ max_surge '25%'
54
+ max_unavailable 0
55
+ end
56
+ end
57
+
58
+ template do
59
+ metadata do
60
+ labels do
61
+ add :app, context.plugin.selector_app
62
+ add :role, ROLE
63
+ end
64
+ end
65
+
66
+ spec do
67
+ container(:worker) do
68
+ name "#{context.plugin.selector_app}-sidekiq-#{ROLE}-#{context.name}"
69
+ image_pull_policy 'IfNotPresent'
70
+ command ['bundle', 'exec', 'sidekiq', *context.options]
71
+ end
72
+
73
+ image_pull_secret do
74
+ name context.plugin.kubernetes.registry_secret.metadata.name
75
+ end
76
+
77
+ restart_policy 'Always'
78
+ service_account_name context.plugin.service_account.metadata.name
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ @deployment.instance_eval(&block) if block
85
+ @deployment
86
+ end
87
+ end
88
+ end
89
+ end
@@ -1,5 +1,5 @@
1
1
  module Kuby
2
2
  module Sidekiq
3
- VERSION = '0.3.0'
3
+ VERSION = '0.5.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,43 +1,63 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kuby-sidekiq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cameron Dutro
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-30 00:00:00.000000000 Z
11
+ date: 2023-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: kuby-kube-db
14
+ name: kuby-core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.16.0
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '1.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 0.16.0
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '1.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: kube-dsl
15
35
  requirement: !ruby/object:Gem::Requirement
16
36
  requirements:
17
37
  - - "~>"
18
38
  - !ruby/object:Gem::Version
19
- version: '0.4'
39
+ version: '0.7'
20
40
  type: :runtime
21
41
  prerelease: false
22
42
  version_requirements: !ruby/object:Gem::Requirement
23
43
  requirements:
24
44
  - - "~>"
25
45
  - !ruby/object:Gem::Version
26
- version: '0.4'
46
+ version: '0.7'
27
47
  - !ruby/object:Gem::Dependency
28
- name: kube-dsl
48
+ name: kuby-redis
29
49
  requirement: !ruby/object:Gem::Requirement
30
50
  requirements:
31
51
  - - "~>"
32
52
  - !ruby/object:Gem::Version
33
- version: '0.3'
53
+ version: '0.2'
34
54
  type: :runtime
35
55
  prerelease: false
36
56
  version_requirements: !ruby/object:Gem::Requirement
37
57
  requirements:
38
58
  - - "~>"
39
59
  - !ruby/object:Gem::Version
40
- version: '0.3'
60
+ version: '0.2'
41
61
  description: Sidekiq plugin for Kuby.
42
62
  email:
43
63
  - camertron@gmail.com
@@ -48,10 +68,12 @@ files:
48
68
  - CHANGELOG.md
49
69
  - Gemfile
50
70
  - LICENSE
71
+ - README.md
51
72
  - Rakefile
52
73
  - kuby-sidekiq.gemspec
53
74
  - lib/kuby/sidekiq.rb
54
75
  - lib/kuby/sidekiq/plugin.rb
76
+ - lib/kuby/sidekiq/sidekiq_process.rb
55
77
  - lib/kuby/sidekiq/version.rb
56
78
  homepage: http://github.com/getkuby/kuby-sidekiq
57
79
  licenses: []
@@ -71,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
71
93
  - !ruby/object:Gem::Version
72
94
  version: '0'
73
95
  requirements: []
74
- rubygems_version: 3.1.4
96
+ rubygems_version: 3.4.5
75
97
  signing_key:
76
98
  specification_version: 4
77
99
  summary: Sidekiq plugin for Kuby.