daemon-kit 0.1.7.9 → 0.1.7.10

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.
@@ -0,0 +1,68 @@
1
+ module DaemonKit
2
+ # Common convenience methods for making ruote pseudo-participants more DRY
3
+ # and unified
4
+ class RuotePseudoParticipant
5
+
6
+ class << self
7
+
8
+ attr_reader :exception_handler_method, :exception_handler_block,
9
+ :on_complete_handler_method, :on_complete_handler_block
10
+
11
+ # Register a callback method or block that gets called when an exception
12
+ # occurs during the processing of an action. +handler+ can be a symbol or
13
+ # string with a method name, or a block. Both will get the exception as
14
+ # the first parameter, and the block handler will receive the participant
15
+ # instance as the second parameter
16
+ def on_exception( handler = nil, &block )
17
+ @exception_handler_method = handler
18
+ @exception_handler_block = block
19
+ end
20
+
21
+ # Register a callback method or block that gets called when the action
22
+ # was successfully completed. Block callbacks get the workitem as
23
+ # parameter.
24
+ def on_complete( handler = nil, &block )
25
+ @on_complete_handler_method = handler
26
+ @on_complete_handler_block = block
27
+ end
28
+ end
29
+
30
+ # Current workitem
31
+ attr_reader :workitem
32
+
33
+ # Current action
34
+ attr_reader :action
35
+
36
+ # Perform the specified action with the provided workitem
37
+ def perform( action, workitem )
38
+ @action, @workitem = action, workitem
39
+
40
+ begin
41
+ send( action )
42
+ run_callbacks
43
+ rescue => e
44
+ handle_exception( e )
45
+ end
46
+ end
47
+
48
+ def handle_exception( e )
49
+ raise e if self.class.exception_handler_method.nil? && self.class.exception_handler_block.nil?
50
+
51
+ if self.class.exception_handler_method
52
+ send( self.class.exception_handler_method, e )
53
+ else
54
+ self.class.exception_handler_block.call( e, self )
55
+ end
56
+ end
57
+
58
+ def run_callbacks
59
+ return if self.class.on_complete_handler_block.nil? && self.class.on_complete_handler_method.nil?
60
+
61
+ if self.class.on_complete_handler_method
62
+ send( self.class.on_complete_handler_method )
63
+ else
64
+ self.class.on_complete_handler_block.call( workitem )
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,169 @@
1
+ module DaemonKit
2
+
3
+ # Dual purpose class that is a) responsible for parsing incoming workitems and
4
+ # delegating to the correct RuotePseudoParticipant, and b) wrapping the
5
+ # workitem hash into something a bit more digestable.
6
+ class RuoteWorkitem
7
+
8
+ class << self
9
+
10
+ # = Process incoming commands via an AMQP queue
11
+ #
12
+ # Expects a JSON workitem from ruote that has these fields set in
13
+ # attributes key:
14
+ #
15
+ # {
16
+ # 'reply_queue' => 'queue to send replies to',
17
+ # 'params' => {
18
+ # 'command' => '/actor/method'
19
+ # }
20
+ # }
21
+ #
22
+ # == Notes on the command key:
23
+ #
24
+ # It looks like a resource, and will be treated as such. Is should
25
+ # be in the format of +/class/method+, and it will be passed the
26
+ # complete workitem as a hash.
27
+ #
28
+ # == Notes on replies
29
+ #
30
+ # Replies are sent back to the queue specified in the +reply_queue+ key.
31
+ #
32
+ # == Notes on errors
33
+ #
34
+ # Where daemon-kit detects errors in attempting to parse and delegate the
35
+ # workitems, it will reply to the engine and set the following field with
36
+ # the error information:
37
+ #
38
+ # daemon_kit.error
39
+ def process( transport, workitem )
40
+ # keep it singleton
41
+ @instance ||= new
42
+
43
+ work = parse( workitem )
44
+
45
+ DaemonKit.logger.warn "Processing workitem that has timed out!" if work.timed_out?
46
+
47
+ target, method = parse_command( work )
48
+
49
+ if target.nil? || method.nil?
50
+ msg = "Missing target/method in command parameter, or command parameter missing"
51
+ DaemonKit.logger.error( msg )
52
+ work["daemon_kit"] = { "error" => msg }
53
+
54
+ elsif target.public_methods.include?( method )
55
+ target.perform( method, work )
56
+
57
+ else
58
+ msg = "Workitem cannot be processes: #{method} not exposed by #{target.inspect}"
59
+ DaemonKit.logger.error( msg )
60
+ work["daemon_kit"] = { "error" => msg }
61
+ end
62
+
63
+ reply_to_engine( transport, work )
64
+ end
65
+
66
+ # Extract the class and method name from the workitem, then pick the matching
67
+ # class from the registered list of participants
68
+ def parse_command( work )
69
+ return nil if work['params']['command'].nil?
70
+
71
+ _, klass, method = work['params']['command'].split('/')
72
+
73
+ instance = RuoteParticipants.instance.participants[ klass ]
74
+
75
+ if instance.nil?
76
+ msg = "No instance registered for #{klass}"
77
+ DaemonKit.logger.error( msg )
78
+ raise DaemonKit::MissingParticipant, msg
79
+ end
80
+
81
+ return instance, method
82
+ end
83
+
84
+ def reply_to_engine( transport, response )
85
+ send( "reply_via_#{transport}", response )
86
+ end
87
+
88
+ def reply_via_amqp( response )
89
+ DaemonKit.logger.debug("Replying to engine via AMQP with #{response.inspect}")
90
+
91
+ ::MQ.queue( response['reply_queue'] ).publish( response.to_json )
92
+
93
+ response
94
+ end
95
+
96
+ def parse( workitem )
97
+ new( JSON.parse( workitem ) )
98
+ end
99
+ end
100
+
101
+ def initialize( workitem = {} )
102
+ @workitem = workitem
103
+ end
104
+
105
+ def fei
106
+ @workitem['flow_expression_id']
107
+ end
108
+
109
+ def short_fei
110
+ @short_fei ||=
111
+ '(' + [
112
+ 'fei', self.fei['owfe_version'], self.fei['engine_id'],
113
+ self.fei['workflow_definition_url'], self.fei['workflow_definition_name'],
114
+ self.fei['workflow_definition_revision'], self.fei['workflow_instance_id'],
115
+ self.fei['expression_name'], self.fei['expression_id']
116
+ ].join(' ') + ')'
117
+ end
118
+
119
+ def dispatch_time
120
+ @dispath_time ||= Time.parse( @workitem['dispatch_time'] )
121
+ end
122
+
123
+ def last_modified
124
+ @last_modified ||= Time.parse( @workitem['last_modified'] )
125
+ end
126
+
127
+ def participant_name
128
+ @workitem['participant_name']
129
+ end
130
+
131
+ def attributes
132
+ @workitem['attributes']
133
+ end
134
+
135
+ def []( key )
136
+ self.attributes[ key ]
137
+ end
138
+
139
+ def []=( key, value )
140
+ self.attributes[ key ] = value
141
+ end
142
+
143
+ def to_json
144
+ @workitem.to_json
145
+ end
146
+
147
+ # Look at the workitem payload and attempt to determine if this workitem
148
+ # has timed out or not. This method will only ever work if you used the
149
+ # +:timeout: parameter was set for the expression.
150
+ def timed_out?
151
+ key = fei['workflow_instance_id'] + '__' + fei['expression_id']
152
+
153
+ if self.attributes["__timeouts__"] && timeout = self.attributes["__timeouts__"][ key ]
154
+ return Time.at( timeout.last ) < Time.now
155
+ end
156
+
157
+ return false
158
+ end
159
+
160
+ def method_missing( method_name, *args )
161
+ if self.attributes.keys.include?( method_name.to_s )
162
+ return self.attributes[ method_name.to_s ]
163
+ end
164
+
165
+ super
166
+ end
167
+
168
+ end
169
+ end
@@ -47,5 +47,24 @@ describe DaemonKit::Arguments do
47
47
 
