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.
- data/.document +5 -0
- data/.gitignore +22 -0
- data/LICENSE +20 -0
- data/README.rdoc +18 -0
- data/Rakefile +78 -0
- data/TODO +1 -0
- data/VERSION +1 -0
- data/apphunkd.gemspec +258 -0
- data/bin/apphunkd +4 -0
- data/config/arguments.rb +12 -0
- data/config/boot.rb +68 -0
- data/config/environment.rb +23 -0
- data/config/environments/development.rb +2 -0
- data/config/environments/production.rb +2 -0
- data/config/environments/test.rb +2 -0
- data/config/post-daemonize/readme +5 -0
- data/config/pre-daemonize/readme +12 -0
- data/config/pre-daemonize/requires.rb +2 -0
- data/lib/apphunkd.rb +25 -0
- data/lib/apphunkd/api.rb +5 -0
- data/lib/apphunkd/api/service.rb +27 -0
- data/lib/apphunkd/queue.rb +96 -0
- data/lib/apphunkd/remote.rb +29 -0
- data/lib/apphunkd/remote/result.rb +15 -0
- data/libexec/apphunkd-daemon.rb +13 -0
- data/script/console +3 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/lib/apphunkd/api/service_spec.rb +47 -0
- data/spec/lib/apphunkd/queue_spec.rb +129 -0
- data/spec/lib/apphunkd/remote_spec.rb +61 -0
- data/spec/lib/apphunkd_spec.rb +50 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +13 -0
- data/support/apphunkd.initd +47 -0
- data/support/apphunkd.monitrc +3 -0
- data/tasks/rspec.rake +21 -0
- data/vendor/daemon-kit/Configuration.txt +102 -0
- data/vendor/daemon-kit/Deployment.txt +113 -0
- data/vendor/daemon-kit/History.txt +97 -0
- data/vendor/daemon-kit/Logging.txt +92 -0
- data/vendor/daemon-kit/Manifest.txt +166 -0
- data/vendor/daemon-kit/PostInstall.txt +6 -0
- data/vendor/daemon-kit/README.rdoc +130 -0
- data/vendor/daemon-kit/Rakefile +37 -0
- data/vendor/daemon-kit/RuoteParticipants.txt +113 -0
- data/vendor/daemon-kit/TODO.txt +37 -0
- data/vendor/daemon-kit/app_generators/daemon_kit/USAGE +7 -0
- data/vendor/daemon-kit/app_generators/daemon_kit/daemon_kit_generator.rb +161 -0
- data/vendor/daemon-kit/app_generators/daemon_kit/templates/README +48 -0
- data/vendor/daemon-kit/app_generators/daemon_kit/templates/Rakefile +6 -0
- data/vendor/daemon-kit/app_generators/daemon_kit/templates/bin/daemon.erb +7 -0
- data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/arguments.rb +12 -0
- data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/boot.rb +68 -0
- data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/environment.rb +23 -0
- data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/environments/development.rb +2 -0
- data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/environments/production.rb +2 -0
- data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/environments/test.rb +2 -0
- data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/post-daemonize/readme +5 -0
- data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/pre-daemonize/readme +12 -0
- data/vendor/daemon-kit/app_generators/daemon_kit/templates/lib/daemon.rb +2 -0
- data/vendor/daemon-kit/app_generators/daemon_kit/templates/libexec/daemon.erb +18 -0
- data/vendor/daemon-kit/app_generators/daemon_kit/templates/script/console +3 -0
- data/vendor/daemon-kit/app_generators/daemon_kit/templates/script/destroy +14 -0
- data/vendor/daemon-kit/app_generators/daemon_kit/templates/script/generate +14 -0
- data/vendor/daemon-kit/bin/daemon_kit +18 -0
- data/vendor/daemon-kit/daemon_generators/amqp/USAGE +5 -0
- data/vendor/daemon-kit/daemon_generators/amqp/amqp_generator.rb +65 -0
- data/vendor/daemon-kit/daemon_generators/amqp/templates/config/amqp.yml +28 -0
- data/vendor/daemon-kit/daemon_generators/amqp/templates/config/initializers/amqp.rb +7 -0
- data/vendor/daemon-kit/daemon_generators/amqp/templates/libexec/daemon.rb +37 -0
- data/vendor/daemon-kit/daemon_generators/cron/USAGE +5 -0
- data/vendor/daemon-kit/daemon_generators/cron/cron_generator.rb +64 -0
- data/vendor/daemon-kit/daemon_generators/cron/templates/config/initializers/cron.rb +11 -0
- data/vendor/daemon-kit/daemon_generators/cron/templates/libexec/daemon.rb +43 -0
- data/vendor/daemon-kit/daemon_generators/cucumber/USAGE +11 -0
- data/vendor/daemon-kit/daemon_generators/cucumber/cucumber_generator.rb +38 -0
- data/vendor/daemon-kit/daemon_generators/cucumber/templates/cucumber +8 -0
- data/vendor/daemon-kit/daemon_generators/cucumber/templates/cucumber.rake +13 -0
- data/vendor/daemon-kit/daemon_generators/cucumber/templates/cucumber_environment.rb +2 -0
- data/vendor/daemon-kit/daemon_generators/cucumber/templates/env.rb +7 -0
- data/vendor/daemon-kit/daemon_generators/deploy_capistrano/deploy_capistrano_generator.rb +35 -0
- data/vendor/daemon-kit/daemon_generators/deploy_capistrano/templates/Capfile +10 -0
- data/vendor/daemon-kit/daemon_generators/deploy_capistrano/templates/USAGE +10 -0
- data/vendor/daemon-kit/daemon_generators/deploy_capistrano/templates/config/deploy.rb +53 -0
- data/vendor/daemon-kit/daemon_generators/deploy_capistrano/templates/config/deploy/production.rb +6 -0
- data/vendor/daemon-kit/daemon_generators/deploy_capistrano/templates/config/deploy/staging.rb +6 -0
- data/vendor/daemon-kit/daemon_generators/deploy_capistrano/templates/config/environments/staging.rb +0 -0
- data/vendor/daemon-kit/daemon_generators/jabber/USAGE +5 -0
- data/vendor/daemon-kit/daemon_generators/jabber/jabber_generator.rb +65 -0
- data/vendor/daemon-kit/daemon_generators/jabber/templates/config/initializers/jabber.rb +7 -0
- data/vendor/daemon-kit/daemon_generators/jabber/templates/config/jabber.yml +26 -0
- data/vendor/daemon-kit/daemon_generators/jabber/templates/libexec/daemon.rb +27 -0
- data/vendor/daemon-kit/daemon_generators/nanite_agent/USAGE +5 -0
- data/vendor/daemon-kit/daemon_generators/nanite_agent/nanite_agent_generator.rb +68 -0
- data/vendor/daemon-kit/daemon_generators/nanite_agent/templates/config/initializers/nanite_agent.rb +6 -0
- data/vendor/daemon-kit/daemon_generators/nanite_agent/templates/config/nanite.yml +35 -0
- data/vendor/daemon-kit/daemon_generators/nanite_agent/templates/lib/actors/sample.rb +11 -0
- data/vendor/daemon-kit/daemon_generators/nanite_agent/templates/libexec/daemon.rb +31 -0
- data/vendor/daemon-kit/daemon_generators/rspec/USAGE +5 -0
- data/vendor/daemon-kit/daemon_generators/rspec/rspec_generator.rb +55 -0
- data/vendor/daemon-kit/daemon_generators/rspec/templates/spec.rb +11 -0
- data/vendor/daemon-kit/daemon_generators/rspec/templates/spec/spec.opts +1 -0
- data/vendor/daemon-kit/daemon_generators/rspec/templates/spec/spec_helper.rb +21 -0
- data/vendor/daemon-kit/daemon_generators/rspec/templates/tasks/rspec.rake +21 -0
- data/vendor/daemon-kit/daemon_generators/ruote/USAGE +5 -0
- data/vendor/daemon-kit/daemon_generators/ruote/ruote_generator.rb +67 -0
- data/vendor/daemon-kit/daemon_generators/ruote/templates/config/amqp.yml +30 -0
- data/vendor/daemon-kit/daemon_generators/ruote/templates/config/initializers/ruote.rb +13 -0
- data/vendor/daemon-kit/daemon_generators/ruote/templates/config/ruote.yml +23 -0
- data/vendor/daemon-kit/daemon_generators/ruote/templates/lib/daemon.rb +4 -0
- data/vendor/daemon-kit/daemon_generators/ruote/templates/lib/sample.rb +26 -0
- data/vendor/daemon-kit/daemon_generators/ruote/templates/libexec/daemon.rb +33 -0
- data/vendor/daemon-kit/lib/daemon_kit.rb +54 -0
- data/vendor/daemon-kit/lib/daemon_kit/abstract_logger.rb +235 -0
- data/vendor/daemon-kit/lib/daemon_kit/amqp.rb +38 -0
- data/vendor/daemon-kit/lib/daemon_kit/application.rb +187 -0
- data/vendor/daemon-kit/lib/daemon_kit/arguments.rb +165 -0
- data/vendor/daemon-kit/lib/daemon_kit/commands/console.rb +38 -0
- data/vendor/daemon-kit/lib/daemon_kit/config.rb +108 -0
- data/vendor/daemon-kit/lib/daemon_kit/console_daemon.rb +2 -0
- data/vendor/daemon-kit/lib/daemon_kit/core_ext.rb +1 -0
- data/vendor/daemon-kit/lib/daemon_kit/core_ext/configurable.rb +96 -0
- data/vendor/daemon-kit/lib/daemon_kit/core_ext/string.rb +22 -0
- data/vendor/daemon-kit/lib/daemon_kit/cron.rb +48 -0
- data/vendor/daemon-kit/lib/daemon_kit/cucumber/world.rb +38 -0
- data/vendor/daemon-kit/lib/daemon_kit/deployment/capistrano.rb +482 -0
- data/vendor/daemon-kit/lib/daemon_kit/em.rb +43 -0
- data/vendor/daemon-kit/lib/daemon_kit/error_handlers/base.rb +32 -0
- data/vendor/daemon-kit/lib/daemon_kit/error_handlers/hoptoad.rb +61 -0
- data/vendor/daemon-kit/lib/daemon_kit/error_handlers/mail.rb +85 -0
- data/vendor/daemon-kit/lib/daemon_kit/exceptions.rb +8 -0
- data/vendor/daemon-kit/lib/daemon_kit/initializer.rb +438 -0
- data/vendor/daemon-kit/lib/daemon_kit/jabber.rb +170 -0
- data/vendor/daemon-kit/lib/daemon_kit/nanite.rb +7 -0
- data/vendor/daemon-kit/lib/daemon_kit/nanite/agent.rb +56 -0
- data/vendor/daemon-kit/lib/daemon_kit/pid_file.rb +61 -0
- data/vendor/daemon-kit/lib/daemon_kit/ruote_participants.rb +119 -0
- data/vendor/daemon-kit/lib/daemon_kit/ruote_pseudo_participant.rb +68 -0
- data/vendor/daemon-kit/lib/daemon_kit/ruote_workitem.rb +169 -0
- data/vendor/daemon-kit/lib/daemon_kit/safety.rb +85 -0
- data/vendor/daemon-kit/lib/daemon_kit/tasks.rb +2 -0
- data/vendor/daemon-kit/lib/daemon_kit/tasks/environment.rake +10 -0
- data/vendor/daemon-kit/lib/daemon_kit/tasks/framework.rake +120 -0
- data/vendor/daemon-kit/lib/daemon_kit/tasks/god.rake +62 -0
- data/vendor/daemon-kit/lib/daemon_kit/tasks/log.rake +8 -0
- data/vendor/daemon-kit/lib/daemon_kit/tasks/monit.rake +29 -0
- data/vendor/daemon-kit/script/console +10 -0
- data/vendor/daemon-kit/script/destroy +14 -0
- data/vendor/daemon-kit/script/generate +14 -0
- data/vendor/daemon-kit/script/txt2html +71 -0
- data/vendor/daemon-kit/spec/abstract_logger_spec.rb +126 -0
- data/vendor/daemon-kit/spec/argument_spec.rb +70 -0
- data/vendor/daemon-kit/spec/config_spec.rb +79 -0
- data/vendor/daemon-kit/spec/configurable_spec.rb +56 -0
- data/vendor/daemon-kit/spec/daemon_kit_spec.rb +7 -0
- data/vendor/daemon-kit/spec/error_handlers_spec.rb +23 -0
- data/vendor/daemon-kit/spec/fixtures/env.yml +15 -0
- data/vendor/daemon-kit/spec/fixtures/noenv.yml +4 -0
- data/vendor/daemon-kit/spec/initializer_spec.rb +26 -0
- data/vendor/daemon-kit/spec/spec.opts +1 -0
- data/vendor/daemon-kit/spec/spec_helper.rb +27 -0
- data/vendor/daemon-kit/tasks/rspec.rake +21 -0
- data/vendor/daemon-kit/templates/god/god.erb +69 -0
- data/vendor/daemon-kit/templates/monit/monit.erb +14 -0
- data/vendor/daemon-kit/test/test_amqp_generator.rb +48 -0
- data/vendor/daemon-kit/test/test_cron_generator.rb +45 -0
- data/vendor/daemon-kit/test/test_daemon-kit_generator.rb +84 -0
- data/vendor/daemon-kit/test/test_daemon_kit_config.rb +28 -0
- data/vendor/daemon-kit/test/test_deploy_capistrano_generator.rb +48 -0
- data/vendor/daemon-kit/test/test_generator_helper.rb +29 -0
- data/vendor/daemon-kit/test/test_helper.rb +7 -0
- data/vendor/daemon-kit/test/test_jabber_generator.rb +49 -0
- data/vendor/daemon-kit/test/test_nanite_agent_generator.rb +49 -0
- data/vendor/daemon-kit/test/test_ruote_generator.rb +45 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail.rb +5 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/address.rb +426 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/attachments.rb +46 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/base64.rb +46 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/compat.rb +41 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/config.rb +67 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/core_extensions.rb +63 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/encode.rb +581 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/header.rb +960 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/index.rb +9 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/interface.rb +1130 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/loader.rb +3 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/mail.rb +578 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/mailbox.rb +495 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/main.rb +6 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/mbox.rb +3 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/net.rb +248 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/obsolete.rb +132 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/parser.rb +1476 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/port.rb +379 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/quoting.rb +118 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/require_arch.rb +58 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/scanner.rb +49 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/scanner_r.rb +261 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/stringio.rb +280 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/utils.rb +337 -0
- data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/version.rb +39 -0
- data/vendor/daemon-kit/vendor/tmail.rb +13 -0
- metadata +281 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Be sure to restart your daemon when you modify this file
|
|
2
|
+
|
|
3
|
+
# Uncomment below to force your daemon into production mode
|
|
4
|
+
#ENV['DAEMON_ENV'] ||= 'production'
|
|
5
|
+
|
|
6
|
+
# Boot up
|
|
7
|
+
require File.join(File.dirname(__FILE__), 'boot')
|
|
8
|
+
|
|
9
|
+
DaemonKit::Initializer.run do |config|
|
|
10
|
+
|
|
11
|
+
# The name of the daemon as reported by process monitoring tools
|
|
12
|
+
config.daemon_name = 'apphunkd'
|
|
13
|
+
|
|
14
|
+
# Force the daemon to be killed after X seconds from asking it to
|
|
15
|
+
# config.force_kill_wait = 30
|
|
16
|
+
|
|
17
|
+
# Log backraces when a thread/daemon dies (Recommended)
|
|
18
|
+
# config.backtraces = true
|
|
19
|
+
|
|
20
|
+
# Configure the safety net (see DaemonKit::Safety)
|
|
21
|
+
# config.safety_net.handler = :mail # (or :hoptoad )
|
|
22
|
+
# config.safety_net.mail.host = 'localhost'
|
|
23
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# You can place files in here to be loaded before the code is daemonized.
|
|
2
|
+
#
|
|
3
|
+
# DaemonKit looks for a file named '<config.daemon_name>.rb' and loads
|
|
4
|
+
# that file first, and inside a DaemonKit::Initializer block. The
|
|
5
|
+
# remaning files then simply required into the running process.
|
|
6
|
+
#
|
|
7
|
+
# These files are mostly useful for operations that should fail blatantly
|
|
8
|
+
# before daemonizing, like loading gems.
|
|
9
|
+
#
|
|
10
|
+
# Be careful not to open any form of IO in here and expecting it to be
|
|
11
|
+
# open inside the running daemon since all IO instances are closed when
|
|
12
|
+
# daemonizing (including STDIN, STDOUT & STDERR).
|
data/lib/apphunkd.rb
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Apphunkd
|
|
2
|
+
|
|
3
|
+
autoload :API, 'apphunkd/api'
|
|
4
|
+
autoload :Queue, 'apphunkd/queue'
|
|
5
|
+
autoload :Remote, 'apphunkd/remote'
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
|
|
9
|
+
attr_accessor :queue
|
|
10
|
+
|
|
11
|
+
def run!
|
|
12
|
+
initialize_queue
|
|
13
|
+
initialize_api_service
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def initialize_queue
|
|
17
|
+
self.queue = Queue.new
|
|
18
|
+
self.queue.activate!
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def initialize_api_service
|
|
22
|
+
API::Service.run! :port => '8212', :host => '127.0.0.1'
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
data/lib/apphunkd/api.rb
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Apphunkd
|
|
2
|
+
module API
|
|
3
|
+
|
|
4
|
+
class Service < Sinatra::Base
|
|
5
|
+
set :sessions, false
|
|
6
|
+
set :environment, DaemonKit.env.to_sym
|
|
7
|
+
|
|
8
|
+
post '/api/messages' do
|
|
9
|
+
if Apphunkd.queue.store(params)
|
|
10
|
+
status 201
|
|
11
|
+
else
|
|
12
|
+
status 400
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
not_found do
|
|
17
|
+
"Not found. The requested resources doesn't exist."
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
error do
|
|
21
|
+
'Hoppla. Some internal stuff has crashed.'
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
module Apphunkd
|
|
2
|
+
class Queue
|
|
3
|
+
|
|
4
|
+
attr_accessor :items
|
|
5
|
+
attr_accessor :mutex
|
|
6
|
+
attr_accessor :worker
|
|
7
|
+
|
|
8
|
+
def initialize
|
|
9
|
+
@items = []
|
|
10
|
+
@mutex = Mutex.new
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def activate!
|
|
14
|
+
@worker = initialize_worker
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def store(message = {})
|
|
18
|
+
return false if message[:body].blank? || message[:token].blank?
|
|
19
|
+
message[:stored_at] = Time.now
|
|
20
|
+
|
|
21
|
+
@mutex.synchronize do
|
|
22
|
+
@items = @items[-9999..-1] if @items.size >= 9999
|
|
23
|
+
@items << message
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
@worker.wakeup
|
|
27
|
+
return true
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def initialize_worker
|
|
31
|
+
Thread.new do
|
|
32
|
+
begin
|
|
33
|
+
loop do
|
|
34
|
+
unless @items.empty?
|
|
35
|
+
items = get_items_from_stack
|
|
36
|
+
items.each do |item|
|
|
37
|
+
result = push_item_to_remote_service(item)
|
|
38
|
+
if result.status == :ok
|
|
39
|
+
case result.response.code
|
|
40
|
+
when '201'
|
|
41
|
+
# Everything fine
|
|
42
|
+
when '400', '403'
|
|
43
|
+
log_error "Remote Service refused to store item: #{result.response.code} / #{result.response.body}. Dropped."
|
|
44
|
+
else
|
|
45
|
+
put_item_to_stack(item)
|
|
46
|
+
log_error "Remote Service went crazy. Put item back in queue: #{result.response.code} / #{result.response.body}"
|
|
47
|
+
end
|
|
48
|
+
else
|
|
49
|
+
put_item_to_stack(item)
|
|
50
|
+
log_error "Could not push to Remote Service: Connection Error. Put item back in queue."
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
sleep
|
|
55
|
+
end
|
|
56
|
+
rescue => e
|
|
57
|
+
log_error "Error: #{e}"
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def get_items_from_stack
|
|
66
|
+
copied_items = []
|
|
67
|
+
@mutex.synchronize do
|
|
68
|
+
copied_items = @items.dup
|
|
69
|
+
@items.clear
|
|
70
|
+
end
|
|
71
|
+
return copied_items
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def put_item_to_stack(item)
|
|
75
|
+
@mutex.synchronize { @items << item }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def push_item_to_remote_service(item)
|
|
79
|
+
url = generate_api_messages_url(item.delete('token'))
|
|
80
|
+
result = Apphunkd::Remote.post(url, item, 300)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def generate_api_messages_url(token)
|
|
84
|
+
path = "api/v1/#{token}/messages"
|
|
85
|
+
if DaemonKit.env.to_s == 'production'
|
|
86
|
+
"http://apphunk.com/#{path}"
|
|
87
|
+
else
|
|
88
|
+
"http://apphunk.local/#{path}"
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def log_error(message)
|
|
93
|
+
DaemonKit.logger.info message
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'net/http'
|
|
2
|
+
require 'timeout'
|
|
3
|
+
require 'uri'
|
|
4
|
+
|
|
5
|
+
module Apphunkd
|
|
6
|
+
module Remote
|
|
7
|
+
|
|
8
|
+
autoload :Result, 'apphunkd/remote/result'
|
|
9
|
+
|
|
10
|
+
class << self
|
|
11
|
+
|
|
12
|
+
def post(url, payload = {}, post_timeout = 30)
|
|
13
|
+
begin
|
|
14
|
+
Timeout.timeout(post_timeout) do
|
|
15
|
+
uri = URI.parse(url)
|
|
16
|
+
result = Remote::Result.new(:response => Net::HTTP.post_form(uri, payload))
|
|
17
|
+
result.status = :ok
|
|
18
|
+
return result
|
|
19
|
+
end
|
|
20
|
+
rescue SocketError
|
|
21
|
+
Remote::Result.new(:status => :connection_error)
|
|
22
|
+
rescue Timeout::Error
|
|
23
|
+
Remote::Result.new(:status => :timeout)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Do your post daemonization configuration here
|
|
2
|
+
|
|
3
|
+
# At minimum you need just the first line (without the block), or a lot
|
|
4
|
+
# of strange things might start happening...
|
|
5
|
+
DaemonKit::Application.running! do |config|
|
|
6
|
+
# Trap signals with blocks or procs
|
|
7
|
+
# config.trap( 'INT' ) do
|
|
8
|
+
# # do something clever
|
|
9
|
+
# end
|
|
10
|
+
# config.trap( 'TERM', Proc.new { puts 'Going down' } )
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
Apphunkd.run!
|
data/script/console
ADDED
data/script/destroy
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
require 'rubigen'
|
|
6
|
+
rescue LoadError
|
|
7
|
+
require 'rubygems'
|
|
8
|
+
require 'rubigen'
|
|
9
|
+
end
|
|
10
|
+
require 'rubigen/scripts/destroy'
|
|
11
|
+
|
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
|
13
|
+
RubiGen::Base.use_component_sources! [:daemon, :test_unit]
|
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
require 'rubigen'
|
|
6
|
+
rescue LoadError
|
|
7
|
+
require 'rubygems'
|
|
8
|
+
require 'rubigen'
|
|
9
|
+
end
|
|
10
|
+
require 'rubigen/scripts/generate'
|
|
11
|
+
|
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
|
13
|
+
RubiGen::Base.use_component_sources! [:daemon]
|
|
14
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../spec_helper.rb'
|
|
2
|
+
require 'rack/test'
|
|
3
|
+
|
|
4
|
+
describe Apphunkd::API::Service do
|
|
5
|
+
include Rack::Test::Methods
|
|
6
|
+
|
|
7
|
+
def app
|
|
8
|
+
Apphunkd::API::Service
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
before(:each) do
|
|
12
|
+
@queue = mock('Queue')
|
|
13
|
+
Apphunkd.queue = @queue
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'should be an instance of Sinatra::Base' do
|
|
17
|
+
Apphunkd::API::Service.new.should be_kind_of(Sinatra::Base)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe 'POST /api/messages' do
|
|
21
|
+
it 'should store a message in the queue' do
|
|
22
|
+
@queue.should_receive(:store).with("params" => 'test')
|
|
23
|
+
post '/api/messages', :params => 'test'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'should return status 201 on success' do
|
|
27
|
+
@queue.stub!(:store).and_return(true)
|
|
28
|
+
post '/api/messages', :params => 'test'
|
|
29
|
+
last_response.status.should eql(201)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'should return status 400 on failure' do
|
|
33
|
+
@queue.stub!(:store).and_return(false)
|
|
34
|
+
post '/api/messages'
|
|
35
|
+
last_response.status.should eql(400)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context 'error handling' do
|
|
40
|
+
it 'should return status 404 not found' do
|
|
41
|
+
post '/api/not-existing-resource'
|
|
42
|
+
last_response.status.should eql(404)
|
|
43
|
+
last_response.body.should include('Not found')
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper.rb'
|
|
2
|
+
|
|
3
|
+
describe Apphunkd::Queue do
|
|
4
|
+
before(:each) do
|
|
5
|
+
@queue = Apphunkd::Queue.new
|
|
6
|
+
@queue.stub!(:initialize_worker).and_return('worker')
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
describe '#initialize' do
|
|
10
|
+
it 'should create a new Mutex' do
|
|
11
|
+
@queue.mutex.should be_kind_of(Mutex)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'should prepare the items list' do
|
|
15
|
+
@queue.items.should be_kind_of(Array)
|
|
16
|
+
@queue.items.count.should be(0)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe '#activate!' do
|
|
22
|
+
it 'should initialize the worker' do
|
|
23
|
+
@queue.activate!
|
|
24
|
+
@queue.worker.should eql('worker')
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe '#store' do
|
|
29
|
+
before(:each) do
|
|
30
|
+
@queue.worker = mock('Worker instance')
|
|
31
|
+
@queue.worker.stub!(:wakeup)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'should return false if message or token is missing' do
|
|
35
|
+
@queue.store().should be_false
|
|
36
|
+
@queue.store(:token => 'test').should be_false
|
|
37
|
+
@queue.store(:body => 'test').should be_false
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'should wrap the store stuff into a mutex' do
|
|
41
|
+
@queue.mutex.should_receive(:synchronize)
|
|
42
|
+
store_message
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'should add stored_at to the message object' do
|
|
46
|
+
store_message
|
|
47
|
+
@message[:stored_at].should be_kind_of(Time)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'should add the message to the end of the items list' do
|
|
51
|
+
store_message
|
|
52
|
+
@queue.items.should include(@message)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'should remove the oldest messages from the list to ensure that there are at max 10000 messages queued' do
|
|
56
|
+
@queue.items = [1] * 10000
|
|
57
|
+
store_message
|
|
58
|
+
@queue.items.size.should eql(10000)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'should wakeup the worker after appending a message' do
|
|
62
|
+
@queue.worker.should_receive(:wakeup)
|
|
63
|
+
store_message
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'should return true after successfully storing a message' do
|
|
67
|
+
store_message.should be_true
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def store_message
|
|
71
|
+
@message = { :body => 'test', :token => 'test' }
|
|
72
|
+
@queue.store(@message)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
describe '#get_items_from_stack' do
|
|
77
|
+
before(:each) do
|
|
78
|
+
@queue.items = ["i1", "i2"]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it 'should create a local copy from the items array' do
|
|
82
|
+
@queue.items.stub!(:clear)
|
|
83
|
+
items_copy = @queue.send(:get_items_from_stack)
|
|
84
|
+
items_copy.should eql(@queue.items)
|
|
85
|
+
items_copy.object_id.should_not be(@queue.items.object_id)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it 'should synchronize via mutex during copy' do
|
|
89
|
+
@queue.mutex.should_receive(:synchronize)
|
|
90
|
+
@queue.send(:get_items_from_stack)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it 'should clear the original items array' do
|
|
94
|
+
@queue.send(:get_items_from_stack)
|
|
95
|
+
@queue.items.should be_empty
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
describe '#put_item_to_stack' do
|
|
100
|
+
it 'should append an item to the queue stack' do
|
|
101
|
+
@queue.send(:put_item_to_stack, 'i3')
|
|
102
|
+
@queue.items.should include('i3')
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it 'should synchronize via mutex during append' do
|
|
106
|
+
@queue.mutex.should_receive(:synchronize)
|
|
107
|
+
@queue.send(:put_item_to_stack, 'i3')
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
describe '#push_item_to_remote_service' do
|
|
112
|
+
before(:each) do
|
|
113
|
+
@item = { 'token' => 'secret', 'message' => 'hallo welt' }
|
|
114
|
+
@queue.stub!(:generate_api_messages_url).and_return('http://api.com/secret/')
|
|
115
|
+
Apphunkd::Remote.stub!(:post)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it "should generate the api url, including the item's token" do
|
|
119
|
+
@queue.should_receive(:generate_api_messages_url).with('secret')
|
|
120
|
+
@queue.send(:push_item_to_remote_service, @item)
|
|
121
|
+
@item.should_not include('token')
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "should post to the url, including the item" do
|
|
125
|
+
Apphunkd::Remote.should_receive(:post).with('http://api.com/secret/', { 'message' => 'hallo welt' }, 300)
|
|
126
|
+
@queue.send(:push_item_to_remote_service, @item)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|