mirror of
https://github.com/elastic/logstash.git
synced 2025-04-24 06:37:19 -04:00
Replace def #{type}_func
with define_singleton_method
When you run multiples pipeline and the config code get evaluated, on every evaluation the class cached is clear, everytime you were calling a `func` method you had the latest evaluated code. The `filter_func` and the `output_func` need to be unique for every instance of the pipeline, this PR replace the `def` with a `define_single_method` call ensuring the uniqueness of the code on every instance. This PR is based on #4254 Fixes #4298
This commit is contained in:
parent
5e76d972d0
commit
9d876fa8b3
2 changed files with 35 additions and 3 deletions
|
@ -107,7 +107,10 @@ module LogStash; module Config; module AST
|
|||
["filter", "output"].each do |type|
|
||||
# defines @filter_func and @output_func
|
||||
|
||||
definitions << "def #{type}_func(event)"
|
||||
# This need to be defined as a singleton method
|
||||
# so each instance of the pipeline has his own implementation
|
||||
# of the output/filter function
|
||||
definitions << "define_singleton_method :#{type}_func do |event|"
|
||||
definitions << " targeted_outputs = []" if type == "output"
|
||||
definitions << " events = [event]" if type == "filter"
|
||||
definitions << " @logger.debug? && @logger.debug(\"#{type} received\", :event => event.to_hash)"
|
||||
|
@ -544,4 +547,4 @@ class Treetop::Runtime::SyntaxNode
|
|||
""
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -47,7 +47,7 @@ class DummyOutput < LogStash::Outputs::Base
|
|||
|
||||
def register
|
||||
end
|
||||
|
||||
|
||||
def receive(event)
|
||||
@events << event
|
||||
end
|
||||
|
@ -382,4 +382,33 @@ describe LogStash::Pipeline do
|
|||
pipeline.shutdown
|
||||
end
|
||||
end
|
||||
|
||||
context "Multiple pipelines" do
|
||||
before do
|
||||
allow(LogStash::Plugin).to receive(:lookup).with("input", "generator").and_return(LogStash::Inputs::Generator)
|
||||
allow(LogStash::Plugin).to receive(:lookup).with("codec", "plain").and_return(DummyCodec)
|
||||
allow(LogStash::Plugin).to receive(:lookup).with("filter", "dummyfilter").and_return(DummyFilter)
|
||||
allow(LogStash::Plugin).to receive(:lookup).with("output", "dummyoutput").and_return(DummyOutput)
|
||||
end
|
||||
|
||||
let(:pipeline1) { LogStash::Pipeline.new("input { generator {} } filter { dummyfilter {} } output { dummyoutput {}}") }
|
||||
let(:pipeline2) { LogStash::Pipeline.new("input { generator {} } filter { dummyfilter {} } output { dummyoutput {}}") }
|
||||
|
||||
it "should handle evaluating different config" do
|
||||
# When the functions are compiled from the AST it will generate instance
|
||||
# variables that are unique to the actual config, the intance are pointing
|
||||
# to conditionals/plugins.
|
||||
#
|
||||
# Before the `defined_singleton_method`, the definition of the method was
|
||||
# not unique per class, but the `instance variables` were unique per class.
|
||||
#
|
||||
# So the methods were trying to access instance variables that did not exist
|
||||
# in the current instance and was returning an array containing nil values for
|
||||
# the match.
|
||||
expect(pipeline1.output_func(LogStash::Event.new)).not_to include(nil)
|
||||
expect(pipeline1.filter_func(LogStash::Event.new)).not_to include(nil)
|
||||
expect(pipeline2.output_func(LogStash::Event.new)).not_to include(nil)
|
||||
expect(pipeline1.filter_func(LogStash::Event.new)).not_to include(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue