removed started? and use AtomicBoolean for ready?

cleanup @filter_to_output initialization

remove @run_mutex, use ready? to synchonize shutdown agains startup sequence

remove ShutdownSignal handling & cleanup
This commit is contained in:
Colin Surprenant 2015-09-09 14:10:10 -04:00
parent 3bdac41a6c
commit 5adf2b0426

View file

@ -1,6 +1,7 @@
# encoding: utf-8 # encoding: utf-8
require "thread" # require "thread"
require "stud/interval" require "stud/interval"
require "concurrent"
require "logstash/namespace" require "logstash/namespace"
require "logstash/errors" require "logstash/errors"
require "logstash/event" require "logstash/event"
@ -34,29 +35,19 @@ class LogStash::Pipeline
end end
@input_to_filter = SizedQueue.new(20) @input_to_filter = SizedQueue.new(20)
# if no filters, pipe inputs directly to outputs
# If no filters, pipe inputs directly to outputs @filter_to_output = filters? ? SizedQueue.new(20) : @input_to_filter
if !filters?
@filter_to_output = @input_to_filter
else
@filter_to_output = SizedQueue.new(20)
end
@settings = { @settings = {
"filter-workers" => 1, "filter-workers" => 1,
} }
@run_mutex = Mutex.new # @ready requires thread safety since it is typically polled from outside the pipeline thread
@ready = false @ready = Concurrent::AtomicBoolean.new(false)
@started = false
@input_threads = [] @input_threads = []
end # def initialize end # def initialize
def ready? def ready?
@run_mutex.synchronize{@ready} @ready.value
end
def started?
@run_mutex.synchronize{@started}
end end
def configure(setting, value) def configure(setting, value)
@ -75,14 +66,15 @@ class LogStash::Pipeline
end end
def run def run
@run_mutex.synchronize{@started = true} begin
start_inputs
# synchronize @input_threads between run and shutdown start_filters if filters?
@run_mutex.synchronize{start_inputs} start_outputs
start_filters if filters? ensure
start_outputs # it is important to garantee @ready to be true after the startup sequence has been completed
# to potentially unblock the shutdown method which may be waiting on @ready to proceed
@run_mutex.synchronize{@ready = true} @ready.make_true
end
@logger.info("Pipeline started") @logger.info("Pipeline started")
@logger.terminal("Logstash startup completed") @logger.terminal("Logstash startup completed")
@ -246,25 +238,20 @@ class LogStash::Pipeline
end end
end # def outputworker end # def outputworker
# Shutdown this pipeline. # initiate the pipeline shutdown sequence
# # this method is intended to be called from outside the pipeline thread
# This method is intended to be called from another thread
def shutdown def shutdown
# shutdown can only start once the pipeline has completed its startup.
# avoid potential race conditoon between the startup sequence and this
# shutdown method which can be called from another thread at any time
sleep(0.1) while !ready?
# TODO: should we also check against calling shutdown multiple times concurently?
InflightEventsReporter.logger = @logger InflightEventsReporter.logger = @logger
InflightEventsReporter.start(@input_to_filter, @filter_to_output, @outputs) InflightEventsReporter.start(@input_to_filter, @filter_to_output, @outputs)
# sometimes an input is stuck in a blocking I/O so we need to tell it to teardown directly @inputs.each(&:stop)
@inputs.each do |input|
begin
# input teardown must be synchronized since is can be called concurrently by
# the input worker thread and from the pipeline thread shutdown method.
# this means that input teardown methods must support multiple calls.
@run_mutex.synchronize{input.stop}
rescue LogStash::ShutdownSignal
# teardown could receive the ShutdownSignal, retry it
retry
end
end
end # def shutdown end # def shutdown
def plugin(plugin_type, name, *args) def plugin(plugin_type, name, *args)