apphunkd 0.9.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.
Files changed (204) hide show
  1. data/.document +5 -0
  2. data/.gitignore +22 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +18 -0
  5. data/Rakefile +78 -0
  6. data/TODO +1 -0
  7. data/VERSION +1 -0
  8. data/apphunkd.gemspec +258 -0
  9. data/bin/apphunkd +4 -0
  10. data/config/arguments.rb +12 -0
  11. data/config/boot.rb +68 -0
  12. data/config/environment.rb +23 -0
  13. data/config/environments/development.rb +2 -0
  14. data/config/environments/production.rb +2 -0
  15. data/config/environments/test.rb +2 -0
  16. data/config/post-daemonize/readme +5 -0
  17. data/config/pre-daemonize/readme +12 -0
  18. data/config/pre-daemonize/requires.rb +2 -0
  19. data/lib/apphunkd.rb +25 -0
  20. data/lib/apphunkd/api.rb +5 -0
  21. data/lib/apphunkd/api/service.rb +27 -0
  22. data/lib/apphunkd/queue.rb +96 -0
  23. data/lib/apphunkd/remote.rb +29 -0
  24. data/lib/apphunkd/remote/result.rb +15 -0
  25. data/libexec/apphunkd-daemon.rb +13 -0
  26. data/script/console +3 -0
  27. data/script/destroy +14 -0
  28. data/script/generate +14 -0
  29. data/spec/lib/apphunkd/api/service_spec.rb +47 -0
  30. data/spec/lib/apphunkd/queue_spec.rb +129 -0
  31. data/spec/lib/apphunkd/remote_spec.rb +61 -0
  32. data/spec/lib/apphunkd_spec.rb +50 -0
  33. data/spec/spec.opts +1 -0
  34. data/spec/spec_helper.rb +13 -0
  35. data/support/apphunkd.initd +47 -0
  36. data/support/apphunkd.monitrc +3 -0
  37. data/tasks/rspec.rake +21 -0
  38. data/vendor/daemon-kit/Configuration.txt +102 -0
  39. data/vendor/daemon-kit/Deployment.txt +113 -0
  40. data/vendor/daemon-kit/History.txt +97 -0
  41. data/vendor/daemon-kit/Logging.txt +92 -0
  42. data/vendor/daemon-kit/Manifest.txt +166 -0
  43. data/vendor/daemon-kit/PostInstall.txt +6 -0
  44. data/vendor/daemon-kit/README.rdoc +130 -0
  45. data/vendor/daemon-kit/Rakefile +37 -0
  46. data/vendor/daemon-kit/RuoteParticipants.txt +113 -0
  47. data/vendor/daemon-kit/TODO.txt +37 -0
  48. data/vendor/daemon-kit/app_generators/daemon_kit/USAGE +7 -0
  49. data/vendor/daemon-kit/app_generators/daemon_kit/daemon_kit_generator.rb +161 -0
  50. data/vendor/daemon-kit/app_generators/daemon_kit/templates/README +48 -0
  51. data/vendor/daemon-kit/app_generators/daemon_kit/templates/Rakefile +6 -0
  52. data/vendor/daemon-kit/app_generators/daemon_kit/templates/bin/daemon.erb +7 -0
  53. data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/arguments.rb +12 -0
  54. data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/boot.rb +68 -0
  55. data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/environment.rb +23 -0
  56. data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/environments/development.rb +2 -0
  57. data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/environments/production.rb +2 -0
  58. data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/environments/test.rb +2 -0
  59. data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/post-daemonize/readme +5 -0
  60. data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/pre-daemonize/readme +12 -0
  61. data/vendor/daemon-kit/app_generators/daemon_kit/templates/lib/daemon.rb +2 -0
  62. data/vendor/daemon-kit/app_generators/daemon_kit/templates/libexec/daemon.erb +18 -0
  63. data/vendor/daemon-kit/app_generators/daemon_kit/templates/script/console +3 -0
  64. data/vendor/daemon-kit/app_generators/daemon_kit/templates/script/destroy +14 -0
  65. data/vendor/daemon-kit/app_generators/daemon_kit/templates/script/generate +14 -0
  66. data/vendor/daemon-kit/bin/daemon_kit +18 -0
  67. data/vendor/daemon-kit/daemon_generators/amqp/USAGE +5 -0
  68. data/vendor/daemon-kit/daemon_generators/amqp/amqp_generator.rb +65 -0
  69. data/vendor/daemon-kit/daemon_generators/amqp/templates/config/amqp.yml +28 -0
  70. data/vendor/daemon-kit/daemon_generators/amqp/templates/config/initializers/amqp.rb +7 -0
  71. data/vendor/daemon-kit/daemon_generators/amqp/templates/libexec/daemon.rb +37 -0
  72. data/vendor/daemon-kit/daemon_generators/cron/USAGE +5 -0
  73. data/vendor/daemon-kit/daemon_generators/cron/cron_generator.rb +64 -0
  74. data/vendor/daemon-kit/daemon_generators/cron/templates/config/initializers/cron.rb +11 -0
  75. data/vendor/daemon-kit/daemon_generators/cron/templates/libexec/daemon.rb +43 -0
  76. data/vendor/daemon-kit/daemon_generators/cucumber/USAGE +11 -0
  77. data/vendor/daemon-kit/daemon_generators/cucumber/cucumber_generator.rb +38 -0
  78. data/vendor/daemon-kit/daemon_generators/cucumber/templates/cucumber +8 -0
  79. data/vendor/daemon-kit/daemon_generators/cucumber/templates/cucumber.rake +13 -0
  80. data/vendor/daemon-kit/daemon_generators/cucumber/templates/cucumber_environment.rb +2 -0
  81. data/vendor/daemon-kit/daemon_generators/cucumber/templates/env.rb +7 -0
  82. data/vendor/daemon-kit/daemon_generators/deploy_capistrano/deploy_capistrano_generator.rb +35 -0
  83. data/vendor/daemon-kit/daemon_generators/deploy_capistrano/templates/Capfile +10 -0
  84. data/vendor/daemon-kit/daemon_generators/deploy_capistrano/templates/USAGE +10 -0
  85. data/vendor/daemon-kit/daemon_generators/deploy_capistrano/templates/config/deploy.rb +53 -0
  86. data/vendor/daemon-kit/daemon_generators/deploy_capistrano/templates/config/deploy/production.rb +6 -0
  87. data/vendor/daemon-kit/daemon_generators/deploy_capistrano/templates/config/deploy/staging.rb +6 -0
  88. data/vendor/daemon-kit/daemon_generators/deploy_capistrano/templates/config/environments/staging.rb +0 -0
  89. data/vendor/daemon-kit/daemon_generators/jabber/USAGE +5 -0
  90. data/vendor/daemon-kit/daemon_generators/jabber/jabber_generator.rb +65 -0
  91. data/vendor/daemon-kit/daemon_generators/jabber/templates/config/initializers/jabber.rb +7 -0
  92. data/vendor/daemon-kit/daemon_generators/jabber/templates/config/jabber.yml +26 -0
  93. data/vendor/daemon-kit/daemon_generators/jabber/templates/libexec/daemon.rb +27 -0
  94. data/vendor/daemon-kit/daemon_generators/nanite_agent/USAGE +5 -0
  95. data/vendor/daemon-kit/daemon_generators/nanite_agent/nanite_agent_generator.rb +68 -0
  96. data/vendor/daemon-kit/daemon_generators/nanite_agent/templates/config/initializers/nanite_agent.rb +6 -0
  97. data/vendor/daemon-kit/daemon_generators/nanite_agent/templates/config/nanite.yml +35 -0
  98. data/vendor/daemon-kit/daemon_generators/nanite_agent/templates/lib/actors/sample.rb +11 -0
  99. data/vendor/daemon-kit/daemon_generators/nanite_agent/templates/libexec/daemon.rb +31 -0
  100. data/vendor/daemon-kit/daemon_generators/rspec/USAGE +5 -0
  101. data/vendor/daemon-kit/daemon_generators/rspec/rspec_generator.rb +55 -0
  102. data/vendor/daemon-kit/daemon_generators/rspec/templates/spec.rb +11 -0
  103. data/vendor/daemon-kit/daemon_generators/rspec/templates/spec/spec.opts +1 -0
  104. data/vendor/daemon-kit/daemon_generators/rspec/templates/spec/spec_helper.rb +21 -0
  105. data/vendor/daemon-kit/daemon_generators/rspec/templates/tasks/rspec.rake +21 -0
  106. data/vendor/daemon-kit/daemon_generators/ruote/USAGE +5 -0
  107. data/vendor/daemon-kit/daemon_generators/ruote/ruote_generator.rb +67 -0
  108. data/vendor/daemon-kit/daemon_generators/ruote/templates/config/amqp.yml +30 -0
  109. data/vendor/daemon-kit/daemon_generators/ruote/templates/config/initializers/ruote.rb +13 -0
  110. data/vendor/daemon-kit/daemon_generators/ruote/templates/config/ruote.yml +23 -0
  111. data/vendor/daemon-kit/daemon_generators/ruote/templates/lib/daemon.rb +4 -0
  112. data/vendor/daemon-kit/daemon_generators/ruote/templates/lib/sample.rb +26 -0
  113. data/vendor/daemon-kit/daemon_generators/ruote/templates/libexec/daemon.rb +33 -0
  114. data/vendor/daemon-kit/lib/daemon_kit.rb +54 -0
  115. data/vendor/daemon-kit/lib/daemon_kit/abstract_logger.rb +235 -0
  116. data/vendor/daemon-kit/lib/daemon_kit/amqp.rb +38 -0
  117. data/vendor/daemon-kit/lib/daemon_kit/application.rb +187 -0
  118. data/vendor/daemon-kit/lib/daemon_kit/arguments.rb +165 -0
  119. data/vendor/daemon-kit/lib/daemon_kit/commands/console.rb +38 -0
  120. data/vendor/daemon-kit/lib/daemon_kit/config.rb +108 -0
  121. data/vendor/daemon-kit/lib/daemon_kit/console_daemon.rb +2 -0
  122. data/vendor/daemon-kit/lib/daemon_kit/core_ext.rb +1 -0
  123. data/vendor/daemon-kit/lib/daemon_kit/core_ext/configurable.rb +96 -0
  124. data/vendor/daemon-kit/lib/daemon_kit/core_ext/string.rb +22 -0
  125. data/vendor/daemon-kit/lib/daemon_kit/cron.rb +48 -0
  126. data/vendor/daemon-kit/lib/daemon_kit/cucumber/world.rb +38 -0
  127. data/vendor/daemon-kit/lib/daemon_kit/deployment/capistrano.rb +482 -0
  128. data/vendor/daemon-kit/lib/daemon_kit/em.rb +43 -0
  129. data/vendor/daemon-kit/lib/daemon_kit/error_handlers/base.rb +32 -0
  130. data/vendor/daemon-kit/lib/daemon_kit/error_handlers/hoptoad.rb +61 -0
  131. data/vendor/daemon-kit/lib/daemon_kit/error_handlers/mail.rb +85 -0
  132. data/vendor/daemon-kit/lib/daemon_kit/exceptions.rb +8 -0
  133. data/vendor/daemon-kit/lib/daemon_kit/initializer.rb +438 -0
  134. data/vendor/daemon-kit/lib/daemon_kit/jabber.rb +170 -0
  135. data/vendor/daemon-kit/lib/daemon_kit/nanite.rb +7 -0
  136. data/vendor/daemon-kit/lib/daemon_kit/nanite/agent.rb +56 -0
  137. data/vendor/daemon-kit/lib/daemon_kit/pid_file.rb +61 -0
  138. data/vendor/daemon-kit/lib/daemon_kit/ruote_participants.rb +119 -0
  139. data/vendor/daemon-kit/lib/daemon_kit/ruote_pseudo_participant.rb +68 -0
  140. data/vendor/daemon-kit/lib/daemon_kit/ruote_workitem.rb +169 -0
  141. data/vendor/daemon-kit/lib/daemon_kit/safety.rb +85 -0
  142. data/vendor/daemon-kit/lib/daemon_kit/tasks.rb +2 -0
  143. data/vendor/daemon-kit/lib/daemon_kit/tasks/environment.rake +10 -0
  144. data/vendor/daemon-kit/lib/daemon_kit/tasks/framework.rake +120 -0
  145. data/vendor/daemon-kit/lib/daemon_kit/tasks/god.rake +62 -0
  146. data/vendor/daemon-kit/lib/daemon_kit/tasks/log.rake +8 -0
  147. data/vendor/daemon-kit/lib/daemon_kit/tasks/monit.rake +29 -0
  148. data/vendor/daemon-kit/script/console +10 -0
  149. data/vendor/daemon-kit/script/destroy +14 -0
  150. data/vendor/daemon-kit/script/generate +14 -0
  151. data/vendor/daemon-kit/script/txt2html +71 -0
  152. data/vendor/daemon-kit/spec/abstract_logger_spec.rb +126 -0
  153. data/vendor/daemon-kit/spec/argument_spec.rb +70 -0
  154. data/vendor/daemon-kit/spec/config_spec.rb +79 -0
  155. data/vendor/daemon-kit/spec/configurable_spec.rb +56 -0
  156. data/vendor/daemon-kit/spec/daemon_kit_spec.rb +7 -0
  157. data/vendor/daemon-kit/spec/error_handlers_spec.rb +23 -0
  158. data/vendor/daemon-kit/spec/fixtures/env.yml +15 -0
  159. data/vendor/daemon-kit/spec/fixtures/noenv.yml +4 -0
  160. data/vendor/daemon-kit/spec/initializer_spec.rb +26 -0
  161. data/vendor/daemon-kit/spec/spec.opts +1 -0
  162. data/vendor/daemon-kit/spec/spec_helper.rb +27 -0
  163. data/vendor/daemon-kit/tasks/rspec.rake +21 -0
  164. data/vendor/daemon-kit/templates/god/god.erb +69 -0
  165. data/vendor/daemon-kit/templates/monit/monit.erb +14 -0
  166. data/vendor/daemon-kit/test/test_amqp_generator.rb +48 -0
  167. data/vendor/daemon-kit/test/test_cron_generator.rb +45 -0
  168. data/vendor/daemon-kit/test/test_daemon-kit_generator.rb +84 -0
  169. data/vendor/daemon-kit/test/test_daemon_kit_config.rb +28 -0
  170. data/vendor/daemon-kit/test/test_deploy_capistrano_generator.rb +48 -0
  171. data/vendor/daemon-kit/test/test_generator_helper.rb +29 -0
  172. data/vendor/daemon-kit/test/test_helper.rb +7 -0
  173. data/vendor/daemon-kit/test/test_jabber_generator.rb +49 -0
  174. data/vendor/daemon-kit/test/test_nanite_agent_generator.rb +49 -0
  175. data/vendor/daemon-kit/test/test_ruote_generator.rb +45 -0
  176. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail.rb +5 -0
  177. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/address.rb +426 -0
  178. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/attachments.rb +46 -0
  179. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/base64.rb +46 -0
  180. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/compat.rb +41 -0
  181. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/config.rb +67 -0
  182. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/core_extensions.rb +63 -0
  183. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/encode.rb +581 -0
  184. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/header.rb +960 -0
  185. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/index.rb +9 -0
  186. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/interface.rb +1130 -0
  187. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/loader.rb +3 -0
  188. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/mail.rb +578 -0
  189. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/mailbox.rb +495 -0
  190. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/main.rb +6 -0
  191. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/mbox.rb +3 -0
  192. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/net.rb +248 -0
  193. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/obsolete.rb +132 -0
  194. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/parser.rb +1476 -0
  195. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/port.rb +379 -0
  196. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/quoting.rb +118 -0
  197. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/require_arch.rb +58 -0
  198. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/scanner.rb +49 -0
  199. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/scanner_r.rb +261 -0
  200. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/stringio.rb +280 -0
  201. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/utils.rb +337 -0
  202. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/version.rb +39 -0
  203. data/vendor/daemon-kit/vendor/tmail.rb +13 -0
  204. metadata +281 -0
