Class: Growthbook::PayloadReducer

Inherits:
Object
  • Object
show all
Defined in:
lib/growthbook/payload_reducer.rb

Overview

internal use only Shrinks a features payload for a user whose attributes are only partly known, e.g. on a server bootstrapping a client SDK. The result evaluates the same as the full payload for anyone who agrees with the known attributes.

Instance Method Summary collapse

Constructor Details

#initialize(payload, attributes:, include:, exclude:, prerequisites:) ⇒ PayloadReducer

Returns a new instance of PayloadReducer.

Parameters:

  • payload (Hash) —

    A decrypted features payload, as returned by the SDK API

  • attributes (Hash) —

    The attributes known for the user

  • include (Hash) —

    Keep only what matches every filter: projects, tags, customFields

  • exclude (Hash) —

    Drop what matches any filter: projects, tags, customFields

  • prerequisites ('keep', 'filter') —

    With 'keep', prerequisites of kept features and experiments are kept even when the filters drop them



15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/growthbook/payload_reducer.rb', line 15

def initialize(payload, attributes:, include:, exclude:, prerequisites:)
  @payload = payload
  @attributes = attributes
  @include = include
  @exclude = exclude
  @filter_prerequisites = prerequisites.to_s == 'filter'
  @saved_groups = payload['savedGroups'] || {}
  @all_features = payload['features'] || {}
  @added = {}
  @as_written = {}
  @on_cycle = nil
end

Instance Method Details

#reduce ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/growthbook/payload_reducer.rb', line 28

def reduce
  @all_features.each do |id, feature|
    add(id) if matches?(feature.is_a?(Hash) ? feature['metadata'] : nil)
  end
  experiments = (@payload['experiments'] || []).select { |e| matches?(e['metadata']) }.map { |e| prune(e, false) }
  experiments.each { |e| add_parents(e) }

  reduced = @payload.merge('features' => @added, 'experiments' => experiments)
  # Only when there were any, as with the payload's other optional keys
  if @payload['contextualBandits']
    reduced['contextualBandits'] = contextual_bandits(experiments)
  else
    reduced.delete('contextualBandits')
  end
  used = [@added, experiments, reduced['contextualBandits']]
  # Walking the payload is only needed when there are groups to find
  unless @saved_groups.empty?
    mark_as_written(used, true, {})
    groups = used_saved_groups(used)
  end
  reduced['savedGroups'] = groups || {}
  reduced
end