48
48
  res.last.should == [ '-h' ]
49
49
  end
50
+
51
+ it "should handle different ordered configurations easily" do
52
+ argv = [ '--pid', '/tmp/piddy', '--log', '/tmp/loggy' ]
53
+ res = DaemonKit::Arguments.configuration( argv )
54
+
55
+ # No additional args
56
+ res.last.should be_empty
57
+
58
+ res.first[0].should == "pid_file=/tmp/piddy"
59
+ res.first[1].should == "log_path=/tmp/loggy"
60
+ end
61
+
62
+ it "should handle mixed configurations easily" do
63
+ argv = [ '--rest', 'yes', '-l', '/tmp/loggy', '-f', 'bar' ]
64
+ res = DaemonKit::Arguments.configuration( argv )
65
+
66
+ res.first.should == [ 'log_path=/tmp/loggy' ]
67
+ res.last.should == [ '--rest', 'yes', '-f', 'bar' ]
68
+ end
50
69
  end
51
70
  end
@@ -4,7 +4,7 @@ describe DaemonKit::Config do
4
4
 
5
5
  describe "working with config data" do
6
6
  before(:each) do
7
- @config = DaemonKit::Config.new('foo' => 'bar')
7
+ @config = DaemonKit::Config.new('foo' => 'bar', 'nes' => { 'ted' => 'value' })
8
8
  end
