logstash-integration-jdbc 5.2.2 → 5.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f43be09f1996c0e4effd6914055fa643549925433ab4512f4e3a0ed1fa1933c
4
- data.tar.gz: 346cb42a27eaaa3f51e7cf1ba3d52fb332f278dfe8cecf7d1aa200af42ba4f5b
3
+ metadata.gz: 2119dbab43322bdc083cf11602e69e63bcb1a957b537f5f44cfcd2b611df1893
4
+ data.tar.gz: 651e016e43bb17db730cc95ad0fd44bed483b9edfa4bbe86e52ced95947bb4a4
5
5
  SHA512:
6
- metadata.gz: 3a75a4a4165e04178384a66740de3bce2981c2d019a8bd2192519a725bfe88d5ddf7469cf2a2aebda12b1b48b2117817171da2f459d283c3e3e16d86422c4c06
7
- data.tar.gz: ae15ead4d5efd52cc67bf58ad1d994bde11443bbc0e083d56f695ddc7163be44454ee1db1a95b81ec884c51a790f2e7582733df4f5faf6b9d4715a0685a31c92
6
+ metadata.gz: 0a90d6aa88365c9ddfe60bba20f6f06633733af4b910b75becc31c37a9e1a224d3aae8d5e62f03f8ae2a3ffd8a24d1b0635307aa152a836c18435a4b36ca1d5d
7
+ data.tar.gz: f6a6648d071bff9069f54448cfed03327cb0f5bb8c036d8b0c6e5adb949c69a75f923541fe6a1237eeb3e6fe35611ad0afd4f99e356e8dd42b1e2b19534bc5b7
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 5.2.3
2
+ - Performance: avoid contention on scheduler execution [#103](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/103)
3
+
1
4
  ## 5.2.2
2
5
  - Feat: name scheduler threads + redirect error logging [#102](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/102)
3
6
 
@@ -296,7 +296,13 @@ module LogStash module Inputs class Jdbc < LogStash::Inputs::Base
296
296
  if @schedule
297
297
  # input thread (Java) name example "[my-oracle]<jdbc"
298
298
  @scheduler = LogStash::PluginMixins::Jdbc::Scheduler.new(
299
- :max_work_threads => 1, :thread_name => "[#{id}]<jdbc__scheduler"
299
+ :max_work_threads => 1,
300
+ :thread_name => "[#{id}]<jdbc__scheduler",
301
+ # amount the scheduler thread sleeps between checking whether jobs
302
+ # should trigger, default is 0.3 which is a bit too often ...
303
+ # in theory the cron expression '* * * * * *' supports running jobs
304
+ # every second but this is very rare, we could potentially go higher
305
+ :frequency => 1.0,
300
306
  )
301
307
  @scheduler.schedule_cron @schedule do
302
308
  execute_query(queue)
@@ -12,6 +12,42 @@ module LogStash module PluginMixins module Jdbc
12
12
  TimeImpl = defined?(Rufus::Scheduler::EoTime) ? Rufus::Scheduler::EoTime :
13
13
  (defined?(Rufus::Scheduler::ZoTime) ? Rufus::Scheduler::ZoTime : ::Time)
14
14
 
15
+ # @overload
16
+ def timeout_jobs
17
+ # Rufus relies on `Thread.list` which is a blocking operation and with many schedulers
18
+ # (and threads) within LS will have a negative impact on performance as scheduler
19
+ # threads will end up waiting to obtain the `Thread.list` lock.
20
+ #
21
+ # However, this isn't necessary we can easily detect whether there are any jobs
22
+ # that might need to timeout: only when `@opts[:timeout]` is set causes worker thread(s)
23
+ # to have a `Thread.current[:rufus_scheduler_timeout]` that is not nil
24
+ return unless @opts[:timeout]
25
+ super
26
+ end
27
+
28
+ # @overload
29
+ def work_threads(query = :all)
30
+ if query == :__all_no_cache__ # special case from JobDecorator#start_work_thread
31
+ @_work_threads = nil # when a new worker thread is being added reset
32
+ return super(:all)
33
+ end
34
+
35
+ # Gets executed every time a job is triggered, we're going to cache the
36
+ # worker threads for this scheduler (to avoid `Thread.list`) - they only
37
+ # change when a new thread is being started from #start_work_thread ...
38
+ work_threads = @_work_threads
39
+ if work_threads.nil?
40
+ work_threads = threads.select { |t| t[:rufus_scheduler_work_thread] }
41
+ @_work_threads = work_threads
42
+ end
43
+
44
+ case query
45
+ when :active then work_threads.select { |t| t[:rufus_scheduler_job] }
46
+ when :vacant then work_threads.reject { |t| t[:rufus_scheduler_job] }
47
+ else work_threads
48
+ end
49
+ end
50
+
15
51
  # @overload
16
52
  def on_error(job, err)
17
53
  details = { exception: err.class, message: err.message, backtrace: err.backtrace }
@@ -76,10 +112,10 @@ module LogStash module PluginMixins module Jdbc
76
112
 
77
113
  ret = super() # does not return Thread instance in 3.0
78
114
 
79
- work_threads = @scheduler.work_threads
115
+ work_threads = @scheduler.work_threads(:__all_no_cache__)
80
116
  while prev_thread_count == work_threads.size # very unlikely
81
117
  Thread.pass
82
- work_threads = @scheduler.work_threads
118
+ work_threads = @scheduler.work_threads(:__all_no_cache__)
83
119
  end
84
120
 
85
121
  work_thread_name_prefix = @scheduler.work_thread_name_prefix
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-integration-jdbc'
3
- s.version = '5.2.2'
3
+ s.version = '5.2.3'
4
4
  s.licenses = ['Apache License (2.0)']
5
5
  s.summary = "Integration with JDBC - input and filter plugins"
6
6
  s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
@@ -49,4 +49,30 @@ describe LogStash::PluginMixins::Jdbc::Scheduler do
49
49
 
50
50
  end
51
51
 
52
+ context 'work threads' do
53
+
54
+ let(:opts) { super().merge :max_work_threads => 3 }
55
+
56
+ let(:counter) { java.util.concurrent.atomic.AtomicLong.new(0) }
57
+
58
+ before do
59
+ scheduler.schedule_cron('* * * * * *') { counter.increment_and_get; sleep 3.25 } # every second
60
+ end
61
+
62
+ it "are working" do
63
+ sleep(0.05) while counter.get == 0
64
+ expect( scheduler.work_threads.size ).to eql 1
65
+ sleep(0.05) while counter.get == 1
66
+ expect( scheduler.work_threads.size ).to eql 2
67
+ sleep(0.05) while counter.get == 2
68
+ expect( scheduler.work_threads.size ).to eql 3
69
+
70
+ sleep 1.25
71
+ expect( scheduler.work_threads.size ).to eql 3
72
+ sleep 1.25
73
+ expect( scheduler.work_threads.size ).to eql 3
74
+ end
75
+
76
+ end
77
+
52
78
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-integration-jdbc
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.2.2
4
+ version: 5.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-19 00:00:00.000000000 Z
11
+ date: 2022-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement