Skip to content
Browse files

Merge pull request #116 by @cris

Conflicts:
	lib/airbrake.rb
	lib/airbrake/configuration.rb
  • Loading branch information...
2 parents 118e9e5 + 1111f11 commit 4b046f1844be0adf70ed2d37f73e7ae60018fd71 @shime shime committed Sep 3, 2012
Showing with 95 additions and 12 deletions.
  1. +22 −0 README.md
  2. +1 −8 lib/airbrake.rb
  3. +28 −4 lib/airbrake/configuration.rb
  4. +13 −0 test/configuration_test.rb
  5. +31 −0 test/notifier_test.rb
View
22 README.md
@@ -275,6 +275,28 @@ configuration.
*Ruby 1.9+. It does not support Ruby 1.8 because of its poor threading*
*support.*
+For implementing custom asynchronous send, provide block to `config.async`. It
+receives `notice` param. Pass it to `Airbrake.sender.send_to_airbrake` method
+to do actual delivery. In this way it's possible to move Airbrake notification
+even in background worker(e.g. Resque or Sidekiq).
+
+ # Thread-based asynchronous send
+ Airbrake.configure do |config|
+ ...
+ config.async do |notice|
+ Thread.new {
+ Airbrake.sender.send_to_airbrake(notice.to_xml)
+ }
+ end
+ end
+
+ # Resque-like configuration
+ Airbrake.configure do |config|
+ ...
+ config.async do |notice|
+ Resque.enqueue(AirbrakeDeliveryWorker, notice)
+ end
+ end
Tracking deployments in Airbrake
--------------------------------
View
9 lib/airbrake.rb
@@ -28,13 +28,6 @@ module Airbrake
'Accept' => 'text/xml, application/xml'
}
-
- # Queue used to send async notices. Used only if configuration.async is
- # set to true.
- AIRBRAKE_QUEUE = GirlFriday::WorkQueue.new(nil,:size => 3) do |notice|
- sender.send_to_airbrake(notice)
- end
-
class << self
# The sender object is responsible for delivering formatted data to the Airbrake server.
# Must respond to #send_to_airbrake. See Airbrake::Sender.
@@ -145,7 +138,7 @@ def build_lookup_hash_for(exception, options = {})
def send_notice(notice)
if configuration.public?
if configuration.async?
- AIRBRAKE_QUEUE << notice
+ configuration.async.call(notice)
else
sender.send_to_airbrake(notice)
end
View
32 lib/airbrake/configuration.rb
@@ -100,9 +100,6 @@ class Configuration
# (boolean or nil; set to nil to catch exceptions when rake isn't running from a terminal; default is nil)
attr_accessor :rescue_rake_exceptions
- # Should Airbrake send notifications asynchronously
- # (boolean or nil; default is nil)
- attr_accessor :async
DEFAULT_PARAMS_FILTERS = %w(password password_confirmation).freeze
@@ -135,7 +132,6 @@ class Configuration
alias_method :secure?, :secure
alias_method :use_system_ssl_cert_chain?, :use_system_ssl_cert_chain
- alias_method :async?, :async
def initialize
@secure = false
@@ -244,6 +240,26 @@ def protocol
end
end
+ # Should Airbrake send notifications asynchronously
+ # (boolean, nil or callable; default is nil).
+ # Can be used as callable-setter when block provided.
+ def async(&block)
+ if block_given?
+ @async = block
+ end
+ @async
+ end
+ alias_method :async?, :async
+
+ def async=(value)
+ # use default GirlFriday-async for 'true' value
+ @async = if value == true
+ default_async_processor
+ else
+ value
+ end
+ end
+
def js_api_key
@js_api_key || self.api_key
end
@@ -280,5 +296,13 @@ def default_port
80
end
end
+
+ # Async notice delivery defaults to girl friday
+ def default_async_processor
+ queue = GirlFriday::WorkQueue.new(nil, :size => 3) do |notice|
+ Airbrake.sender.send_to_airbrake(notice.to_xml)
+ end
+ lambda {|notice| queue << notice}
+ end
end
end
View
13 test/configuration_test.rb
@@ -32,6 +32,19 @@ class ConfigurationTest < Test::Unit::TestCase
assert_config_default :async, nil
end
+ should "set GirlFriday-callable for async=true" do
+ config = Airbrake::Configuration.new
+ config.async = true
+ assert config.async.respond_to?(:call)
+ end
+
+ should "set provided-callable for async {}" do
+ config = Airbrake::Configuration.new
+ config.async {|notice| :ok}
+ assert config.async.respond_to?(:call)
+ assert_equal :ok, config.async.call
+ end
+
should "provide default values for secure connections" do
config = Airbrake::Configuration.new
config.secure = true
View
31 test/notifier_test.rb
@@ -139,6 +139,37 @@ def set_development_env
assert_received(sender, :send_to_airbrake) {|expect| expect.never }
end
+ should "deliver exception in async-mode" do
+ Airbrake.configure do |config|
+ config.environment_name = 'production'
+ config.async do |notice|
+ Airbrake.sender.send_to_airbrake(notice.to_xml)
+ end
+ end
+ exception = build_exception
+ sender = stub_sender!
+ notice = stub_notice!
+
+ Airbrake.notify(exception)
+
+ assert_sent(notice, :exception => exception)
+ end
+
+ should "pass notice in async-mode" do
+ received_notice = nil
+ Airbrake.configure do |config|
+ config.environment_name = 'production'
+ config.async {|notice| received_notice = notice}
+ end
+ exception = build_exception
+ sender = stub_sender!
+ notice = stub_notice!
+
+ Airbrake.notify(exception)
+
+ assert_equal received_notice, notice
+ end
+
should "deliver an ignored exception when notifying manually" do
set_public_env
exception = build_exception

0 comments on commit 4b046f1

Please sign in to comment.
Something went wrong with that request. Please try again.