9
9
 
10
10
  it "should have string key access to values" do
@@ -19,15 +19,17 @@ describe DaemonKit::Config do
19
19
  @config.foo.should == 'bar'
20
20
  end
21
21
 
22
- it "should return the config as a has" do
23
- @config.to_h.should == { 'foo' => 'bar' }
22
+ it "should have nested instance accessors to values" do
23
+ @config.nes.ted.should == 'value'
24
24
  end
25
25
 
26
- it "should be able to symbolize keys in returned hash" do
27
- @config.to_h(true).should == { :foo => 'bar' }
26
+ it "should return the config as a hash" do
27
+ @config.to_h.should == { 'foo' => 'bar', 'nes' => { 'ted' => 'value' } }
28
28
  end
29
29
 
30
- it "should symbolize keys in a nested fashion"
30
+ it "should be able to symbolize keys in returned hash" do
31
+ @config.to_h(true).should == { :foo => 'bar', :nes => { :ted => 'value' } }
32
+ end
31
33
  end
32
34
 
33
35
  describe "parsing files" do
@@ -18,15 +18,9 @@ describe DaemonKit::Configuration do
18
18
  @configuration.log_level.should_not be_nil
19
19
  end
20
20
 
21
- end
22
-
23
-
24
- describe DaemonKit::Initializer do
25
-
26
- it "should setup a logger" do
27
- pending
28
- DaemonKit::Initializer.run(:initialize_logger)
29
- DaemonKit.logger.should_not be_nil
21
+ it "should set a default umask" do
22
+ File.umask.should_not be(0)
23
+ File.umask.should be(18)
30
24
  end
31
25
 
32
26
  end
