Erlang/OTP Forums

Author Message

<  Yaws mailing list  ~  yapps without mnesia?

Guest
Posted: Fri Apr 04, 2008 8:02 pm Reply with quote
Guest
Currently, yapps require mnesia by default for registration purpose.
For some systems, though, this might be considered overkill, and it
looks like the yapp code already allows for replacing the mnesia
implementation with something else via the yapp_registry_impl
application config parameter.

Has anyone implemented such a replacement that uses a mechanism other
than mnesia? Any advice for writing such a replacement module?

thanks,
--steve

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
Erlyaws-list mailing list
Erlyaws-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/erlyaws-list
Post recived from mailinglist
Guest
Posted: Sun Apr 06, 2008 9:18 pm Reply with quote
Guest
Friday 04 April 2008 21:54:29 Steve Vinoski wrote:
> Currently, yapps require mnesia by default for registration purpose.
> For some systems, though, this might be considered overkill, and it
> looks like the yapp code already allows for replacing the mnesia
> implementation with something else via the yapp_registry_impl
> application config parameter.
>
> Has anyone implemented such a replacement that uses a mechanism other
> than mnesia? Any advice for writing such a replacement module?
>
> thanks,
> --steve

Hi Steve,
it is fairly straightforward to replace the mnesia implementation with
another one.
The yapp_registry_impl environment entry in the yapp.app file should
point to a module that implements the gen_server behaviour with three
clauses in the handle_call/3 function:

handle_call({yapp_registry, list}, _From, State)
handle_call({yapp_registry, register,{SrvId,KeyValue}}, _From, State)
handle_call({yapp_registry, unregister,{SrvId,Key}}, _From, State)

as given by the "contract" in the yapp_registry.erl module.

It should also take a Name parameter for its local name in the start_link/1
function.

If the above makes no sense Smile, I have included such a module that writes
and reads the registry from an erlang consult file instead, which could give
you a hint on how to implement your own. This module may take another
(callback) module which only needs to implement two functions rget/0 and
rput/1 to get the registry and to put the registry. May simplify things a bit,
but introduces yet another level indirection.

Best Regards
Mikael

%%--------------------------------------------------------------------
%% implements yapp_registry
-module(yapp_my_registry_server).
-behaviour(gen_server).

%% API
-export([start_link/1, start_link/2, rput/1, rget/0]).

%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).

%% registry module should export rput/1 and rget/0
-record(state, {registry_module}).

%% API
%%--------------------------------------------------------------------
%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
%% Description: Starts the server
%%--------------------------------------------------------------------
start_link(Name) ->
start_link(Name, ?MODULE). %% Use own module as default registry_module
start_link(Name, RegistryModule) ->
gen_server:start_link({local, Name}, ?MODULE, [RegistryModule], []).

-define(CSL_FILE,"my_registry_file.csl").

%% Registry is [{"serverid1",[{"/myurl1", myapp1},..]}, ..]
%% Returns registry
rget() ->
case file:consult(?CSL_FILE) of
{ok, Value} ->
Value;
_ -> %% Assume that no file exists, make an empty one
rput([]), %% Will exit if file can't be created
[]
end.

%% Puts Registry
rput(Registry) ->
unconsult(?CSL_FILE,Registry).

unconsult(File, List) ->
{ok,F} = file:open(File, write),
[ io:format(F, "~p.~n",[X]) || X <- List ],
file:close(F).

%%=====================================
%% gen_server callbacks
%%=====================================

