class Greenfinch::BufferedConsumer
BufferedConsumer
buffers messages in memory, and sends messages as a batch. This can improve performance, but calls to send!
may still block if the buffer is full. If you use this consumer, you should call flush
when your application exits or the messages remaining in the buffer will not be sent.
To use a BufferedConsumer
directly with a Greenfinch::Tracker
, instantiate your Tracker
like this
buffered_consumer = Greenfinch::BufferedConsumer.new begin buffered_tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN) do |type, message| buffered_consumer.send!(type, message) end # Do some tracking here ... ensure buffered_consumer.flush end
Constants
- MAX_LENGTH
Public Class Methods
Create a Greenfinch::BufferedConsumer
. If you provide endpoint arguments, they will be used instead of the default Greenfinch
endpoints. This can be useful for proxying, debugging, or if you prefer not to use SSL for your events.
You can also change the preferred buffer size before the consumer automatically sends its buffered events. The Greenfinch
endpoints have a limit of 50 events per HTTP request, but you can lower the limit if your individual events are very large.
By default, BufferedConsumer
will use a standard Greenfinch
consumer to send the events once the buffer is full (or on calls to flush
), but you can override this behavior by passing a block to the constructor, in the same way you might pass a block to the Greenfinch::Tracker
constructor. If a block is passed to the constructor, the *_endpoint constructor arguments are ignored.
# File lib/greenfinch-ruby/consumer.rb, line 190 def initialize(events_endpoint=nil, update_endpoint=nil, import_endpoint=nil, max_buffer_length=MAX_LENGTH, &block) @max_length = [max_buffer_length, MAX_LENGTH].min @buffers = { :event => [], :profile_update => [], } if block @sink = block else consumer = Consumer.new(events_endpoint, update_endpoint, import_endpoint) @sink = consumer.method(:send!) end end
Public Instance Methods
Pushes all remaining messages in the buffer to Greenfinch
. You should call flush
before your application exits or messages may not be sent.
# File lib/greenfinch-ruby/consumer.rb, line 231 def flush @buffers.keys.each { |k| flush_type(k) } end
This method was deprecated in release 2.0.0, please use send! instead
# File lib/greenfinch-ruby/consumer.rb, line 223 def send(type, message) warn '[DEPRECATION] send has been deprecated as of release 2.0.0, please use send! instead' send!(type, message) end
Stores a message for Greenfinch
in memory. When the buffer hits a maximum length, the consumer will flush automatically. Flushes are synchronous when they occur.
Currently, only :event and :profile_update messages are buffered, :import messages will be send immediately on call.
# File lib/greenfinch-ruby/consumer.rb, line 211 def send!(type, message) type = type.to_sym if @buffers.has_key? type @buffers[type] << message flush_type(type) if @buffers[type].length >= @max_length else @sink.call(type, message) end end
Private Instance Methods
# File lib/greenfinch-ruby/consumer.rb, line 237 def flush_type(type) sent_messages = 0 begin @buffers[type].each_slice(@max_length) do |chunk| data = chunk.map {|message| JSON.load(message)['data'] } @sink.call(type, {'data' => data}.to_json) sent_messages += chunk.length end rescue @buffers[type].slice!(0, sent_messages) raise end @buffers[type] = [] end