@@ -0,0 +1,45 @@
1
+ require File.join(File.dirname(__FILE__), "test_generator_helper.rb")
2
+
3
+
4
+ class TestRuoteGenerator < Test::Unit::TestCase
5
+ include RubiGen::GeneratorTestHelper
6
+
7
+ def setup
8
+ bare_setup
9
+ end
10
+
11
+ def teardown
12
+ bare_teardown
13
+ end
14
+
15
+ # Some generator-related assertions:
16
+ # assert_generated_file(name, &block) # block passed the file contents
17
+ # assert_directory_exists(name)
18
+ # assert_generated_class(name, &block)
19
+ # assert_generated_module(name, &block)
20
+ # assert_generated_test_for(name, &block)
21
+ # The assert_generated_(class|module|test_for) &block is passed the body of the class/module within the file
22
+ # assert_has_method(body, *methods) # check that the body has a list of methods (methods with parentheses not supported yet)
23
+ #
24
+ # Other helper methods are:
25
+ # app_root_files - put this in teardown to show files generated by the test method (e.g. p app_root_files)
26
+ # bare_setup - place this in setup method to create the APP_ROOT folder for each test
27
+ # bare_teardown - place this in teardown method to destroy the TMP_ROOT or APP_ROOT folder after each test
28
+
29
+ def test_generator_without_options
30
+ name = "myapp"
31
+ run_generator('ruote', [name], sources)
32
+ assert_directory_exists "some/directory"
33
+ assert_generated_file "some_file"
34
+ end
35
+
36
+ private
37
+ def sources
38
+ [RubiGen::PathSource.new(:test, File.join(File.dirname(__FILE__),"..", generator_path))
39
+ ]
40
+ end
41
+
42
+ def generator_path
43
+ "daemon_generators"
44
+ end
45
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: daemon-kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7.9
4
+ version: 0.1.7.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenneth Kalmer
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-22 00:00:00 +02:00
12
+ date: 2009-08-12 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -40,7 +40,7 @@ dependencies:
40
40
  requirements:
41
41
  - - ">="
42
42
  - !ruby/object:Gem::Version
43
- version: 1.4.1
43
+ version: 1.5.1
44
44
  version:
45
45
  - !ruby/object:Gem::Dependency
46
46
  name: hoe
@@ -50,9 +50,20 @@ dependencies:
50
50
  requirements:
51
51
  - - ">="
52
52
  - !ruby/object:Gem::Version
53
- version: 1.8.0
53
+ version: 2.3.2
54
54
  version:
55
- description: "Daemon Kit aims to simplify creating Ruby daemons by providing a sound application skeleton (through a generator), task specific generators (jabber bot, etc) and robust environment management code. Using simple built-in generators it is easy to created evented and non-evented daemons that perform a multitude of different tasks. Supported generators: * Evented and non-evented Jabber Bot (coming next) * Evented and non-evented loops (coming soon) * Queue poller (SQS, AMQP, etc) (coming soon)"
55
+ description: |-
56
+ Daemon Kit aims to simplify creating Ruby daemons by providing a sound application skeleton (through a generator), task specific generators (jabber bot, etc) and robust environment management code.
57
+
58
+ Using simple built-in generators it is easy to created evented and non-evented daemons that perform a multitude of different tasks.
59
+
60
+ Supported generators:
61
+
62
+ * XMPP bot (non-evented)
63
+ * AMQP consumer (evented)
64
+ * Nanite agent
65
+ * Cron-style daemon
66
+ * ruote remote participants
56
67
  email:
57
68
  - kenneth.kalmer@gmail.com
58
69
  executables:
@@ -66,7 +77,7 @@ extra_rdoc_files:
66
77
  - Logging.txt
67
78
  - Manifest.txt
68
79
  - PostInstall.txt
69
- - README.rdoc
80
+ - RuoteParticipants.txt
70
81
  - TODO.txt
71
82
  files:
72
83
  - Configuration.txt
@@ -77,6 +88,7 @@ files:
77
88
  - PostInstall.txt
78
89
  - README.rdoc
79
90
  - Rakefile
91
+ - RuoteParticipants.txt
80
92
  - TODO.txt
81
93
  - app_generators/daemon_kit/USAGE
82
94
  - app_generators/daemon_kit/daemon_kit_generator.rb
@@ -136,6 +148,14 @@ files:
136
148
  - daemon_generators/rspec/templates/spec/spec.opts
