SharedSettings (shared_settings v0.2.0)

SharedSettings is a library for fetching and updating settings at runtime.

The goal of this is to provide a simple, language-agnostic storage interface as well as an accompanying Ruby gem (TODO) and UI. This is not intended to be a fully-fledged feature flagging library (see FunWithFlags if you need that). Instead, this is geared toward updating settings represented by a string, integer, etc., for the purpose of easing runtime tweaking of knobs.

Link to this section Summary

Functions

Deletes a setting by name from cache and storage.

Checks whether a given setting exists

Fetches a setting by name.

Fetches all stored settings.

Creates or updates a setting.

Link to this section Types

Link to this type

setting_name()

Specs

setting_name() :: atom() | String.t()

Link to this section Functions

Specs

delete(setting_name()) :: :ok

Deletes a setting by name from cache and storage.

Arguments

  • name - An atom representing the name of the setting to delete

Returns

If the setting was deleted :ok is returned.

This method returns :ok if the setting wasn't found so it's safe to match on :ok

Specs

exists?(setting_name()) :: boolean()

Checks whether a given setting exists

Arguments

  • name - An atom or string representing the name of the setting to check

Returns

Returns a boolean based on if the setting was found.

This uses the same logic as get so cache is hit first

Specs

get(setting_name()) :: {:ok, any()} | {:error, any()}

Fetches a setting by name.

Fetches from cache first and falls back to storage if a setting isn't found/is expired.

Arguments

  • name - An atom or string representing the name of the setting to fetch

Returns

If a setting is found, returns a tuple of :ok and the stored value

If a setting is not found, returns {:error, :not_found}

If there is an error with the storage adaptor that error is passed straight though as {:error, any()}

Specs

get_all() :: {:ok, [SharedSettings.Setting.t()]} | {:error, any()}

Fetches all stored settings.

This method differs from others in the fact that:

  1. The cache isn't hit, only the source of truth (ie: the store)
  2. The raw Setting.t() is returned instead of the final re-hydrated value (save for decryption)

Both of these changes come from the fact that this is meant to feed the UI. The reason it's exposed on the main module is that there's a secondary personal usecase for setting presence validation on app boot.

Since this is hitting the store directly thought should be put into if/how frequently this is called

Returns

If successful (even if no settings are found), returns {:ok, [Setting.t()]}

If there is an error with the storage adaptor that error is passed straight though as {:error, any()}

Link to this function

put(name, value, opts \\ [])

Creates or updates a setting.

Settings are unique by name and creating a second setting with the same name will overwrite the original.

Arguments

  • name - An atom or string representing the name of the setting. Used for fetching/deleting
  • value - Any data of type string, number, boolean, or range

Returns

If a setting is successfully stored, a tuple of :ok and the setting name as a string is returned.

If value's type isn't supported, {:error, :unsupported_type} is returned

Any other failures (say, from the storage adaptor) will be returned as-is. Failures to write to cache will not be returned as an error so long as writing to storage succeeds.