Skip to content
This repository

Erlang View Server for CouchDB

branch: master
README
Mon Oct 19 15:52:40 PDT 2009
Michael McDaniel

 You really ought to upgrade CouchDB to 0.10.0 or above and use
 the built-in Erlang view server.  
 See http://wiki.apache.org/couchdb/EnableErlangViews

TODO:

1) erlview should be parameterized in local.ini
2) add to Makefile the copy of erlview.beam and
   couch_query_servers.beam to CDB ebin

I currently manually copy {erlview, couch_query_servers}.beam to 
/usr/local/lib/couchdb/erlang/lib/couch-0.9.0a740870-incubating/ebin/
                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                  whichever version being used


3) Reconsider the interface for writing map funs.  I am not at all sure
   I like the basic premise of how I'm currently doing it.


4) Write reduce fun(s).

5) Need to know which funs (in ets table) are in which design docs and which
   db so I only run the ones in specific design doc to which a new fun is
   being added (and for current db).  

   So, now, need to determine, when couch_query_servers calls add_fun ...
   * which design doc a fun is in
   * which db is being used 


   One storage scheme, a single ets table (as now) though with these contents
   -record(fun, {
		 ts="the_time_stamp_see_add_fun" , % keeps add_fun sequence 
                 fcrypt="sha_sum_of_tokenized_map_fun" ,
   		 db="name_of_db" , 
   		 design_doc="name_of_design_doc" ,
		 fun_name="name_of_map_fun" ,
		 fun="map_fun_in_binary" } ).

   Then, when couch_query_server calls add_fun, it passes the 
   db/design_doc/fun_name and function source to view server.
   Or, I derive that information somehow.  Then,

   * parse/eval new fun
   * add to ets table if it doesn't already exist 
     (i.e. if db/design_doc/fcrypt exist don't add to table again)
   * run all funs for that db/design_doc (per CDB spec)


6 DONE, I put examples in the html docs.
6) Write end-user docs on how to write map funs, and how to use the
   individual helper funs.  I have started writing inline docs in
   the code so during 'make', the html docs get made.


7) Makefile could use some improving (e.g. doc target instead of just making it)

8) Maybe modify couch_query_servers.erl so that map_docs/2 sent a list of
   docs rather than a single doc.  That way, handle_call( {map_doc ... )
   in erlview could run parallel funs.  

---


KNOWN BUGS:


1) If your map funs don't run properly the view name and contents can get
   mixed up.  If you go change the offending map fun so as to force a 
   runtime failure that will usually straighten things out (then correct
   the map fun).  Otherwise you may need to start/stop CouchDB.  Or send
   a reset (e.g. curl  -X POST --header "Content-Type: application/erlang" \
                 http://your.server:5984/daptest/_slow_view/reset)

2) Still getting the problem of  'view name'/contents mixed up.  Sometimes
   adding only two map funs (I'm using Futon) will cause the name and 
   contents to be reversed.  Though sometimes I can get three or four
   map funs entered and they'll be ok.  Or maybe a couple will be reversed.

   The above is in reference, of course, to multiple map funs in a single
   design document.

   Related to 5 in TODO above.

3) Helper funs have not been thoroughly tested.  They seem to work correctly
   for each goal, just not stringently tested against known output.  I 
   have run javascript map funs for same outputs and the output document
   counts have been same (and spot checking looked correct as well).


---


NOTES:

1) Remember, erlview is "AS IS, NO WARRANTY".  See the licensing in 
   src/erlview.erl or doc/erlview.html

   Hopefully, by the time you read this, I'll have it up on
   http://github.com so you can get it and fix or add whatever
   you want.

2) When running eunit:test(erlview, [verbose]), all 9 tests run
   successfully.  Don't let the SASL "=ERROR REPORT= ..." throw you.
   They are proper behaviour to the correct crash of certain funs.


3) In order for erlang to show up as a view language choice (e.g. in Futon),
   the following gets added to .../local.ini

[query_servers]
...
erlang = /dev/null

   The /dev/null used to cause an error from CDB (apparently because nothing
   returned a pid and something in couch dinna like that); I am now
   using CDB ver 0.9.0a740870-incubating and the /dev/null works fine
   with no error messages or apparently problems.


3)To start the erlang view server (also in local.ini) ...

[daemons]
erlview = {erlview, start_link, []}



4) CouchDB code changes are only in module couch_query_servers.erl
   Using a traditional view server, Pid would be returned from whatever
   runs on the query_server line (e.g. javascript = ...).  However, as
   you see from the modified get_os_process/1 code below,
   Pid = erlang:whereis(erlview) ,
   where erlview is the registered name of the Erlang view server.

couch_query_servers.erl changes
---
% MODIFY get_os_process/1
get_os_process(Lang) ->
     case Lang 
 	of <<"erlang">> -> erlang:whereis(erlview) ;
 	    _           ->
	     gen_server:call(couch_query_servers, {get_proc, Lang})
 	   end
.


% ADD BEFORE map_docs/2
% Pid comes from start_doc_map/2 (see call in couch_view_updater)
map_docs({<<"erlang">>, Pid}, Docs) ->
    Results = lists:map( fun( Doc ) ->
		       couch_os_process:prompt(Pid, [<<"map_doc">>, Doc])
	       end,
	       Docs) ,
    {ok, Results}
;



5) Edit src/Emakefile for the path to your couch_db.hrl file.


%% end
Something went wrong with that request. Please try again.