137
149
  - daemon_generators/rspec/templates/spec/spec_helper.rb
138
150
  - daemon_generators/rspec/templates/tasks/rspec.rake
151
+ - daemon_generators/ruote/USAGE
152
+ - daemon_generators/ruote/ruote_generator.rb
153
+ - daemon_generators/ruote/templates/config/amqp.yml
154
+ - daemon_generators/ruote/templates/config/initializers/ruote.rb
155
+ - daemon_generators/ruote/templates/config/ruote.yml
156
+ - daemon_generators/ruote/templates/lib/daemon.rb
157
+ - daemon_generators/ruote/templates/lib/sample.rb
158
+ - daemon_generators/ruote/templates/libexec/daemon.rb
139
159
  - lib/daemon_kit.rb
140
160
  - lib/daemon_kit/abstract_logger.rb
141
161
  - lib/daemon_kit/amqp.rb
@@ -154,11 +174,15 @@ files:
154
174
  - lib/daemon_kit/error_handlers/base.rb
155
175
  - lib/daemon_kit/error_handlers/hoptoad.rb
156
176
  - lib/daemon_kit/error_handlers/mail.rb
177
+ - lib/daemon_kit/exceptions.rb
157
178
  - lib/daemon_kit/initializer.rb
158
179
  - lib/daemon_kit/jabber.rb
159
180
  - lib/daemon_kit/nanite.rb
160
181
  - lib/daemon_kit/nanite/agent.rb
161
182
  - lib/daemon_kit/pid_file.rb
183
+ - lib/daemon_kit/ruote_participants.rb
184
+ - lib/daemon_kit/ruote_pseudo_participant.rb
185
+ - lib/daemon_kit/ruote_workitem.rb
162
186
  - lib/daemon_kit/safety.rb
163
187
  - lib/daemon_kit/tasks.rb
164
188
  - lib/daemon_kit/tasks/environment.rake
@@ -193,6 +217,7 @@ files:
193
217
  - test/test_helper.rb
194
218
  - test/test_jabber_generator.rb
195
219
  - test/test_nanite_agent_generator.rb
220
+ - test/test_ruote_generator.rb
196
221
  - vendor/tmail-1.2.3/tmail.rb
197
222
  - vendor/tmail-1.2.3/tmail/address.rb
198
223
  - vendor/tmail-1.2.3/tmail/attachments.rb
@@ -223,6 +248,8 @@ files:
223
248
  - vendor/tmail.rb
224
249
  has_rdoc: true
225
250
  homepage: http://kit.rubyforge.org/daemon-kit/rdoc/
251
+ licenses: []
252
+
226
253
  post_install_message: |+
227
254
 
228
255
  For more information on daemon-kit, see http://kit.rubyforge.org/daemon-kit
@@ -250,17 +277,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
250
277
  requirements: []
251
278
 
252
279
  rubyforge_project: kit
253
- rubygems_version: 1.3.1
280
+ rubygems_version: 1.3.4
254
281
  signing_key:
255
- specification_version: 2
282
+ specification_version: 3
256
283
  summary: Daemon Kit aims to simplify creating Ruby daemons by providing a sound application skeleton (through a generator), task specific generators (jabber bot, etc) and robust environment management code.
257
284
  test_files:
258
285
  - test/test_generator_helper.rb
259
- - test/test_cron_generator.rb
260
- - test/test_nanite_agent_generator.rb
261
- - test/test_daemon_kit_config.rb
262
- - test/test_helper.rb
263
286
  - test/test_amqp_generator.rb
287
+ - test/test_cron_generator.rb
264
288
  - test/test_daemon-kit_generator.rb
289
+ - test/test_daemon_kit_config.rb
265
290
  - test/test_deploy_capistrano_generator.rb
291
+ - test/test_helper.rb
266
292
  - test/test_jabber_generator.rb
293
+ - test/test_nanite_agent_generator.rb
294
+ - test/test_ruote_generator.rb