-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Next Gen Pipeline #4254
Next Gen Pipeline #4254
Changes from 18 commits
6322c5f
0d09556
5aff6ac
d11d1cc
56ada56
9a0a68c
808c8d8
5c69235
9ac1f2f
16fc8e7
de66bb2
3439464
05e9650
4f0d100
167a180
616afe1
76ddd14
5d6e9a9
5be12df
ec1c03b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -108,6 +108,7 @@ def compile | |
# defines @filter_func and @output_func | ||
|
||
definitions << "def #{type}_func(event)" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is an error here when you run multiples pipeline and the way we are generating the code. I have a PR to fix it in #4298 |
||
definitions << " targeted_outputs = []" if type == "output" | ||
definitions << " events = [event]" if type == "filter" | ||
definitions << " @logger.debug? && @logger.debug(\"#{type} received\", :event => event.to_hash)" | ||
|
||
|
@@ -116,6 +117,7 @@ def compile | |
end | ||
|
||
definitions << " events" if type == "filter" | ||
definitions << " targeted_outputs" if type == "output" | ||
definitions << "end" | ||
end | ||
|
||
|
@@ -237,7 +239,7 @@ def compile | |
events = #{variable_name}.multi_filter(events) | ||
CODE | ||
when "output" | ||
return "#{variable_name}.handle(event)\n" | ||
return "targeted_outputs << #{variable_name}\n" | ||
when "codec" | ||
settings = attributes.recursive_select(Attribute).collect(&:compile).reject(&:empty?) | ||
attributes_code = "LogStash::Util.hash_merge_many(#{settings.map { |c| "{ #{c} }" }.join(", ")})" | ||
|
@@ -402,7 +404,7 @@ def cond_func_#{i}(input_events) | |
<<-CODE | ||
events = cond_func_#{i}(events) | ||
CODE | ||
else | ||
else # Output | ||
<<-CODE | ||
#{super} | ||
end | ||
|
@@ -542,4 +544,4 @@ def _inspect(indent="") | |
"" | ||
) | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# encoding: utf-8 | ||
require "concurrent/atomic/atomic_fixnum" | ||
|
||
# This class goes hand in hand with the pipeline to provide a pool of | ||
# free workers to be used by pipeline worker threads. The pool is | ||
# internally represented with a SizedQueue set the the size of the number | ||
# of 'workers' the output plugin is configured with. | ||
# | ||
# This plugin also records some basic statistics | ||
module LogStash; class OutputDelegator | ||
attr_reader :workers, :config, :worker_count | ||
|
||
def initialize(logger, klass, *args) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for readability and maintainability and especially when non-obvious, but ideally always, we should document method parameters. In particular here |
||
@logger = logger | ||
@config = args.reduce({}, :merge) | ||
@klass = klass | ||
@worker_count = @config["workers"] || 1 | ||
|
||
@worker_queue = SizedQueue.new(@worker_count) | ||
|
||
@workers = @worker_count.times.map do | ||
w = @klass.new(*args) | ||
w.register | ||
@worker_queue << w | ||
w | ||
end | ||
|
||
@events_received = Concurrent::AtomicFixnum.new(0) | ||
end | ||
|
||
def config_name | ||
@klass.config_name | ||
end | ||
|
||
def register | ||
@workers.each {|w| w.register} | ||
end | ||
|
||
def multi_receive(events) | ||
@events_received.increment(events.length) | ||
|
||
worker = @worker_queue.pop | ||
begin | ||
worker.multi_receive(events) | ||
ensure | ||
@worker_queue.push(worker) | ||
end | ||
end | ||
|
||
def do_close | ||
@logger.debug("closing output delegator", :klass => self) | ||
|
||
@worker_count.times do | ||
worker = @worker_queue.pop | ||
worker.do_close | ||
end | ||
end | ||
|
||
def events_received | ||
@events_received.value | ||
end | ||
|
||
def busy_workers | ||
@worker_queue.size | ||
end | ||
end end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this means this changes allows us to have multiple pipelines?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is already in the current master, but yes this is the first step to enable multiple pipelines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice, very interesting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing to note is I made the pipeline ID part of the thread names so it looks nice in VisualVM!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@andrewvc this pipeline_id handling is quirky,I see that in pipeline.rb if the id is nil then
object_id
is used. maybe we could do it here instead? because otherwise callingadd_pipeline(nil, "") will create a nil key in @pipelines but the pipeline.id will return
object_id`There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @jsvd comment.
But this scenario is also problematic if you are trying to add a new pipeline with an existing key, but I think this can be solve in another PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jsvd @ph yep, great observation. I'll move that logic here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jsvd @ph looking through the code the reason I made the UUID generation automatic inside of pipeline was that for testing this is pretty inconvenient.
If we're thinking of making pipeline_id required it should change the signature of the constructor to
Pipeline.new(pipeline_id, config_str, settings)
. Are you guys OK with this change? It will make the PR a good bit larger as all tests instantiating the pipeline will need to change.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@andrewvc Lets make that into another PR :(