Class: Hackle::Core

Inherits:
Object
  • Object
show all
Defined in:
lib/hackle/internal/core/hackle_core.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(experiment_evaluator:, remote_config_evaluator:, workspace_fetcher:, event_factory:, event_processor:, clock:) ⇒ Core

Returns a new instance of Core.

Parameters:



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/hackle/internal/core/hackle_core.rb', line 25

def initialize(
  experiment_evaluator:,
  remote_config_evaluator:,
  workspace_fetcher:,
  event_factory:,
  event_processor:,
  clock:
)
  # @type experiment_evaluator [ExperimentEvaluator]
  @experiment_evaluator = experiment_evaluator
  # @type remote_config_evaluator [RemoteConfigEvaluator]
  @remote_config_evaluator = remote_config_evaluator
  # @type workspace_fetcher [WorkspaceFetcher]
  @workspace_fetcher = workspace_fetcher
  # @type event_factory [UserEventFactory]
  @event_factory = event_factory
  # @type event_processor [UserEventProcessor]
  @event_processor = event_processor
  # @type clock [Clock]
  @clock = clock
end

Class Method Details

.create(workspace_fetcher:, event_processor:) ⇒ Core

Parameters:

Returns:



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/hackle/internal/core/hackle_core.rb', line 50

def self.create(workspace_fetcher:, event_processor:)
  delegating_evaluator = DelegatingEvaluator.new

  condition_matcher_factory = ConditionMatcherFactory.new(evaluator: delegating_evaluator)
  target_matcher = TargetMatcher.new(condition_matcher_factory: condition_matcher_factory)
  bucketer = Bucketer.new(hasher: Hasher.new)

  experiment_evaluator = ExperimentEvaluator.new(
    flow_factory: ExperimentEvaluationFlowFactory.new(
      target_matcher: target_matcher,
      bucketer: bucketer
    )
  )
  delegating_evaluator.add(experiment_evaluator)

  remote_config_evaluator = RemoteConfigEvaluator.new(
    target_rule_determiner: RemoteConfigTargetRuleDeterminer.new(
      matcher: RemoteConfigTargetRuleMatcher.new(
        target_matcher: target_matcher,
        bucketer: bucketer
      )
    )
  )
  delegating_evaluator.add(remote_config_evaluator)

  Core.new(
    experiment_evaluator: experiment_evaluator,
    remote_config_evaluator: remote_config_evaluator,
    workspace_fetcher: workspace_fetcher,
    event_factory: UserEventFactory.new(clock: SystemClock.instance),
    event_processor: event_processor,
    clock: SystemClock.instance
  )
end

Instance Method Details

#closeObject



158
159
160
161
# File 'lib/hackle/internal/core/hackle_core.rb', line 158

def close
  @workspace_fetcher.stop
  @event_processor.stop
end

#experiment(experiment_key, user, default_variation) ⇒ ExperimentDecision

Parameters:

  • experiment_key (Integer)
  • user (HackleUser)
  • default_variation (String)

Returns:



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/hackle/internal/core/hackle_core.rb', line 89

def experiment(experiment_key, user, default_variation)
  workspace = @workspace_fetcher.fetch
  return ExperimentDecision.new(default_variation, DecisionReason::SDK_NOT_READY, ParameterConfig.empty) if workspace.nil?

  experiment = workspace.get_experiment_or_nil(experiment_key)
  return ExperimentDecision.new(default_variation, DecisionReason::EXPERIMENT_NOT_FOUND, ParameterConfig.empty) if experiment.nil?

  request = ExperimentRequest.create(workspace, user, experiment, default_variation)
  evaluation = @experiment_evaluator.evaluate(request, Evaluator.context)

  events = @event_factory.create(request, evaluation)
  events.each do |event|
    @event_processor.process(event)
  end

  ExperimentDecision.new(evaluation.variation_key, evaluation.reason, evaluation.parameter_config)
end

#feature_flag(feature_key, user) ⇒ FeatureFlagDecision

Parameters:

Returns:



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/hackle/internal/core/hackle_core.rb', line 110

def feature_flag(feature_key, user)
  workspace = @workspace_fetcher.fetch
  return FeatureFlagDecision.new(false, DecisionReason::SDK_NOT_READY, ParameterConfig.empty) if workspace.nil?

  feature_flag = workspace.get_feature_flag_or_nil(feature_key)
  return FeatureFlagDecision.new(false, DecisionReason::FEATURE_FLAG_NOT_FOUND, ParameterConfig.empty) if feature_flag.nil?

  request = ExperimentRequest.create(workspace, user, feature_flag, 'A')
  evaluation = @experiment_evaluator.evaluate(request, Evaluator.context)

  events = @event_factory.create(request, evaluation)
  events.each do |event|
    @event_processor.process(event)
  end

  is_on = evaluation.variation_key != 'A'
  FeatureFlagDecision.new(is_on, evaluation.reason, evaluation.parameter_config)
end

#remote_config(parameter_key, user, required_type, default_value) ⇒ Object

Parameters:

  • parameter_key (String)
  • user (HackleUser)
  • required_type (ValueType)
  • default_value (Object, nil)


133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/hackle/internal/core/hackle_core.rb', line 133

def remote_config(parameter_key, user, required_type, default_value)
  workspace = @workspace_fetcher.fetch
  return RemoteConfigDecision.new(default_value, DecisionReason::SDK_NOT_READY) if workspace.nil?

  parameter = workspace.get_remote_config_parameter_or_nil(parameter_key)
  return RemoteConfigDecision.new(default_value, DecisionReason::REMOTE_CONFIG_PARAMETER_NOT_FOUND) if parameter.nil?

  request = RemoteConfigRequest.create(workspace, user, parameter, required_type, default_value)
  evaluation = @remote_config_evaluator.evaluate(request, Evaluator.context)

  events = @event_factory.create(request, evaluation)
  events.each do |event|
    @event_processor.process(event)
  end

  RemoteConfigDecision.new(evaluation.value, evaluation.reason)
end

#resumeObject



163
164
165
166
# File 'lib/hackle/internal/core/hackle_core.rb', line 163

def resume
  @workspace_fetcher.resume
  @event_processor.resume
end

#track(event, user) ⇒ Object

Parameters:



153
154
155
156
# File 'lib/hackle/internal/core/hackle_core.rb', line 153

def track(event, user)
  event_type = event_type(event)
  @event_processor.process(UserEvent.track(event_type, event, user, @clock.current_millis))
end