On Wed, Sep 14, 2011 at 10:26, Andrey Somov <[email protected]>wrote:
> Hi Dirkjan,
> when I see the code like the one below (couch_server) I realize that I do
> not understand the complete picture.
> I do not get what is linked with what at the end.
> I am wondering if someone can go through the code and explain it line by
> line.
> And I have severe difficulties to organize a working Erlang environment.
>
> Do you have plans to attend any local conference in the nearest future ?
> (by
> the way I live in Den Haag)
>
>
As a fun exercise, I'll happily do that right now with this chunk.
If you need erlang help, the Armstrong "Programming Erlang" book is a good
read.
> open_async(Server, From, DbName, Filepath, Options) ->
> Parent = self(),
>
First, store the current process ID so it can be accessed later on, from a
closure running in another process.
> Opener = spawn_link(fun() ->
> Res = couch_db:start_link(DbName, Filepath, Options),
> gen_server:call(
> Parent, {open_result, DbName, Res, Options}, infinity
> ),
> unlink(Parent),
> case Res of
> {ok, DbReader} ->
> unlink(DbReader);
> _ ->
> ok
> end
> end),
>
Spawn another process to execute a function (in this case an anonymous 'fun'
[lambda]).
Start a new couch_db gen_server process, returning a handle (Res) to the
process.
Notify the couch_server process, via the gen_server:call RPC mechanism, that
the database is open and send it a handle to the newly opened database
couch_db process. This line is why we saved Parent in the first line.
Unlink this process from its parent so that it can die without sending
unnecessary messages to the parent or the couch_db process.
> true = ets:insert(couch_dbs_by_name, {DbName, {opening, Opener,
> [From]}}),
> true = ets:insert(couch_dbs_by_pid, {Opener, DbName}),
>
Store, using the built-in ets module, a reference to the calling process so
that when the fun that was spawned above reports a successful open, this
couch_server process can return the database reference to the caller.
> DbsOpen = case lists:member(sys_db, Options) of
> true ->
> true = ets:insert(couch_sys_dbs, {DbName, true}),
> Server#server.dbs_open;
> false ->
> Server#server.dbs_open + 1
> end,
>
This is just logic so that the system databases (_users, _replicator) don't
count against the maximum number of open databases.
> Server#server{dbs_open = DbsOpen}.
>
This is the new state of the couch_server process.
There are four processes interacting in total:
1) the process opening a database
2) the couch_server process which maintains the state of all open databases
and manages closing the least recently used when applicable
3) the couch_db process which controls the open database
4) the anonymous process which decouples (2) from the start-up and
initialization of (3) so that couch_server can service concurrent requests
while a database is being opened.
Isn't Erlang fun?
(No pun intended.)
Cheers,
-Randall
>
> On Wed, Sep 14, 2011 at 7:01 PM, Dirkjan Ochtman <[email protected]>
> wrote:
>
> > On Wed, Sep 14, 2011 at 18:54, Andrey Somov <[email protected]>
> > wrote:
> > > I would be happy to join a meetup of CouchDB developers.
> > > Googling did not help to find either CouchDB or Erlang community here
> in
> > the
> > > Netherlands. Can someone help me ? Is there one ?
> >
> > There are a few Dutchies involved with CouchDB, but I don't think
> > there's been much actual contribution in terms of Erlang code. AFAIK,
> > most of us just use CouchDB in one way or another (or help out around
> > the edges; couchdb-python, paisley, Futon).
> >
> > Cheers,
> >
> > Dirkjan
> >
>