Module: PostHog::FlagDefinitionCacheProvider

Defined in:
lib/posthog/flag_definition_cache.rb

Overview

Interface for external caching of feature flag definitions.

Enables multi-worker environments (Kubernetes, load-balanced servers, serverless functions) to share flag definitions via an external cache, reducing redundant API calls.

Implement the four required methods on any object and pass it as the :flag_definition_cache_provider option when creating a Client.

Required Methods

Error Handling

All methods are wrapped in begin/rescue. Errors are logged but never break flag evaluation:

  • should_fetch_flag_definitions? errors default to fetching (fail-safe)
  • flag_definitions errors fall back to API fetch
  • on_flag_definitions_received errors are logged; flags remain in memory
  • shutdown errors are logged; shutdown continues

Example

cache = RedisFlagCache.new(redis, service_key: 'my-service')
client = PostHog::Client.new(
api_key: '<project_api_key>',
secret_key: '<secret_key>',
flag_definition_cache_provider: cache
)

Constant Summary collapse

REQUIRED_METHODS =
%i[
  flag_definitions
  should_fetch_flag_definitions?
  on_flag_definitions_received
  shutdown
].freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.validate!(provider) ⇒ void

This method returns an undefined value.

Validates that provider implements all required methods. Raises ArgumentError listing any missing methods.

Parameters:

  • provider (Object) —

    the cache provider to validate

Raises:

  • (ArgumentError) —

    if any required methods are missing



79
80
81
82
83
84
85
86
# File 'lib/posthog/flag_definition_cache.rb', line 79

def self.validate!(provider)
  missing = REQUIRED_METHODS.reject { |m| provider.respond_to?(m) }
  return if missing.empty?

  raise ArgumentError,
        "Flag definition cache provider is missing required methods: #{missing.join(', ')}. " \
        'See PostHog::FlagDefinitionCacheProvider for the required interface.'
end

Instance Method Details

#flag_definitions ⇒ Hash?

Retrieve cached flag definitions. Return a Hash with :flags, :group_type_mapping, :cohorts, :minimal_flag_called_events, and :property_matching_version keys, or nil if the cache is empty. Returning nil triggers an API fetch when no flags are loaded yet (emergency fallback). Providers written before :minimal_flag_called_events existed continue to work; a missing key is treated as false. Preserve :property_matching_version with the definitions: exactly 2 selects explicit equality; missing/1 (including older cache entries) selects service legacy boolean matching. A fresh entry without the version resets to legacy, even after version 2.

Returns:

  • (Hash, nil)


65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/posthog/flag_definition_cache.rb', line 65

module FlagDefinitionCacheProvider
  REQUIRED_METHODS = %i[
    flag_definitions
    should_fetch_flag_definitions?
    on_flag_definitions_received
    shutdown
  ].freeze

  # Validates that +provider+ implements all required methods.
  # Raises +ArgumentError+ listing any missing methods.
  #
  # @param provider [Object] the cache provider to validate
  # @raise [ArgumentError] if any required methods are missing
  # @return [void]
  def self.validate!(provider)
    missing = REQUIRED_METHODS.reject { |m| provider.respond_to?(m) }
    return if missing.empty?

    raise ArgumentError,
          "Flag definition cache provider is missing required methods: #{missing.join(', ')}. " \
          'See PostHog::FlagDefinitionCacheProvider for the required interface.'
  end
end

#on_flag_definitions_received(data) ⇒ void

This method returns an undefined value.

Called after successfully fetching new definitions from the API. data is a Hash with :flags, :group_type_mapping, :cohorts, :minimal_flag_called_events, and :property_matching_version keys

(plain Ruby types, not Concurrent

wrappers). Store the entire snapshot

together in your external cache, including version-only updates.

Parameters:

  • data (Hash)


65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/posthog/flag_definition_cache.rb', line 65

module FlagDefinitionCacheProvider
  REQUIRED_METHODS = %i[
    flag_definitions
    should_fetch_flag_definitions?
    on_flag_definitions_received
    shutdown
  ].freeze

  # Validates that +provider+ implements all required methods.
  # Raises +ArgumentError+ listing any missing methods.
  #
  # @param provider [Object] the cache provider to validate
  # @raise [ArgumentError] if any required methods are missing
  # @return [void]
  def self.validate!(provider)
    missing = REQUIRED_METHODS.reject { |m| provider.respond_to?(m) }
    return if missing.empty?

    raise ArgumentError,
          "Flag definition cache provider is missing required methods: #{missing.join(', ')}. " \
          'See PostHog::FlagDefinitionCacheProvider for the required interface.'
  end
end

#should_fetch_flag_definitions? ⇒ Boolean

Return true if this instance should fetch new definitions from the API, false to read from cache instead. Use for distributed lock coordination so only one worker fetches at a time.

Returns:

  • (Boolean)


65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/posthog/flag_definition_cache.rb', line 65

module FlagDefinitionCacheProvider
  REQUIRED_METHODS = %i[
    flag_definitions
    should_fetch_flag_definitions?
    on_flag_definitions_received
    shutdown
  ].freeze

  # Validates that +provider+ implements all required methods.
  # Raises +ArgumentError+ listing any missing methods.
  #
  # @param provider [Object] the cache provider to validate
  # @raise [ArgumentError] if any required methods are missing
  # @return [void]
  def self.validate!(provider)
    missing = REQUIRED_METHODS.reject { |m| provider.respond_to?(m) }
    return if missing.empty?

    raise ArgumentError,
          "Flag definition cache provider is missing required methods: #{missing.join(', ')}. " \
          'See PostHog::FlagDefinitionCacheProvider for the required interface.'
  end
end

#shutdown ⇒ void

This method returns an undefined value.

Called when the PostHog client shuts down. Release any distributed locks and clean up resources.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/posthog/flag_definition_cache.rb', line 65

module FlagDefinitionCacheProvider
  REQUIRED_METHODS = %i[
    flag_definitions
    should_fetch_flag_definitions?
    on_flag_definitions_received
    shutdown
  ].freeze

  # Validates that +provider+ implements all required methods.
  # Raises +ArgumentError+ listing any missing methods.
  #
  # @param provider [Object] the cache provider to validate
  # @raise [ArgumentError] if any required methods are missing
  # @return [void]
  def self.validate!(provider)
    missing = REQUIRED_METHODS.reject { |m| provider.respond_to?(m) }
    return if missing.empty?

    raise ArgumentError,
          "Flag definition cache provider is missing required methods: #{missing.join(', ')}. " \
          'See PostHog::FlagDefinitionCacheProvider for the required interface.'
  end
end