watercooling 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Asynchronous webhook queueing with skinny daemon support.
4
4
 
5
- Inspired by @progriums Hookah and Watercoolr (http://watercoolr.nuklei.com/).
5
+ Inspired by Watercoolr (http://watercoolr.nuklei.com/) and @progrium's Hookah.
6
6
 
7
7
  # Installing
8
8
 
@@ -15,7 +15,7 @@ From source:
15
15
  rake build
16
16
  sudo rake install
17
17
 
18
- # Start
18
+ # Starting
19
19
 
20
20
  Start as a regular server:
21
21
 
@@ -25,20 +25,32 @@ Start as a daemon:
25
25
 
26
26
  watercooling start -d
27
27
 
28
- # Use
28
+ # Using
29
29
 
30
- Send out a webhook to be asynchronous queued and sent.
30
+ Required param:
31
31
 
32
- The _url param is required. All other params are optional.
32
+ * _url [webhook end destination]
33
+
34
+ Optional params:
35
+
36
+ * _callback [url for POST request on SUCCESS]
37
+ * _errback [url for POST request on FAILURE]
38
+
39
+ Example:
33
40
 
34
- → POST /dispatch { '_url':'http://www.postbin.org/1jp87ds', 'param1':'value1', etc.. }
41
+ → POST /dispatch { '_url':'http://www.postbin.org/1jp87ds', '_callback':'http://callbackaddress.com', '_errback':'http://errbackaddress.com', etc.. }
35
42
 
36
43
  # Todo
37
44
 
38
45
  * pub/sub support
46
+ * true evented support
39
47
  * web interface
40
48
  * application configuration
41
- * success and error callbacks
49
+ * <del>success and error callbacks</del>
50
+
51
+ # Helping
52
+
53
+ Help me make this a better product. Contact me at linuxsable@gmail.com.
42
54
 
43
55
  # Copyright
44
56
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.3
@@ -4,6 +4,8 @@ class Webhook
4
4
  property :id, Serial
5
5
  property :queued, Boolean, :default => false
6
6
  property :url, String
7
+ property :callback, String
8
+ property :errback, String
7
9
  property :sent, Boolean, :default => false
8
10
  property :sent_at, DateTime
9
11
  property :send_error, String
@@ -4,5 +4,5 @@ require 'rest-client'
4
4
  url = "http://localhost:2003"
5
5
 
6
6
  puts "sending webhook"
7
- resp = RestClient.post(url + '/dispatch', :_url => ARGV[0], :test_param1 => 'test1', :test_param2 => 'test2')
7
+ resp = RestClient.post(url + '/dispatch', :_url => ARGV[0], :test_param1 => 'test1', :_callback => ARGV[0], :_errback => ARGV[0])
8
8
  puts resp
@@ -9,10 +9,12 @@ class WebhookQueue
9
9
  EM.add_periodic_timer(1) {
10
10
  send_current_webhooks
11
11
  }
12
+ puts "Watercoolr is cooling..."
12
13
  end
13
14
 
14
- # Loop through all pending messages and send them.
15
- # Allow a max retry of @@retries
15
+ private
16
+
17
+ # Currently this method is blocking.
16
18
  def send_current_webhooks
17
19
  queued_webhooks = Webhook.all(:queued => true, :sent => false)
18
20
  queued_webhooks.each do |webhook|
@@ -20,21 +22,54 @@ class WebhookQueue
20
22
  while trys > 0
21
23
  num_tries = 4 - trys
22
24
  begin
23
- # Grab all the webhook params and send em
24
- params = {}
25
- webhook.params.each { |param| params[param.name] = param.value }
26
- response = HTTPClient.post(webhook.url, JSON.generate(params))
25
+ send_webhook(webhook)
27
26
  webhook.update!(:sent => true, :sent_at => Time.now, :queued => false, :send_num_tries => num_tries)
27
+ callback(webhook)
28
28
  break
29
29
  rescue => e
30
30
  trys -= 1
31
- sleep 1
32
31
  if trys == 0
33
32
  # Failed to send. Take it off the queue and log error.
34
33
  webhook.update!(:sent => false, :queued => false, :send_error => e, :send_num_tries => num_tries)
34
+ errback(webhook)
35
35
  end
36
36
  end
37
37
  end
38
38
  end
39
39
  end
40
+
41
+ # Fire off the webhook
42
+ def send_webhook(webhook)
43
+ params = {}
44
+ webhook.params.each { |param| params[param.name] = param.value }
45
+ HTTPClient.post(webhook.url, params)
46
+ end
47
+
48
+ # Send a POST back to user on SUCCESS if callback url supplied
49
+ def callback(webhook)
50
+ return false if webhook.callback.nil?
51
+ operation = proc {
52
+ HTTPClient.post(webhook.callback,
53
+ :status => 'OK',
54
+ :id => webhook.id,
55
+ :sent_at => webhook.sent_at.to_time.to_i,
56
+ :send_num_tries => webhook.send_num_tries
57
+ )
58
+ }
59
+ EM.defer(operation)
60
+ end
61
+
62
+ # Send a POST back to user on ERROR if errback url supplied
63
+ def errback(webhook)
64
+ return false if webhook.errback.nil?
65
+ operation = proc {
66
+ HTTPClient.post(webhook.errback,
67
+ :status => 'FAIL',
68
+ :id => webhook.id,
69
+ :send_error => webhook.send_error,
70
+ :send_num_tries => webhook.send_num_tries
71
+ )
72
+ }
73
+ EM.defer(operation)
74
+ end
40
75
  end
data/lib/watercooling.rb CHANGED
@@ -20,8 +20,12 @@ require File.dirname(__FILE__) + '/watercooling/models/param'
20
20
  class Watercooling < Sinatra::Base
21
21
  # Database config
22
22
  configure :production, :development do
23
- db = "sqlite3:///#{Dir.pwd}/lib/watercooling.sqlite3"
24
- DataMapper.setup(:default, db)
23
+ db_path = "#{ENV['HOME']}/.watercooling"
24
+ if !File.exist?(db_path)
25
+ puts "Creating directory \"#{ENV['HOME']}/.watercooling\"."
26
+ FileUtils.mkdir(db_path)
27
+ end
28
+ DataMapper.setup(:default, 'sqlite3:///' + db_path + '/database.sqlite3')
25
29
  end
26
30
 
27
31
  configure :test do
@@ -39,7 +43,7 @@ class Watercooling < Sinatra::Base
39
43
  end
40
44
 
41
45
  configure do
42
- # Fire up the message queue
46
+ # Fire up the webhook queue
43
47
  Thread.new do
44
48
  until EM.reactor_running?
45
49
  sleep 1
@@ -57,27 +61,31 @@ class Watercooling < Sinatra::Base
57
61
  erb :index
58
62
  end
59
63
 
60
- # Accept a webhook with a special field of _url to be queued to be sent out.
64
+ # Accept a webhook with a special to be queued to be sent out
61
65
  post '/dispatch' do
62
66
  content_type :json
63
67
  response = false
64
-
68
+
65
69
  if params[:_url]
66
- if webhook = Webhook.create(:queued => true, :url => params[:_url])
67
- params.each do |key, value|
68
- unless key == '_url'
69
- response = webhook.params.create(:name => key, :value => value)
70
- end
70
+ webhook = Webhook.create(
71
+ :queued => true,
72
+ :url => params[:_url],
73
+ :callback => params[:_callback],
74
+ :errback => params[:_errback]
75
+ )
76
+
77
+ meta_params = ['_url', '_callback', '_errback']
78
+ params.each do |key, value|
79
+ unless meta_params.include?(key)
80
+ response = webhook.params.create(:name => key, :value => value)
71
81
  end
72
- else
73
- fail_reason = "Couldn't queue webhook."
74
82
  end
75
83
  else
76
84
  fail_reason = '_url post param required.'
77
85
  end
78
86
 
79
87
  if response
80
- { :status => 'OK' }.to_json
88
+ { :status => 'OK', :id => webhook.id }.to_json
81
89
  else
82
90
  { :status => 'FAIL', :reason => fail_reason }.to_json
83
91
  end
@@ -7,19 +7,34 @@ URL = 'http://localhost:2003'
7
7
  # address of your app before running the tests.
8
8
  describe "watercooling" do
9
9
  it "should add webhook" do
10
- response = RestClient.post(URL + '/dispatch', :_url => 'http://google.com', :test_param => 'test')
10
+ response = RestClient.post(URL + '/dispatch',
11
+ :_url => 'http://google.com',
12
+ :_callback => 'http://google.com',
13
+ :_errback => 'http://google.com',
14
+ :test_param => 'test'
15
+ )
11
16
  JSON.parse(response)['status'].should == 'OK'
12
17
  end
13
18
 
14
19
  it "should fail if _url is missing" do
15
- response = RestClient.post(URL + '/dispatch', :url => 'http://google.com', :test_param => 'test')
20
+ response = RestClient.post(URL + '/dispatch',
21
+ :url => 'http://google.com',
22
+ :_callback => 'http://google.com',
23
+ :_errback => 'http://google.com',
24
+ :test_param => 'test'
25
+ )
16
26
  JSON.parse(response)['status'].should == 'FAIL'
17
27
  end
18
28
 
19
29
  it "should add webhook to queue" do
20
30
  _url = 'http://asdf.com'
21
31
 
22
- RestClient.post(URL + '/dispatch', :_url => _url, :test_param => 'test')
32
+ response = RestClient.post(URL + '/dispatch',
33
+ :_url => _url,
34
+ :_callback => 'http://google.com',
35
+ :_errback => 'http://google.com',
36
+ :test_param => 'test'
37
+ )
23
38
  webhook = Webhook.first(:url => _url)
24
39
  webhook.id.should > 0
25
40
 
data/watercooling.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{watercooling}
8
- s.version = "0.0.2"
8
+ s.version = "0.0.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["@_ty"]
12
- s.date = %q{2010-09-01}
12
+ s.date = %q{2010-09-12}
13
13
  s.default_executable = %q{watercooling}
14
14
  s.description = %q{Asynchronous webhook queueing with skinny daemon support.}
15
15
  s.email = %q{linuxsable@gmail.com}
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: watercooling
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 25
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 0
8
- - 2
9
- version: 0.0.2
9
+ - 3
10
+ version: 0.0.3
10
11
  platform: ruby
11
12
  authors:
12
13
  - "@_ty"
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-09-01 00:00:00 -07:00
18
+ date: 2010-09-12 00:00:00 -07:00
18
19
  default_executable: watercooling
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
@@ -25,6 +26,7 @@ dependencies:
25
26
  requirements:
26
27
  - - ">="
27
28
  - !ruby/object:Gem::Version
29
+ hash: 13
28
30
  segments:
29
31
  - 1
30
32
  - 2
@@ -76,6 +78,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
76
78
  requirements:
77
79
  - - ">="
78
80
  - !ruby/object:Gem::Version
81
+ hash: 3
79
82
  segments:
80
83
  - 0
81
84
  version: "0"
@@ -84,6 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
87
  requirements:
85
88
  - - ">="
86
89
  - !ruby/object:Gem::Version
90
+ hash: 3
87
91
  segments:
88
92
  - 0
89
93
  version: "0"