You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@couchdb.apache.org by Antony Blakey <an...@gmail.com> on 2009/02/02 06:40:56 UTC
Simple erlang plugins (was Re: couch_gen_btree: pluggable storage / tree engines)
I've recreated my simple erlang plugins system
http://github.com/AntonyBlakey/couchdb/tree/simple-erlang-plugins
A plugin is a directory. It can contain a plugin.ini file and an
erlang directory.
The erlang directory is added to the erlang load path - you put your
beam files in there.
The plugin.ini file is loaded after the default.ini, but before
local.ini. If you supply your own ini files on the command line then
it comes before them.
To start your plugin you probably want to add to the [daemons] section
of your plugin.ini file. Check start_secondary_services in
couch_server_sup.erl to see what happens with daemons, and you can see
examples in default.ini (.tpl.in in the source).
If plugins need to be integrated in a different fashion, or
dependencies are needed, then I'd suggest that a different config
section be created to handle richer specification/invocation option
format than [daemons].
There are command line options for manipulating the list of plugins.
By default it will load plugins from /etc/couchdb/plugins/ or whatever
your localconfdir is - mine is always relative - but this can be
controlled by the options:
-C clean the plugins list
-D add all the plugins in $DEFAULT_PLUGIN_DIR
-G DIR add all the plugins in DIR
-P DIR add the plugin DIR
Bit light on testing, I wanted to show how trivial it is.
Antony Blakey
-------------
CTO, Linkuistics Pty Ltd
Ph: 0438 840 787
There are two ways of constructing a software design: One way is to
make it so simple that there are obviously no deficiencies, and the
other way is to make it so complicated that there are no obvious
deficiencies.
-- C. A. R. Hoare
Re: Simple erlang plugins (was Re: couch_gen_btree: pluggable storage / tree engines)
Posted by Antony Blakey <an...@gmail.com>.
On 02/02/2009, at 8:56 PM, Noah Slater wrote:
> I've found this thread a little hard to follow so far, but why not
> configure the
> plugins from /etc/couchdb/local.ini itself, including the
> configuration that
> tells CouchDB which plugins to work. I'm not sure I'm comfortable
> with the idea
> of CouchDB scanning a list of directories each time, loading things
> automatically.
I did it this way to avoid touching the CouchDB code, and not wanting
to impose another file format or do parsing in shell script.
Especially given that I have an imminent requirement for CouchDB/Win32
where the shell is complete shit. OTOH I may have to replace the start
script with C for that reason.
It might be better to have an erlang plugin manager that can deal with
plugin selection, dependencies and ordering requirements, but that's a
more intrusive solution.
Antony Blakey
--------------------------
CTO, Linkuistics Pty Ltd
Ph: 0438 840 787
The greatest challenge to any thinker is stating the problem in a way
that will allow a solution
-- Bertrand Russell
Re: Simple erlang plugins (was Re: couch_gen_btree: pluggable
storage / tree engines)
Posted by Noah Slater <ns...@apache.org>.
On Mon, Feb 02, 2009 at 06:07:37PM +1030, Antony Blakey wrote:
> My concern is how to allow plugins to be updated without stomping on
> user configuration, which is why I suggest having the local plugin
> configuration be outside of the plugin's directory. Maybe that's a
> deployment required that's unlike to happen, but I look forward to a
> time when couch plugins are like rubygems and regular updating is
> common.
I've found this thread a little hard to follow so far, but why not configure the
plugins from /etc/couchdb/local.ini itself, including the configuration that
tells CouchDB which plugins to work. I'm not sure I'm comfortable with the idea
of CouchDB scanning a list of directories each time, loading things automatically.
--
Noah Slater, http://tumbolia.org/nslater
Re: Simple erlang plugins (was Re: couch_gen_btree: pluggable storage / tree engines)
Posted by Antony Blakey <an...@gmail.com>.
On 02/02/2009, at 5:36 PM, Chris Anderson wrote:
> Maybe each plugin could have a default.ini and a local.ini, so
> something like:
>
> plugins/
> geo_index/
> Makefile.am.in
> src/
> geo_index.erl
> geo_httpd.erl
> geo_manager.erl
> default.ini
> local.ini
> ...
>
>
> Then CouchDB could automatically pickup plugin config from each
> directory, running all the defaults before all the locals.
I think we may be talking at cross-purposes here - I'm thinking
particularly of plugins that are separately compiled without being
included in the canonical sources, while I gather you're focussed on a
refactored core or a way to handle less tightly coupled contributions.
I'm interested in seeing those things happen, but I'll be guided by
you as to what I should for that. In particular I know sfa about
automake et al.
OTOH, I think top level default.ini + local.ini + local.*.ini would be
a good idea regardless, and a simple change.
> I'm not invested in these specifics, just trying to think of ways it
> could look that would give new developers the least amount of
> head-scratching.
I think head-scratching would be best mitigated by some good docs. If
we want to implement this then I'll commit to writing a spec/tutorial
on the wiki.
My concern is how to allow plugins to be updated without stomping on
user configuration, which is why I suggest having the local plugin
configuration be outside of the plugin's directory. Maybe that's a
deployment required that's unlike to happen, but I look forward to a
time when couch plugins are like rubygems and regular updating is
common.
Somewhat OT: plugins are also a mechanism for deploying generic non-
couch functionality for a deployment scenario like mine where every
user runs a Couch instance ala Notes client e.g. distributed voting
algorithms and scalaris-like functionality for emergent clusters
within wider p2p meshes.
Antony Blakey
--------------------------
CTO, Linkuistics Pty Ltd
Ph: 0438 840 787
Plurality is not to be assumed without necessity
-- William of Ockham (ca. 1285-1349)
Re: Simple erlang plugins (was Re: couch_gen_btree: pluggable storage
/ tree engines)
Posted by Chris Anderson <jc...@apache.org>.
On Sun, Feb 1, 2009 at 10:39 PM, Antony Blakey <an...@gmail.com> wrote:
>
> I imagined that the ini file in the plugin directory wouldn't be modified by
> users i.e. that's "part of the plugin". Users would modify the local.ini
> file to change the user-configurable parts of that. That makes me think that
> the startup script should load local.*.ini, so you can separate your
> per-plugin user-configurable bits. The reason for not modifying the
> plugin.ini directly is so that you can update them easily.
>
There's a bunch of ways we could do this. The simplest overall system
I can think of would be a `make plugins` target that builds whatever
is in the plugins directory.
Maybe each plugin could have a default.ini and a local.ini, so something like:
plugins/
geo_index/
Makefile.am.in
src/
geo_index.erl
geo_httpd.erl
geo_manager.erl
default.ini
local.ini
...
Then CouchDB could automatically pickup plugin config from each
directory, running all the defaults before all the locals.
I'm not invested in these specifics, just trying to think of ways it
could look that would give new developers the least amount of
head-scratching.
--
Chris Anderson
http://jchris.mfdz.com
Re: Simple erlang plugins (was Re: couch_gen_btree: pluggable storage / tree engines)
Posted by Antony Blakey <an...@gmail.com>.
On 02/02/2009, at 4:46 PM, Chris Anderson wrote:
> On Sun, Feb 1, 2009 at 9:40 PM, Antony Blakey
> <an...@gmail.com> wrote:
>> There are command line options for manipulating the list of
>> plugins. By
>> default it will load plugins from /etc/couchdb/plugins/ or whatever
>> your
>> localconfdir is - mine is always relative - but this can be
>> controlled by
>> the options:
>
>> -C clean the plugins list
>> -D add all the plugins in $DEFAULT_PLUGIN_DIR
>> -G DIR add all the plugins in DIR
>> -P DIR add the plugin DIR
>> Bit light on testing, I wanted to show how trivial it is.
>
> Thanks for getting started on this. It looks like with a make plugins
> target, this will be ready to roll.
I think there are multiple levels of modularity possible - some core
features could be plugins, purely in a separation-of-concerns kind of
way. Then there would be third-party plugins. This could be a
convenient way to play with some new contributions without having to
merge into the a single code directory (assuming each plugin is
separate in the source). And finally there would be per-user plugins
that customize couch on a per-app basis.
I assume you mean a make plugins target for core plugins?
> One thing I don't understand is the plugins list and the additional
> command-line options to launch script. I wonder if there's a
> non-ephemeral way to control the list of loaded plugins.
Well, there is the default location. If a plugin were to have an
extension e.g. '.plugin' then the activation could be controlled via
renaming. OTOH I like the Apache (httpd) mechanism of having
'available/active' dirs, which seems cleaner.
I use the command line options to the startup script because I have
couchdb/erlang/icu etc packaged as ruby gems that deploys couch using
dependcies, and the class that controls couchdb allows multiple
instances in self-contained locations. It looks a bit like this:
---------------------------------------
require 'memetic'
require 'memetic-erlang'
require 'memetic-spidermonkey'
require 'memetic-icu'
module Memetic
class CouchDB
DIRECTORY = %x{cd #{File.dirname(File.dirname(__FILE__)) + "/
BUILD"} ; pwd}.split()[0]
def CouchDB.configure_environment(env)
Erlang.configure_environment(env)
Spidermonkey.configure_environment(env)
ICU.configure_environment(env)
end
def initialize(local_directory)
@local_directory = local_directory
Dir.mkdir(@local_directory) unless File.exists?(@local_directory)
@log_directory = "#{@local_directory}/log"
Dir.mkdir(@log_directory) unless File.exists?(@log_directory)
@data_directory = "#{@local_directory}/data"
Dir.mkdir(@data_directory) unless File.exists?(@data_directory)
File.open("#{@local_directory}/configuration.ini", "w") do |f|
f << configuration()
end
end
def start
env = Environment.new
CouchDB.configure_environment(env)
cmd = env.as_command_prefix
cmd << "( cd '#{DIRECTORY}' ; "
cmd << "./bin/couchdb -b "
cmd << "-o '#{@log_directory}/couchdb.stdout' "
cmd << "-e '#{@log_directory}/couchdb.stderr' "
cmd << "-p '#{@local_directory}/pid' "
cmd << "-c './etc/couchdb/default.ini' "
cmd << "-c '#{@local_directory}/configuration.ini' "
#cmd << "-G '#{@local_directory}/plugins' "
cmd << " )"
IO.popen(cmd) do |p|
s = p.gets
s.chomp if s
end
end
def status
env = Environment.new
CouchDB.configure_environment(env)
IO.popen("#{env.as_command_prefix} #{DIRECTORY}/bin/couchdb -p
#{@local_directory}/pid -s") do |p|
s = p.gets
s.chomp if s
end
end
def stop
env = Environment.new
CouchDB.configure_environment(env)
IO.popen("#{env.as_command_prefix} #{DIRECTORY}/bin/couchdb -p
#{@local_directory}/pid -d") do |p|
s = p.gets
s.chomp if s
end
end
def configuration
return <<END_OF_STRING
[couchdb]
database_dir = #{@data_directory}
[log]
file = #{@log_directory}/couch.log
level = debug
END_OF_STRING
end
end
end
---------------------------------------
> As far as configuration, users will likely also want to configure
> their API endpoints as http_db_handlers or http_global_handlers. These
> allow you to hook an Erlang function directly to a CouchDB path.
Sure.
I imagined that the ini file in the plugin directory wouldn't be
modified by users i.e. that's "part of the plugin". Users would modify
the local.ini file to change the user-configurable parts of that. That
makes me think that the startup script should load local.*.ini, so you
can separate your per-plugin user-configurable bits. The reason for
not modifying the plugin.ini directly is so that you can update them
easily.
Antony Blakey
-------------
CTO, Linkuistics Pty Ltd
Ph: 0438 840 787
A reasonable man adapts himself to suit his environment. An
unreasonable man persists in attempting to adapt his environment to
suit himself. Therefore, all progress depends on the unreasonable man.
-- George Bernard Shaw
Re: Simple erlang plugins (was Re: couch_gen_btree: pluggable storage
/ tree engines)
Posted by Chris Anderson <jc...@apache.org>.
On Sun, Feb 1, 2009 at 9:40 PM, Antony Blakey <an...@gmail.com> wrote:
> There are command line options for manipulating the list of plugins. By
> default it will load plugins from /etc/couchdb/plugins/ or whatever your
> localconfdir is - mine is always relative - but this can be controlled by
> the options:
> -C clean the plugins list
> -D add all the plugins in $DEFAULT_PLUGIN_DIR
> -G DIR add all the plugins in DIR
> -P DIR add the plugin DIR
> Bit light on testing, I wanted to show how trivial it is.
Thanks for getting started on this. It looks like with a make plugins
target, this will be ready to roll.
One thing I don't understand is the plugins list and the additional
command-line options to launch script. I wonder if there's a
non-ephemeral way to control the list of loaded plugins.
At this point `utils/run` is still a copy-paste job from `couchdb`.
Now might be a good opportunity to make that more sensible.
As far as configuration, users will likely also want to configure
their API endpoints as http_db_handlers or http_global_handlers. These
allow you to hook an Erlang function directly to a CouchDB path.
--
Chris Anderson
http://jchris.mfdz.com
Re: Simple erlang plugins (was Re: couch_gen_btree: pluggable storage
/ tree engines)
Posted by Ben Browning <be...@gmail.com>.
To spark some additional conversation around plugins, is there a clear
idea how we would handle plugin X that also uses plugin Y? For
example, I could see the Erlang API, the partitioning/clustering
functionality, and individual pieces of the clustering as additional
plugins (consistent hashing algorithm being the immediately obvious
one). The partitioning would depend on the Erlang API and a consistent
hashing plugin being configured.
For now I'm just throwing additional modules in the src/couchdb
directory in my git branch but there are enough modules in there it
makes me hesitate to add more. We could separate these into multiple
folders by using Erlang packages, but a plugin system could accomplish
the same goal and provide additional benefit for 3rd-party plugins.
It's not a pressing priority, but getting a plugin system in-place
would better allow for 3rd-party development around CouchDB and make
it easier to release and version functionality separately from the
core app.
Ben
Re: Simple erlang plugins (was Re: couch_gen_btree: pluggable storage
/ tree engines)
Posted by Chris Anderson <jc...@apache.org>.
On Mon, Feb 2, 2009 at 4:39 AM, Antony Blakey <an...@gmail.com> wrote:
>
> On 02/02/2009, at 10:34 PM, Jan Lehnardt wrote:
>
>>
>> On 2 Feb 2009, at 12:45, Antony Blakey wrote:
>>
>>>
>>> On 02/02/2009, at 10:09 PM, Noah Slater wrote:
>>>
>>>> That's fine with me. (Says the man who's not going to develop it.)
>>>
>>> Unfortunately requiring a bigger commitment to this feature than I can
>>> manage at this time.
>>
>> I hope you can push for an agreed-upon design and give a rough todo list
>> and maybe start with it and leave open work items with a good description
>> in JIRA for others to pick up. Would that work?
>
> It's just a matter of doing in erlang what I did in the script, finding out
> how to extend the load path. Hopefully my implementation shows how
> conceptually trivial it is. I agree with Noah about the configuration issue.
> Probably the only trick is that you need to load the config to find the
> plugins and then load more config from each plugin.
>
> I need to focus on the transactional _bulk_docs issue, and then the filename
> patch - that's a 0.9 blocker.
>
Yes, I think having this thread open which lays out the possibilities
is good work as long as we can avoid losing them to history by the
time we are ready to implement the plugin thing.
I think dropping a patch in Jira with a someday/maybe priority is th
best way to let us pick back up when the time comes.
--
Chris Anderson
http://jchris.mfdz.com
Re: Simple erlang plugins (was Re: couch_gen_btree: pluggable storage / tree engines)
Posted by Jan Lehnardt <ja...@apache.org>.
On 2 Feb 2009, at 13:39, Antony Blakey wrote:
>
> On 02/02/2009, at 10:34 PM, Jan Lehnardt wrote:
>
>> I hope you can push for an agreed-upon design and give a rough todo
>> list
>> and maybe start with it and leave open work items with a good
>> description
>> in JIRA for others to pick up. Would that work?
>
> It's just a matter of doing in erlang what I did in the script,
> finding out how to extend the load path. Hopefully my implementation
> shows how conceptually trivial it is. I agree with Noah about the
> configuration issue. Probably the only trick is that you need to
> load the config to find the plugins and then load more config from
> each plugin.
>
> I need to focus on the transactional _bulk_docs issue, and then the
> filename patch - that's a 0.9 blocker.
Great, thanks. Focus is good.
Cheers
Jan
--
Re: Simple erlang plugins (was Re: couch_gen_btree: pluggable storage / tree engines)
Posted by Antony Blakey <an...@gmail.com>.
On 02/02/2009, at 10:34 PM, Jan Lehnardt wrote:
>
> On 2 Feb 2009, at 12:45, Antony Blakey wrote:
>
>>
>> On 02/02/2009, at 10:09 PM, Noah Slater wrote:
>>
>>> That's fine with me. (Says the man who's not going to develop it.)
>>
>> Unfortunately requiring a bigger commitment to this feature than I
>> can manage at this time.
>
> I hope you can push for an agreed-upon design and give a rough todo
> list
> and maybe start with it and leave open work items with a good
> description
> in JIRA for others to pick up. Would that work?
It's just a matter of doing in erlang what I did in the script,
finding out how to extend the load path. Hopefully my implementation
shows how conceptually trivial it is. I agree with Noah about the
configuration issue. Probably the only trick is that you need to load
the config to find the plugins and then load more config from each
plugin.
I need to focus on the transactional _bulk_docs issue, and then the
filename patch - that's a 0.9 blocker.
Antony Blakey
-------------
CTO, Linkuistics Pty Ltd
Ph: 0438 840 787
The intuitive mind is a sacred gift and the rational mind is a
faithful servant. We have created a society that honours the servant
and has forgotten the gift.
-- Albert Einstein
Re: Simple erlang plugins (was Re: couch_gen_btree: pluggable storage / tree engines)
Posted by Jan Lehnardt <ja...@apache.org>.
On 2 Feb 2009, at 12:45, Antony Blakey wrote:
>
> On 02/02/2009, at 10:09 PM, Noah Slater wrote:
>
>> That's fine with me. (Says the man who's not going to develop it.)
>
> Unfortunately requiring a bigger commitment to this feature than I
> can manage at this time.
I hope you can push for an agreed-upon design and give a rough todo list
and maybe start with it and leave open work items with a good
description
in JIRA for others to pick up. Would that work?
Cheers
Jan
--
Re: Simple erlang plugins (was Re: couch_gen_btree: pluggable storage / tree engines)
Posted by Antony Blakey <an...@gmail.com>.
On 02/02/2009, at 10:09 PM, Noah Slater wrote:
> That's fine with me. (Says the man who's not going to develop it.)
Unfortunately requiring a bigger commitment to this feature than I can
manage at this time.
Antony Blakey
-------------
CTO, Linkuistics Pty Ltd
Ph: 0438 840 787
A Buddhist walks up to a hot-dog stand and says, "Make me one with
everything". He then pays the vendor and asks for change. The vendor
says, "Change comes from within".
Re: Simple erlang plugins (was Re: couch_gen_btree: pluggable
storage / tree engines)
Posted by Noah Slater <ns...@apache.org>.
On Mon, Feb 02, 2009 at 10:06:48PM +1030, Antony Blakey wrote:
>
> On 02/02/2009, at 9:48 PM, Noah Slater wrote:
>
>> I think I agree with a comment earlier in this thread. I don't think
>> command
>> options are the place for this type of configuration. Ideally, you'd
>> want all
>> the configuration in the ini file.
>
> That means that the plugin system needs to be written in CouchDB itself,
> rather than being a lightweight launch-time facility.
That's fine with me. (Says the man who's not going to develop it.)
--
Noah Slater, http://tumbolia.org/nslater
Re: Simple erlang plugins (was Re: couch_gen_btree: pluggable storage / tree engines)
Posted by Antony Blakey <an...@gmail.com>.
On 02/02/2009, at 9:48 PM, Noah Slater wrote:
> I think I agree with a comment earlier in this thread. I don't think
> command
> options are the place for this type of configuration. Ideally, you'd
> want all
> the configuration in the ini file.
That means that the plugin system needs to be written in CouchDB
itself, rather than being a lightweight launch-time facility.
Antony Blakey
-------------
CTO, Linkuistics Pty Ltd
Ph: 0438 840 787
The ultimate measure of a man is not where he stands in moments of
comfort and convenience, but where he stands at times of challenge and
controversy.
-- Martin Luther King
Re: Simple erlang plugins (was Re: couch_gen_btree: pluggable
storage / tree engines)
Posted by Noah Slater <ns...@apache.org>.
On Mon, Feb 02, 2009 at 09:31:36PM +1030, Antony Blakey wrote:
>>> -D add all the plugins in $DEFAULT_PLUGIN_DIR
>>> -G DIR add all the plugins in DIR
>>> -P DIR add the plugin DIR
>>
>> Why have you chosen all capitals?
>
> Because all the obvious lower case options have been used. I wanted to
> use long options, but the shell getopts doesn't allow it.
I think I agree with a comment earlier in this thread. I don't think command
options are the place for this type of configuration. Ideally, you'd want all
the configuration in the ini file. If you really need to override some ini file
setting, maybe using an environment variable would be the way forward.
Bottom line: I want to keep the number of command line options small.
--
Noah Slater, http://tumbolia.org/nslater
Re: Simple erlang plugins (was Re: couch_gen_btree: pluggable storage / tree engines)
Posted by Antony Blakey <an...@gmail.com>.
On 02/02/2009, at 8:51 PM, Noah Slater wrote:
> This sounds pretty good.
>
> On Mon, Feb 02, 2009 at 04:10:56PM +1030, Antony Blakey wrote:
>> -C clean the plugins list
>
> What does this do? I think it needs more explanation.
clear the plugin list.
The plugin list is by default all the plugins in $DEFAULT_PLUGIN_DIR. -
C clears the list, either to run without plugins, or as a precursor to
using -D -G -P in some order to define a specific plugin ordering and/
or load additional plugins from non-default locations.
>> -D add all the plugins in $DEFAULT_PLUGIN_DIR
>> -G DIR add all the plugins in DIR
>> -P DIR add the plugin DIR
>
> Why have you chosen all capitals?
Because all the obvious lower case options have been used. I wanted to
use long options, but the shell getopts doesn't allow it.
Antony Blakey
-------------
CTO, Linkuistics Pty Ltd
Ph: 0438 840 787
There are two ways of constructing a software design: One way is to
make it so simple that there are obviously no deficiencies, and the
other way is to make it so complicated that there are no obvious
deficiencies.
-- C. A. R. Hoare
Re: Simple erlang plugins (was Re: couch_gen_btree: pluggable
storage / tree engines)
Posted by Noah Slater <ns...@apache.org>.
This sounds pretty good.
On Mon, Feb 02, 2009 at 04:10:56PM +1030, Antony Blakey wrote:
> -C clean the plugins list
What does this do? I think it needs more explanation.
> -D add all the plugins in $DEFAULT_PLUGIN_DIR
> -G DIR add all the plugins in DIR
> -P DIR add the plugin DIR
Why have you chosen all capitals?
--
Noah Slater, http://tumbolia.org/nslater