On Aug 8, 2013, at 12:39 , Jason Smith <j...@apache.org> wrote:

> Well, I just googled it. Basically there is a couchdb_plugin.erl which
> tells Erlang what a behavior looks like. And all that does is define the
> functions and arity which a couchdb_plugin would have to export.
> 
> Probably there are some better Erlangers on the list who might chime in. It
> looks like okay bang-for-buck; only not much bang or much buck.

how would this work if a plugin is only interested in handling a single hook,
would it have to implement mock funs for all hooks then?

> On Thu, Aug 8, 2013 at 5:26 PM, Jan Lehnardt <j...@apache.org> wrote:
> 
>> how would this look in code?
>> 
>> On Aug 8, 2013, at 12:21 , Jason Smith <j...@apache.org> wrote:
>> 
>>> Perhaps a custom behaviour to help catch API problems at compile time?
>>> 
>>>   -behaviour(couchdb_plugin).
>>> 
>>> 
>>> 
>>> On Thu, Aug 8, 2013 at 3:47 PM, Jan Lehnardt <j...@apache.org> wrote:
>>> 
>>>> 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
>>>> --
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>> 
>> 

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

Reply via email to