Class: Karst::Access::Search
- Inherits:
-
Object
- Object
- Karst::Access::Search
- Defined in:
- lib/karst/access/search.rb
Overview
Orchestrates the two-stage search for a user who can actually use a route: the ordinary bounded sample first, then -- only if that found nothing usable -- one bounded retry against each approved candidate population, stopping at the first verified success.
This is deliberately an orchestrator built on top of the existing primitives rather than new behavior inside them. Access::Sweep still owns every actual request (and therefore every rollback, write observation, exception, and halted-callback observation), and CandidatePopulation still owns resolving one configured callable into bounded records. Search only decides what to run next and records what it chose not to run.
Approval boundary: the populations considered here are exactly the ones on the Karst::Access::PrincipalSource objects handed to this class -- which means either explicit configuration (config.principal_populations, or a config.principal_sources :populations entry) or a candidate a developer explicitly approved locally, folded into the same configuration by Karst::Access::ApprovedPopulations. A name merely discovered by Karst::Access::PopulationDiscovery, and never approved, is never executed. Search itself deliberately cannot tell the two apart and never reads approval state: whatever produced this source's populations already had to answer for them. rubocop:disable Metrics/ClassLength
Constant Summary collapse
- MAX_RESOLUTION_LIMIT =
Why a population contributed nothing, kept explicit rather than inferred from an empty result so the panel can say what actually happened instead of implying every population was tested:
:usable ran, and produced a usable outcome :no_match ran, and produced no usable outcome :empty resolved, but currently matches no records :already_tried resolved, but every candidate was already tested :unresolved the callable did not yield usable records :skipped not tried -- a usable user was already found :budget_exhausted not tried -- the retry request budget was reachedHard ceiling on the LIMIT any single population resolution may use, independent of how many users have already been tested. See #resolve_limit.
50- PopulationAttempt =
Value.define(:name, :source_name, :state, :result, :error) do def ran? !result.nil? end end
- Result =
initialis the ordinary Access::Sweep::Result;attemptsis one PopulationAttempt per approved population, in configuration order, including the ones deliberately not run. rubocop:disable Metrics/BlockLength Value.define(:initial, :attempts) do def path initial.path end def http_method initial.http_method end # Every outcome observed across both stages, initial sample first. def all_outcomes ([initial] + attempts.filter_map(&:result)).flat_map(&:outcomes) end def attempted attempts.select(&:ran?) end def population_request_count attempted.sum { |attempt| attempt.result.outcomes.size } end # The winning evidence and its origin are exposed by Search itself so # adapters never need to invent another definition of usable access. def verified_outcome all_outcomes.find { |outcome| Karst.config.usable_access_outcome.call(outcome) } end def verified_source return nil unless verified_outcome return { type: :sample, name: nil } if initial.outcomes.include?(verified_outcome) attempt = attempts.find { |item| item.result&.outcomes&.include?(verified_outcome) } { type: :population, name: attempt.name } end def request_count initial.outcomes.size + population_request_count end def elapsed_ms ([initial] + attempted.map(&:result)).sum(&:elapsed_ms).round(1) end end
Instance Method Summary collapse
- #call ⇒ Object
-
#initialize(path:, http_method: "GET", sources: nil, application: nil) ⇒ Search
constructor
rubocop:enable Metrics/BlockLength.
Constructor Details
#initialize(path:, http_method: "GET", sources: nil, application: nil) ⇒ Search
rubocop:enable Metrics/BlockLength
109 110 111 112 113 114 115 116 |
# File 'lib/karst/access/search.rb', line 109 def initialize(path:, http_method: "GET", sources: nil, application: nil) @path = path @http_method = http_method @sources = sources || {} @application = application @requests_used = 0 @tried_keys = {} end |