blender-serf 0.1.0 → 0.2.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 +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG.md +4 -0
- data/README.md +96 -0
- data/blender-serf.gemspec +1 -1
- data/lib/blender/drivers/serf_async.rb +1 -1
- data/lib/blender/tasks/serf_async.rb +17 -11
- data/spec/blender/drivers/serf_spec.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 89f1bece5fe6e866cb89265426ac0f96c3dafcf8
|
4
|
+
data.tar.gz: def82f90d757304d58be03f0480e16a125bfbdd6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 89d621fcca8551eef4f2218ba3e56fa98e01815a21a528bd70d2b3464b9ad22c7391b5d95b914bf235b4c290b793e1bacc67a395703a8b5362b646ae7e9d5350
|
7
|
+
data.tar.gz: 276b2d52e496c88a29d5c2ef64b9264f76f97cd344d62cf15d38f4cade269604588b2ab0a7f63319a674fb60362c2118011f9cd916c8a7affc186a9f34209874
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -115,6 +115,102 @@ end
|
|
115
115
|
run
|
116
116
|
|
117
117
|
```
|
118
|
+
|
119
|
+
### Async task DSL:
|
120
|
+
|
121
|
+
Since serf event handler execution happens synchronously (i.e. normal serf
|
122
|
+
events wont be processed when an event handler is running). Hence, it is
|
123
|
+
desirable that the actual event handler returns promptly. This imposes certain
|
124
|
+
design challenges in orchestrating long running commands via serf.
|
125
|
+
|
126
|
+
blender-serf integration provides a simpler solution to this problem.
|
127
|
+
It recommends using the serf event handler only to fork off the long running command, and maintain
|
128
|
+
a state file locally that can be used to decide whether the original task is running or finished.
|
129
|
+
Most of these gears are offered by Serfx::Utils::AsynJob module. On blender side `serf_async_task` method
|
130
|
+
is used to manage this long running job, using three separate serf events (one to start
|
131
|
+
the command, another one to poll and check if its finished or not, and the last one
|
132
|
+
to reap the finished command).
|
133
|
+
|
134
|
+
Following is an example handler that runs apt update. It exposes the task management as 4
|
135
|
+
distinct events, start, check, kill, reap.
|
136
|
+
|
137
|
+
```ruby
|
138
|
+
require 'serfx/utils/async_job'
|
139
|
+
require 'serfx/utils/handler'
|
140
|
+
require 'json'
|
141
|
+
|
142
|
+
include Serfx::Utils::Handler
|
143
|
+
|
144
|
+
job = Serfx::Utils::AsyncJob.new( name: 'update', command: 'sudo apt-get update -y', state: '/opt/serf/states/chef')
|
145
|
+
|
146
|
+
on :query, 'apt-update' do |event|
|
147
|
+
case event.payload
|
148
|
+
when 'start'
|
149
|
+
status = job.start
|
150
|
+
code = (status == 'success') ? 0 : -1
|
151
|
+
puts JSON.dump(code: code, result: { status: status })
|
152
|
+
when 'kill'
|
153
|
+
status = job.kill
|
154
|
+
code = (status == 'success') ? 0 : -1
|
155
|
+
puts JSON.dump(code: code, result: { status: status })
|
156
|
+
when 'reap'
|
157
|
+
status = job.reap
|
158
|
+
code = (status == 'success') ? 0 : -1
|
159
|
+
puts JSON.dump(code: code, result: { status: status })
|
160
|
+
when 'check'
|
161
|
+
state = job.stateinfo
|
162
|
+
puts JSON.dump(code: 0, result: state)
|
163
|
+
else
|
164
|
+
puts JSON.dump(code: -1, result: { status: 'failed' })
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
run
|
169
|
+
```
|
170
|
+
|
171
|
+
This long running command can be orchestrated using the `serf_async_task` like this:
|
172
|
+
|
173
|
+
```ruby
|
174
|
+
serf_async_task 'run apt-get update' do
|
175
|
+
|
176
|
+
start do
|
177
|
+
query 'apt-update'
|
178
|
+
payload 'start'
|
179
|
+
end
|
180
|
+
|
181
|
+
check do
|
182
|
+
query 'apt-update'
|
183
|
+
payload 'check'
|
184
|
+
process do |responses|
|
185
|
+
responses.all? do |resp|
|
186
|
+
status = JSON.parse(resp['Payload'])['result']['status']
|
187
|
+
fail 'Apt-get update is running' if status == 'running'
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
reap do
|
193
|
+
query 'apt-update'
|
194
|
+
payload 'reap'
|
195
|
+
end
|
196
|
+
end
|
197
|
+
```
|
198
|
+
Which can also be reduced to this, as job named are default query names and `serf_async_task`
|
199
|
+
defaults to `start`, `check` and `reap` as payload for managing the life cycle of the command.
|
200
|
+
|
201
|
+
```ruby
|
202
|
+
serf_async_task 'apt-update' do
|
203
|
+
check do
|
204
|
+
process do |responses|
|
205
|
+
responses.all? do |resp|
|
206
|
+
status = JSON.parse(resp['Payload'])['result']['status']
|
207
|
+
fail ChefRunning if status == 'running'
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
```
|
213
|
+
|
118
214
|
## Supported ruby versions
|
119
215
|
|
120
216
|
Blender-serf currently support the following MRI versions:
|
data/blender-serf.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = 'blender-serf'
|
7
|
-
spec.version = '0.
|
7
|
+
spec.version = '0.2.0'
|
8
8
|
spec.authors = ['Ranjib Dey']
|
9
9
|
spec.email = ['ranjib@pagerduty.com']
|
10
10
|
spec.summary = %q{Serf backend for blender}
|
@@ -47,7 +47,7 @@ module Blender
|
|
47
47
|
raise ExecutionFailed, cmd.stderr
|
48
48
|
end
|
49
49
|
end
|
50
|
-
cmd = @driver.run_command(task.
|
50
|
+
cmd = @driver.run_command(task.reap_query.command, nodes)
|
51
51
|
if cmd.exitstatus != 0 and !task.metadata[:ignore_failure]
|
52
52
|
raise ExecutionFailed, cmd.stderr
|
53
53
|
end
|
@@ -19,7 +19,7 @@ require 'blender/tasks/serf'
|
|
19
19
|
module Blender
|
20
20
|
module Task
|
21
21
|
class SerfAsync < Blender::Task::Base
|
22
|
-
attr_reader :start_query, :
|
22
|
+
attr_reader :start_query, :reap_query, :check_query
|
23
23
|
|
24
24
|
def initialize(name, options = {})
|
25
25
|
super
|
@@ -29,11 +29,11 @@ module Blender
|
|
29
29
|
@start_query.no_ack(metadata[:no_ack])
|
30
30
|
@start_query.process(&metadata[:process])
|
31
31
|
|
32
|
-
@
|
33
|
-
@
|
34
|
-
@
|
35
|
-
@
|
36
|
-
@
|
32
|
+
@reap_query = Blender::Task::Serf.new(name)
|
33
|
+
@reap_query.payload(metadata[:reap])
|
34
|
+
@reap_query.timeout(metadata[:timeout])
|
35
|
+
@reap_query.no_ack(metadata[:no_ack])
|
36
|
+
@reap_query.process(&metadata[:process])
|
37
37
|
|
38
38
|
@check_query = Blender::Task::Serf.new(name)
|
39
39
|
@check_query.payload(metadata[:check])
|
@@ -42,12 +42,18 @@ module Blender
|
|
42
42
|
@check_query.process(&metadata[:process])
|
43
43
|
end
|
44
44
|
|
45
|
+
def query(event)
|
46
|
+
@start_query.query(event)
|
47
|
+
@reap_query.query(event)
|
48
|
+
@check_query.query(event)
|
49
|
+
end
|
50
|
+
|
45
51
|
def start(&block)
|
46
52
|
@start_query.instance_eval(&block)
|
47
53
|
end
|
48
54
|
|
49
|
-
def
|
50
|
-
@
|
55
|
+
def reap(&block)
|
56
|
+
@reap_query.instance_eval(&block)
|
51
57
|
end
|
52
58
|
|
53
59
|
def check(&block)
|
@@ -61,19 +67,19 @@ module Blender
|
|
61
67
|
end
|
62
68
|
|
63
69
|
def retry_options(options = {})
|
64
|
-
@metadata[:retry_options]
|
70
|
+
@metadata[:retry_options] = options
|
65
71
|
end
|
66
72
|
|
67
73
|
def default_metadata
|
68
74
|
{
|
69
75
|
ignore_failure: false,
|
70
76
|
start: 'start',
|
71
|
-
|
77
|
+
reap: 'reap',
|
72
78
|
check: 'check',
|
73
79
|
timeout: 5,
|
74
80
|
no_ack: false,
|
75
81
|
process: nil,
|
76
|
-
retry_options: {
|
82
|
+
retry_options: { intervals: Array.new(5, 30) }
|
77
83
|
}
|
78
84
|
end
|
79
85
|
end
|
@@ -61,7 +61,7 @@ describe Blender::Driver::Serf do
|
|
61
61
|
conn = double('serf connection')
|
62
62
|
ev = double('serf event')
|
63
63
|
allow(ev).to receive(:body).and_return({'success' => true})
|
64
|
-
%w{start
|
64
|
+
%w{start reap check}.each do |payload|
|
65
65
|
allow(conn).to receive(:query).with('chef', payload , Timeout: 5000000000, FilterNodes: ['node1']).and_yield(ev)
|
66
66
|
end
|
67
67
|
allow(Serfx).to receive(:connect).with(authkey: 'asyncexample').and_yield(conn)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blender-serf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ranjib Dey
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-12-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pd-blender
|
@@ -159,6 +159,7 @@ extra_rdoc_files: []
|
|
159
159
|
files:
|
160
160
|
- ".gitignore"
|
161
161
|
- ".travis.yml"
|
162
|
+
- CHANGELOG.md
|
162
163
|
- Gemfile
|
163
164
|
- README.md
|
164
165
|
- Rakefile
|
@@ -195,7 +196,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
195
196
|
version: '0'
|
196
197
|
requirements: []
|
197
198
|
rubyforge_project:
|
198
|
-
rubygems_version: 2.
|
199
|
+
rubygems_version: 2.4.5.1
|
199
200
|
signing_key:
|
200
201
|
specification_version: 4
|
201
202
|
summary: Serf backend for blender
|