@@ -0,0 +1,170 @@
1
+ require 'yaml'
2
+
3
+ module DaemonKit
4
+ # Thin wrapper around xmpp4r-simple, specifically designed to ease
5
+ # configuration of a jabber daemon and provide some added simplicity.
6
+ class Jabber
7
+
8
+ # Jabber connection
9
+ attr_reader :connection
10
+
11
+ @@instance = nil
12
+ @@message_handler = nil
13
+ @@presence_handler = nil
14
+ @@subscription_handler = nil
15
+
16
+ class << self
17
+
18
+ # Deliver a message to the specified jid.
19
+ def deliver( jid, message )
20
+ instance.connection.deliver( jid, message )
21
+ end
22
+
23
+ # Use this instead of initializing, keeps it singleton
24
+ def instance
25
+ @instance ||= new
26
+ @instance.startup!
27
+ end
28
+ private :new
29
+
30
+ def run
31
+ DaemonKit.logger.info "Starting jabber loop"
32
+
33
+ loop do
34
+ process_messages
35
+ process_updates
36
+ process_subscriptions
37
+
38
+ begin
39
+ sleep 1
40
+ rescue Interrupt
41
+ DaemonKit.logger.warn "Jabber loop interrupted"
42
+ break
43
+ end
44
+ end
45
+ end
46
+
47
+ def process_messages
48
+ @message_handler ||= Proc.new { |m| DaemonKit.logger.info "Received message from #{m.from}: #{m.body}" }
49
+
50
+ instance.valid_messages { |m| @message_handler.call(m) }
51
+ end
52
+
53
+ def process_updates
54
+ @presence_handler ||= Proc.new { |friend, old_presence, new_presence|
55
+ DaemonKit.logger.debug "Received presence update: #{friend} went from #{old_presence} to #{new_presence}"
56
+ }
57
+
58
+ instance.connection.presence_updates { |friend, old_presence, new_presence|
59
+ @presence_handler.call(friend, old_presence, new_presence)
60
+ }
61
+
62
+ end
63
+
64
+ def process_subscriptions
65
+ @subscription_handler ||= Proc.new { |friend,presence| DaemonKit.logger.debug "Received presence update from #{friend}: #{presence}" }
66
+
67
+ instance.connection.subscription_requests { |friend,presence| @subscription_handler.call(friend,presence) }
68
+ end
69
+
70
+ def received_messages(&block)
71
+ @message_handler = block
72
+ end
73
+
74
+ def presence_updates(&block)
75
+ @presence_handler = block
76
+ end
77
+
78
+ def subscription_requests(&block)
79
+ @subscription_handler = block
80
+ end
81
+
82
+ end
83
+
84
+ def initialize
85
+ options = DaemonKit::Config.load( 'jabber' )
86
+
87
+ @jabber_id = options.delete("jabber_id")
88
+ @password = options.delete("password")
89
+ @resource = options.delete("resource") || 'daemon_kit'
90
+ @masters = options.delete("masters") || []
91
+ @supporters = options.delete("supporters") || []
92
+
93
+ raise ArgumentError if [ @jabber_id, @password ].any? { |a| a.nil? }
94
+ end
95
+
96
+ def startup!
97
+ return self if @booted
98
+
99
+ connect!
100
+ setup_roster!
101
+
102
+ DaemonKit.trap( 'INT', Proc.new { self.shutdown! } )
103
+ DaemonKit.trap( 'TERM', Proc.new { self.shutdown! } )
104
+
105
+ @booted = true
106
+
107
+ self
108
+ end
109
+
110
+ def shutdown!
111
+ DaemonKit.logger.warn "Disconnecting jabber connection"
112
+ self.connection.disconnect
113
+ end
114
+
115
+ def contacts
116
+ @masters + @supporters
117
+ end
118
+
119
+ def valid_messages(&block)
120
+ self.connection.received_messages.each do |message|
121
+ next unless valid_master?( message.from )
122
+
123
+ busy do
124
+ block.call message
125
+ end
126
+ end
127
+ end
128
+
129
+ def valid_master?( jid )
130
+ @masters.include?( jid.strip.to_s )
131
+ end
132
+
133
+ def busy(&block)
134
+ self.connection.status(:dnd, "Working...")
135
+ yield
136
+ self.connection.status(:chat, self.status_line )
137
+ end
138
+
139
+ def status_line
140
+ "#{DaemonKit.configuration.daemon_name} ready for instructions"
141
+ end
142
+
143
+ private
144
+
145
+ def connect!
146
+ jid = @jabber_id + '/' + @resource
147
+
148
+ @connection = ::Jabber::Simple.new( jid, @password, nil, self.status_line )
149
+ end
150
+
151
+ def setup_roster!
152
+ # cleanup the roster
153
+ self.connection.roster.items.each_pair do |jid, roster_item|
154
+ jid = jid.strip.to_s
155
+ unless self.contacts.include?( jid )
156
+ self.connection.remove( jid )
157
+ end
158
+ end
159
+
160
+ # add missing contacts
161
+ self.contacts.each do |jid|
162
+ unless self.connection.subscribed_to?( jid )
163
+ self.connection.add( jid )
164
+ #self.connection.accept_subscription( jid )
165
+ end
166
+ end
167
+ end
168
+
169
+ end
170
+ end
@@ -0,0 +1,7 @@
1
+ module DaemonKit
2
+ # For building daemons that integrate with nanite, either as mappers
3
+ # or agents. See #DaemonKit::Nanite::Agent so far
4
+ module Nanite
5
+ autoload :Agent, "daemon_kit/nanite/agent"
6
+ end
7
+ end
@@ -0,0 +1,56 @@
1
+ module DaemonKit
2
+ module Nanite
3
+ # Pull support into a daemon for being a nanite agent.
4
+ class Agent
5
+
6
+ @@instance = nil
7
+
8
+ class << self
9
+
10
+ def instance
11
+ @instance ||= new
12
+ end
13
+
14
+ private :new
15
+
16
+ def run(&block)
17
+ instance.run(&block)
18
+ end
19
+
20
+ end
21
+
22
+ def initialize
23
+ @config = DaemonKit::Config.load( 'nanite' ).to_h( true )
24
+
25
+ config_agent
26
+ end
27
+
28
+ def run(&block)
29
+ # Ensure graceful shutdown of the connection to the broker
30
+ DaemonKit.trap('INT') { ::EM.stop }
31
+ DaemonKit.trap('TERM') { ::EM.stop }
32
+
33
+ # Start our mapper
34
+ mapper_thread = Thread.new do
35
+ EM.run do
36
+ agent = ::Nanite.start_agent( @config )
37
+ block.call( agent ) if block
38
+ end
39
+ end
40
+
41
+ #block.call if block
42
+
43
+ mapper_thread.join
44
+ end
45
+
46
+ private
47
+
48
+ # Make sure to fine tune the agent config to be DK friendly
49
+ def config_agent
50
+ @config[:root] = DAEMON_ROOT
51
+ @config[:daemonize] = false
52
+ @config[:actors_dir] = File.join(DAEMON_ROOT, 'lib', 'actors')
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,61 @@
1
+ module DaemonKit
2
+
3
+ # Simple pidfile handling for daemon processes
4
+ class PidFile
5
+
6
+ def initialize( path )
7
+ @path = path.to_absolute_path
8
+ end
9
+
10
+ def exists?
11
+ File.exists?( @path )
12
+ end
13
+
14
+ # Returns true if the process is running
15
+ def running?
16
+ return false unless self.exists?
17
+
18
+ # Check if process is in existence
19
+ # The simplest way to do this is to send signal '0'
20
+ # (which is a single system call) that doesn't actually
21
+ # send a signal
22
+ begin
23
+ Process.kill(0, self.pid)
24
+ return true
25
+ rescue Errno::ESRCH
26
+ return false
27
+ rescue ::Exception # for example on EPERM (process exists but does not belong to us)
28
+ return true
29
+ #rescue Errno::EPERM
30
+ # return false
31
+ end
32
+ end
33
+
34
+ # Return the pid contained in the pidfile, or nil
35
+ def pid
36
+ return nil unless self.exists?
37
+
38
+ File.open( @path ) { |f|
39
+ return f.gets.to_i
40
+ }
41
+ end
42
+
43
+ def ensure_stopped!
44
+ if self.running?
45
+ puts "Process already running with id #{self.pid}"
46
+ exit 1
47
+ end
48
+ end
49
+
50
+ def cleanup
51
+ File.delete( @path ) rescue Errno::ENOENT
52
+ end
53
+ alias zap cleanup
54
+
55
+ def write!
56
+ File.open( @path, 'w' ) { |f|
57
+ f.puts Process.pid
58
+ }
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,119 @@
1
+ module DaemonKit
2
+ # Class that cleanly abstracts away the different remote participants in
3
+ # ruote and allows daemon writers to just worry about processing workitems
4
+ # without worrying over the transport mechanism or anything else...
5
+ class RuoteParticipants
6
+
7
+ class << self
8
+
9
+ # Configure this daemon as a remote participant to ruote.
10
+ def configure(&block)
11
+ instance.configure(&block)
12
+ end
13
+
14
+ # Activate and run the remote participant code, calling the optional
15
+ # block for additional daemon logic.
16
+ def run(&block)
17
+ instance.run(&block)
18
+ end
19
+
20
+ private :new
21
+
22
+ def instance
23
+ @instance ||= new
24
+ end
25
+
26
+ private
27
+
28
+ def instance=( obj )
29
+ @instance = obj
30
+ end
31
+ end
32
+
33
+ attr_reader :participants
34
+
35
+ def initialize
36
+ @transports = []
37
+ @participants = {}
38
+
39
+ @configuration = Config.load('ruote')
40
+ end
41
+
42
+ # Yields +self+ and configures the remote participants
43
+ def configure(&block)
44
+ block.call( self )
45
+
46
+ @transports.freeze
47
+ @participants.freeze
48
+ end
49
+
50
+ # Enable the use of a specific transport for workitems. Can be :amqp to use
51
+ # the AMQPParticipant/AMQPListener pair in ruote.
52
+ def use( transport )
53
+ @transports << transport
54
+ end
55
+
56
+ # Register classes as pseudo-participants. Two styles of registration are
57
+ # supported:
58
+ #
59
+ # register( Foo )
60
+ # register( 'short', ShortParticipant )
61
+ #
62
+ # The first format uses the class name (downcased and underscored) as the
63
+ # key for identifying the pseudo-participant, the second uses the the
64
+ # provided key.
65
+ #
66
+ # Pseudo-participant classes are instantiated when registered, and the
67
+ # instances are re-used.
68
+ def register( *args )
69
+ key, klass = if args.size == 1
70
+ [ underscore( args.first.to_s ), args.first ]
71
+ else
72
+ [ args[0].to_s, args[1] ]
73
+ end
74
+
75
+ @participants[ key ] = klass.new
76
+ end
77
+
78
+ # Run the participants
79
+ def run(&block)
80
+ run_amqp! if @transports.include?( :amqp )
81
+ end
82
+
83
+ private
84
+
85
+ def run_amqp!
86
+ AMQP.run do
87
+ mq = ::MQ.new
88
+ queues = @configuration['amqp']['queues'].to_a
89
+
90
+ queues.each do |q|
91
+ DaemonKit.logger.debug("Subscribing to #{q} for workitems")
92
+
93
+ cmdq = mq.queue( q, :durable => true )
94
+ cmdq.subscribe( :ack => true ) do |header, message|
95
+ safely do
96
+ DaemonKit.logger.debug("Received workitem: #{message.inspect}")
97
+
98
+ RuoteWorkitem.process( :amqp, message )
99
+
100
+ DaemonKit.logger.debug("Processed workitem.")
101
+
102
+ header.ack
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ # Shamelessly lifted from the ActiveSupport inflector
110
+ def underscore(camel_cased_word)
111
+ camel_cased_word.to_s.gsub(/::/, '/').
112
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
113
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
114
+ tr("-", "_").
115
+ downcase
116
+ end
117
+ end
118
+
119
+ end
@@ -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