From 37a8f45d8b2e7987dcce84eda2505d7a6e5f7874 Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Wed, 22 Jul 2020 01:27:29 -0400 Subject: [PATCH 1/2] Add connection pool option --- lib/net/ldap.rb | 12 +++++++++++- lib/net/ldap/connection.rb | 9 +++++++++ net-ldap.gemspec | 2 ++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/net/ldap.rb b/lib/net/ldap.rb index 107cd930..f7ce86ed 100644 --- a/lib/net/ldap.rb +++ b/lib/net/ldap.rb @@ -31,6 +31,8 @@ class LDAP require_relative 'ldap/auth_adapter/simple' require_relative 'ldap/auth_adapter/sasl' +require 'connection_pool' + Net::LDAP::AuthAdapter.register([:simple, :anon, :anonymous], Net::LDAP::AuthAdapter::Simple) Net::LDAP::AuthAdapter.register(:sasl, Net::LDAP::AuthAdapter::Sasl) @@ -553,6 +555,10 @@ def initialize(args = {}) @force_no_page = args[:force_no_page] || DefaultForceNoPage @encryption = normalize_encryption(args[:encryption]) # may be nil @connect_timeout = args[:connect_timeout] + if args[:connection_pool].is_a? Hash + options = { size: 5, timeout: (@connection_timeout || 5) }.merge args[:connection_pool] + @connection_pool = ConnectionPool.new(options) { new_connection } + end if pr = @auth[:password] and pr.respond_to?(:call) @auth[:password] = pr.call @@ -1293,7 +1299,11 @@ def connection=(connection) # result from that, and :use_connection: will not yield at all. If not # the return value is whatever is returned from the block. def use_connection(args) - if @open_connection + if @connection_pool + @connection_pool.with do |conn| + yield conn + end + elsif @open_connection yield @open_connection else begin diff --git a/lib/net/ldap/connection.rb b/lib/net/ldap/connection.rb index 1f900b6e..087bcb8a 100644 --- a/lib/net/ldap/connection.rb +++ b/lib/net/ldap/connection.rb @@ -23,6 +23,8 @@ def initialize(server = {}) # Allows tests to parameterize what socket class to use @socket_class = server.fetch(:socket_class, DefaultSocket) + ObjectSpace.define_finalizer self, finalize + yield self if block_given? end @@ -186,6 +188,13 @@ def close @conn = nil end + # Ensure the connection closes when this instance is destroyed. + def finalize + proc do |_obj_id| + close + end + end + # Internal: Reads messages by ID from a queue, falling back to reading from # the connected socket until a message matching the ID is read. Any messages # with mismatched IDs gets queued for subsequent reads by the origin of that diff --git a/net-ldap.gemspec b/net-ldap.gemspec index 93433042..aea95bb0 100644 --- a/net-ldap.gemspec +++ b/net-ldap.gemspec @@ -29,6 +29,8 @@ the most recent LDAP RFCs (4510-4519, plutions of 4520-4532).} s.required_ruby_version = ">= 2.0.0" s.summary = %q{Net::LDAP for Ruby (also called net-ldap) implements client access for the Lightweight Directory Access Protocol (LDAP), an IETF standard protocol for accessing distributed directory services} + s.add_runtime_dependency("connection_pool", "~> 2.2") + s.add_development_dependency("flexmock", "~> 1.3") s.add_development_dependency("rake", "~> 12.3.3") s.add_development_dependency("rubocop", "~> 0.49.0") From eb2f83420ea30613b5ed83125bba17b2250281c2 Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Wed, 22 Jul 2020 01:34:58 -0400 Subject: [PATCH 2/2] Rubocop fixes --- .rubocop_todo.yml | 11 +++++------ lib/net/ldap/connection.rb | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 315dc0c5..7a0f2094 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2020-07-12 00:41:11 -0400 using RuboCop version 0.49.1. +# on 2020-07-22 01:34:13 -0400 using RuboCop version 0.49.1. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -196,13 +196,12 @@ Lint/UselessAccessModifier: Exclude: - 'lib/net/ldap/connection.rb' -# Offense count: 6 +# Offense count: 4 Lint/UselessAssignment: Exclude: - 'test/integration/test_add.rb' - 'test/test_ldap_connection.rb' - 'test/test_search.rb' - - 'test/test_snmp.rb' # Offense count: 48 Metrics/AbcSize: @@ -221,13 +220,13 @@ Metrics/BlockNesting: # Offense count: 11 # Configuration parameters: CountComments. Metrics/ClassLength: - Max: 429 + Max: 437 # Offense count: 23 Metrics/CyclomaticComplexity: Max: 41 -# Offense count: 216 +# Offense count: 219 # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # URISchemes: http, https Metrics/LineLength: @@ -648,7 +647,7 @@ Style/SpecialGlobalVars: - 'net-ldap.gemspec' - 'testserver/ldapserver.rb' -# Offense count: 656 +# Offense count: 658 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, ConsistentQuotesInMultiline. # SupportedStyles: single_quotes, double_quotes diff --git a/lib/net/ldap/connection.rb b/lib/net/ldap/connection.rb index 087bcb8a..b4e9a577 100644 --- a/lib/net/ldap/connection.rb +++ b/lib/net/ldap/connection.rb @@ -23,7 +23,7 @@ def initialize(server = {}) # Allows tests to parameterize what socket class to use @socket_class = server.fetch(:socket_class, DefaultSocket) - ObjectSpace.define_finalizer self, finalize + ObjectSpace.define_finalizer self, finalize yield self if block_given? end