docbrown/app/services/search/client.rb
Michael Kohl 909519c5d5
Search::Client refactor (#6440)
* Refactor Search::Client

* Fix stack overflow error
2020-03-10 22:21:12 +01:00

60 lines
1.9 KiB
Ruby

module Search
# Search client (uses Elasticsearch as a backend)
class Client
class << self
# adapted from https://api.rubyonrails.org/classes/Module.html#method-i-delegate_missing_to
def method_missing(method, *args, &block)
return super unless target.respond_to?(method, false)
# define for re-use
self.class.define_method(method) do |*new_args, &new_block|
request do
target.public_send(method, *new_args, &new_block)
end
end
# call the original method, this will only be called the first time
# as in subsequent calls, the newly defined method will prevail
request do
target.public_send(method, *args, &block)
end
end
# adapted from https://api.rubyonrails.org/classes/Module.html#method-i-delegate_missing_to
def respond_to_missing?(method, _include_all = false)
target.respond_to?(method, false) || super
end
private
TRANSPORT_EXCEPTIONS = [
Elasticsearch::Transport::Transport::Errors::BadRequest,
Elasticsearch::Transport::Transport::Errors::NotFound,
].freeze
def request
yield
rescue *TRANSPORT_EXCEPTIONS => e
class_name = e.class.name.demodulize
DatadogStatsClient.increment("elasticsearch.errors", tags: ["error:#{class_name}"], message: e.message)
# raise specific error if known, generic one if unknown
error_class = "::Search::Errors::Transport::#{class_name}".safe_constantize
raise error_class, e.message if error_class
raise ::Search::Errors::TransportError, e.message
end
def target
@target ||= Elasticsearch::Client.new(
url: ApplicationConfig["ELASTICSEARCH_URL"],
retry_on_failure: 5,
request_timeout: 30,
adapter: :typhoeus,
log: Rails.env.development?,
)
end
end
end
end