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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6a360de1c7367a78e1ae4cb4a5a1bb2095f11e3d
4
- data.tar.gz: 61df6de3ba420247a8e0169005212c1f74baef39
3
+ metadata.gz: 89f1bece5fe6e866cb89265426ac0f96c3dafcf8
4
+ data.tar.gz: def82f90d757304d58be03f0480e16a125bfbdd6
5
5
  SHA512:
6
- metadata.gz: 43bef41ba273f03c8ebe522e8de7820b215a2fd2606f587cb8916544b2d4d30819e55f8f552d4fbfd1b0a4655aa4ea7183e057aaee58c1503d3769abba33ccac
7
- data.tar.gz: 4870e0f7baf6977b6ec519d3a997317b9df659cb723eb457be3f1311b4fa68a261d51841b50fb9338185f7cf4a527d2ee2b7f680ccc91cdac246c51b65a2df39
6
+ metadata.gz: 89d621fcca8551eef4f2218ba3e56fa98e01815a21a528bd70d2b3464b9ad22c7391b5d95b914bf235b4c290b793e1bacc67a395703a8b5362b646ae7e9d5350
7
+ data.tar.gz: 276b2d52e496c88a29d5c2ef64b9264f76f97cd344d62cf15d38f4cade269604588b2ab0a7f63319a674fb60362c2118011f9cd916c8a7affc186a9f34209874
@@ -1,9 +1,9 @@
1
1
  before_install:
2
2
  - bundle install --path .bundle
3
3
  rvm:
4
- - 1.9.3
5
4
  - 2.1.0
6
5
  - 2.1.2
6
+ - 2.2.3
7
7
  branches:
8
8
  only:
9
9
  - master
@@ -0,0 +1,4 @@
1
+ CHANGELOG for blender-serf
2
+ ==========================
3
+ ## 0.2 (December 10, 2015)
4
+ - Async task support
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:
@@ -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.1.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.stop_query.command, nodes)
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, :stop_query, :check_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
- @stop_query = Blender::Task::Serf.new(name)
33
- @stop_query.payload(metadata[:stop])
34
- @stop_query.timeout(metadata[:timeout])
35
- @stop_query.no_ack(metadata[:no_ack])
36
- @stop_query.process(&metadata[:process])
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 stop(&block)
50
- @stop_query.instance_eval(&block)
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].merge!(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
- stop: 'stop',
77
+ reap: 'reap',
72
78
  check: 'check',
73
79
  timeout: 5,
74
80
  no_ack: false,
75
81
  process: nil,
76
- retry_options: { max_elapsed_time: 180 }
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 stop check}.each do |payload|
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.1.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-02-02 00:00:00.000000000 Z
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.2.2
199
+ rubygems_version: 2.4.5.1
199
200
  signing_key:
200
201
  specification_version: 4
201
202
  summary: Serf backend for blender