blender-serf 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|