%%--------------------------------------------------------------------
%% Function: init(Args) -> {ok, State} |
%% {ok, State, Timeout} |
%% ignore |
%% {stop, Reason}
%% Description: Initiates the server
%%--------------------------------------------------------------------
init([Module]) ->
{ok, #state{registry_module=Module}}.

%%--------------------------------------------------------------------
%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
%% {reply, Reply, State, Timeout} |
%% {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, Reply, State} |
%% {stop, Reason, State}
%% Description: Handling call messages
%%--------------------------------------------------------------------

handle_call({yapp_registry, list}, _From, #state{registry_module=M}=State) ->
Reply = M:rget(),
{reply, Reply, State};
handle_call({yapp_registry, register,{SrvId,KeyValue}}, _From, #state{registry_module=M}=State) ->
NewRegistry = register_yapp(SrvId,KeyValue,M:rget()),
Reply = M:rput(NewRegistry),
{reply, Reply, State};
handle_call({yapp_registry, unregister,{SrvId,Key}}, _From, #state{registry_module=M}=State) ->
NewRegistry = unregister_yapp(SrvId,Key, M:rget()),
Reply = M:rput(NewRegistry),
{reply, Reply, State};
handle_call({set_registry_module, Module}, _From, State) ->
{reply, ok, State#state{registry_module=Module}};
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State}.

%%--------------------------------------------------------------------
%% Function: handle_cast(Msg, State) -> {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State}
%% Description: Handling cast messages
%%--------------------------------------------------------------------
handle_cast(_Msg, State) ->
{noreply, State}.

%%--------------------------------------------------------------------
%% Function: handle_info(Info, State) -> {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State}
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
handle_info(_Info, State) ->
{noreply, State}.

%%--------------------------------------------------------------------
%% Function: terminate(Reason, State) -> void()
%% Description: This function is called by a gen_server when it is about to
%% terminate. It should be the opposite of Module:init/1 and do any necessary
%% cleaning up. When it returns, the gen_server terminates with Reason.
%% The return value is ignored.
%%--------------------------------------------------------------------
terminate(_Reason, _State) ->
ok.

%%--------------------------------------------------------------------
%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
%% Description: Convert process state when code is changed
%%--------------------------------------------------------------------
code_change(_OldVsn, State, _Extra) ->
{ok, State}.

%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
%% The yapp registry contains a list of {yapp_server_id, yapps} tuples,
%% where yapps is a list of {UrlPath, AppName} tuples
%% UrlPath = string()
%% AppName = atom()

%% @spec register_yapp(SrvId::string(), {YappUrl::string(), AppName::atom()}, Registry) -> NewRegistry
%% @doc Register a Yapp. Registers in the virtual server with the opaque property
%% yapp_server_id = SrvID. The YappUrl is the root path to the Yapp and the AppName is
%% the Name of the application.
register_yapp(SrvId, {YappUrl, AppName}, YR) ->
case proplists:get_value(SrvId,YR) of
undefined ->
[{SrvId,[{YappUrl,AppName}]} | YR ];
UrlApps ->
UrlApps2 = insert({YappUrl,AppName},UrlApps),
lists:keyreplace(SrvId, 1, YR, {SrvId,UrlApps2})
end.


%% @spec unregister_yapp(SrvId::string(), YappUrl::string()) -> NewRegistry
%% @doc Unregister a Yapp. Unregisters in the virtual server with yapp_server_id = SrvID.
%% The YappUrl is the root path to the Yapp.
unregister_yapp(SrvId, YappUrl, YR) ->
case proplists:get_value(SrvId,YR) of
undefined ->
YR;
UrlApps ->
case delete(YappUrl, UrlApps) of
[] ->
lists:keydelete(SrvId,1,YR);
UrlApps2 ->
lists:keyreplace(SrvId, 1, YR, {SrvId,UrlApps2})
end
end.

insert({Key,Value}, List)->
case lists:keymember(Key, 1, List) of
false ->
[{Key,Value}|List];
true ->
lists:keyreplace(Key, 1, List, {Key, Value})
end.

delete(Key, List) ->
case lists:keymember(Key, 1, List) of
false ->
List;
true ->
lists:keydelete(Key, 1, List)
end.
%%--------------------------------------------------------------------


-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Register now and save $200. Hurry, offer ends at 11:59 p.m.,
Monday, April 7! Use priority code J8TLD2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Erlyaws-list mailing list
Erlyaws-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/erlyaws-list
Post recived from mailinglist
Guest
Posted: Sun Apr 06, 2008 11:17 pm Reply with quote
Guest
On 4/6/08, Mikael Karlsson <mikael.karlsson@creado.com> wrote:
> Friday 04 April 2008 21:54:29 Steve Vinoski wrote:
> > Currently, yapps require mnesia by default for registration purpose.
> > For some systems, though, this might be considered overkill, and it
> > looks like the yapp code already allows for replacing the mnesia
> > implementation with something else via the yapp_registry_impl
> > application config parameter.
> >
> > Has anyone implemented such a replacement that uses a mechanism other
> > than mnesia? Any advice for writing such a replacement module?
>
>
> Hi Steve,
> it is fairly straightforward to replace the mnesia implementation with
> another one.
> The yapp_registry_impl environment entry in the yapp.app file should
> point to a module that implements the gen_server behaviour with three
> clauses in the handle_call/3 function:
>
> handle_call({yapp_registry, list}, _From, State)
> handle_call({yapp_registry, register,{SrvId,KeyValue}}, _From, State)
> handle_call({yapp_registry, unregister,{SrvId,Key}}, _From, State)
>
> as given by the "contract" in the yapp_registry.erl module.
>
> It should also take a Name parameter for its local name in the start_link/1
> function.

I looked through it after sending my initial email -- should have done
that before sending, but oh well Smile -- and it does indeed look
straightforward.

> If the above makes no sense Smile, I have included such a module that writes
> and reads the registry from an erlang consult file instead, which could give
> you a hint on how to implement your own. This module may take another
> (callback) module which only needs to implement two functions rget/0 and
> rput/1 to get the registry and to put the registry. May simplify things a bit,
> but introduces yet another level indirection.

Thanks! I assume, BTW, that there are really no persistence
requirements here if all the yapps are bootstrapped in the yaws.conf
file?

--steve

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Register now and save $200. Hurry, offer ends at 11:59 p.m.,
Monday, April 7! Use priority code J8TLD2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Erlyaws-list mailing list
Erlyaws-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/erlyaws-list
Post recived from mailinglist
Guest
Posted: Mon Apr 07, 2008 6:13 am Reply with quote
Guest
Monday 07 April 2008 01:16:27 Steve Vinoski wrote:
> ...
> Thanks! I assume, BTW, that there are really no persistence
> requirements here if all the yapps are bootstrapped in the yaws.conf
> file?
>
> --steve

That is a correct assumption.
Regards
Mikael


-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Register now and save $200. Hurry, offer ends at 11:59 p.m.,
Monday, April 7! Use priority code J8TLD2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Erlyaws-list mailing list
Erlyaws-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/erlyaws-list
Post recived from mailinglist

Display posts from previous:  

All times are GMT
Page 1 of 1
This forum is locked: you cannot post, reply to, or edit topics.

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You can attach files in this forum
You can download files in this forum