Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
Update documentation
  • Loading branch information
iilyak committed Oct 1, 2015
1 parent d6c5081 commit 6cb1b9ca98a3e5bcf6fc72e791e13a07a564cf0c
Showing 3 changed files with 48 additions and 49 deletions.
@@ -20,39 +20,40 @@

## Support release upgrade

We monitor the source of config information and have an ability to notify the subscriber.
The source is either a file for a `couch_epi_data_source` or module for `couch_epi_functions`.
We monitor the modules involved in configuration of the service/provider so we
get notified when there is a code upgrade. We use this notification in order to:

If the subscriber wants to receive notifications when the config has been updated it can use:
- regenerate dispatch module if needed
- call notify/3 of a module implementing couch_epi_plugin behaviour

couch_epi:subscribe(App, Key, Module, Func, ExtraArgs)

The function would be called with following arguments

Fun(App :: app(), Key :: key(),
OldData :: notification(), NewData :: notification(),
ExtraArgs :: term()

The `notification()` is either `{data, term()}` or `{modules, [module()]}`
Call to notify/3 would be called for both providers and data_providers.

## data example

Any application that wants to register some configuration data for a service using module
could add an entry in its supervision tree with something like:
could add an entry in its implementation of couch_epi_plugin behaviour:

Spec = couch_epi_data:childspec(
appname_stats, %% Id
appname, %% CurrentApp
{epi_key, {couch_stats, definitions}},
appname_stats_config %% Module
).
data_providers() ->
[
{{couch_stats, descriptions},
{priv_file, "stats_descriptions.cfg"}, [{interval, 5000}]}
{{couch_stats, descriptions},
{file, "/tmp/extra_stats.cfg"}, [{interval, 5000}]},
{{couch_stats, descriptions}, {module, my_stats}}
].

When service provider wants to learn about all the installed config data for it to use
it would then just do something like:


couch_epi:get(Handle, Service, Key)

The service provider also have to mention the data keys it is using in its
implementation of couch_epi_plugin behaviour

data_subscriptions() ->
[{couch_stats, descriptions}].

There are also additional functions to get the same data in various formats

- `couch_epi:all(Handle)` - returns config data for all services for a given handle
@@ -65,38 +66,22 @@ There are also additional functions to get the same data in various formats
- `couch_epi:subscribers(Handle)` - return list of known subscribers



## data_source example

Any application that wants to register some configuration data for a service
could add an entry in its supervision tree with something like:

Spec = couch_epi_data_source:childspec(
appname_stats, %% Id
appname, %% CurrentApp
{epi_key, {couch_stats, definitions}},
{priv_file, "couch_stats.cfg"},
[{interval, 5000}]
).

Note we also support `{file, FilePath}` instead of `{priv_file, File}`

The query API is the same as for `data` (see `data example`)

# Function dispatch example

Any application that wants to register some functions for a service
could add an entry in its supervision tree with something like:
Any application that wants to register implementation functions for a service
could add following into it's implementation of couch_epi_plugin behaviour:

providers() ->
[{my_service, module_which_implements_the_functions}].

Spec = couch_epi_functions:childspec(
appname_stats, %% child id
appname, %% CurrentApp
my_service,
my_module %% Module
).
Adding the entry would generate a dispatch methods for any exported function
of modules passed.

Adding the entry would generate a dispatch methods for any exported function of modules passed.
Services have to be defined in one of the implementations of couch_epi_plugin
behaviour as:

services() ->
[{my_service, module_to_monitor_for_codechange}].

When app wants to dispatch the call to all service providers it calls

@@ -111,3 +96,18 @@ There are multiple ways of doing the apply which is controlled by Opts
Notes:

- `concurrent` is incompatible with `pipe`

# couch_epi_plugin behaviour

The module implementing behaviour need to export following functions:

- Module:app/0 - Returns atom representing the application name
- Module:providers/0 - Returns list of {service_id(), module()} tuples
for defined providers
- Module:services/0 - Returns list of {service_id(), module()} tuples
for defined services
- Module:data_subscriptions/0 - Returns list of keys we define
- Module:data_providers/0 - Returns list of keys we provide
- Module:processes/0 - Supervisor specs which we would be injected into
application supervisor
- Module:notify/3 - Notification callback
@@ -12,7 +12,6 @@

-module(couch_epi).

%% subscribtion management
-export([get_handle/1]).
-export([register_service/1]).

@@ -12,10 +12,10 @@

-module(couch_epi_sup).

%% ----------------------------------
%% --------------------
%% Important assumption
%% ====================
%% Keeper and codechange_monitor childspecs relie on underdocumented feature.
%% Keeper and codechange_monitor childspecs rely on undocumented behaviour.
%% According to supervisor docs:
%% ...if the child process is a supervisor, gen_server, or gen_fsm, this
%% should be a list with one element [Module].

0 comments on commit 6cb1b9c

Please sign in to comment.