incubator-couchdb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jan Lehnardt <...@apache.org>
Subject [PLUGINS] Plugin Hooks
Date Thu, 08 Aug 2013 08:47:55 GMT
Heya,

I’m toying with the idea of moving some of my experimental into
bona-fide plugins. One of them is my log_to_db branch that on top of
writing log messages to a text file also writes a document to a log
database.

Conceptually, this is the perfect use of a plugin: the feature is not
useful in the general case, because *any* activity creates write load
on a single database, but for certain low-volume installations, this
might be a useful feature (I wouldn’t have written it, if I hadn’t
needed it at some point) so allowing users to enable it as a plugin
would be nice.

But regardless of whether my plugin is useful, it illustrates an
interesting point:

A log_to_db plugin would need to register for logging events or, if it
doesn’t want to duplicate all the logging-level logic in couch_log, it
would need some way of injecting a function call into
`couch_log:log().`. We could of course try and find a way where a
plugin would be able to provide an API compatible version of a CouchDB
module and swap it out for it’s custom one, but that’s hardly a great
idea.

Other software has the notion of “hooks” (some may call it something
else) where at well defined points in the main code base, external
functions get called with certain parameters. To make things dynamic,
there might be a way for plugins to register to be called by those
hooks and the main code then asks the registry whether there are any
plugin functions to call.

In the log_to_db example, we’d have something like this:

couch_log_to_db.erl:

    init() ->
        couch_hooks:register(couch_log_hook, log_hook_fun/1),
        ok.

    log_hook_fun(Log) ->
        % do the log_to_db magic
        ok.


couch_hooks.erl:

    register(Hook, Fun) ->
        % store the Fun with the Hook somewhere
        ok.

    call(Hook, Args) ->
         % retrieve Fun for Hook from somewhere
        Fun(Args).

couch_log.erl:

% in log()

    ...
    couch_hooks:call(couch_log_hook, Args),
    ...

The main code would define what the hook name and arguments are and the
plugin would have to conform. The plugin registry would just manage the
registration and calling of functions for a hook, but nothing more.

* * *

This is just my first stab at this not thinking about it too much and I
likely miss some subtleties in Erlang that make this not work (hot code
upgrades e.g.).


How do you think we should implement a hooks feature in CouchDB?


Thanks!
Jan
-- 





Mime
View raw message