Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

added support/docs for embedded mode

git-svn-id: https://erlyaws.svn.sourceforge.net/svnroot/erlyaws/trunk/yaws@179 9fbdc01b-0d2c-0410-bfb7-fb27d70d8b52
  • Loading branch information...
commit 50a7ab21ca0fa57a77d6ff22774933b719e26d48 1 parent d02a5cb
@klacke authored
View
7 applications/webmail/test.erl
@@ -31,6 +31,13 @@ s() ->
{passwd, "ulMer9"}]),
S.
+s2() ->
+ {ok, S} = pop3lib_cli:connect([{user, "klacke"},
+ {addr, {213,67,177,217}},
+ {passwd, "ulMer9"}]),
+ S.
+
+
pop2() ->
webmail:get_mails(s()).
View
12 man/yaws_api.5
@@ -263,6 +263,18 @@ cookie.
\fBreplace_cookie_session(Session, User)\fR
+.TP
+\fBsetconf(Gconf, Groups)\fR
+This function is intended for embedded mode in yaws. It makes it possible
+to load a yaws configuration from another data source than /etc/yaws.conf, such
+as a database.
+If yaws is started with the environment \fI{embedded, true}\fR, yaws will
+start with an empty default configuration, and wait for some other
+program to execute a \fIsetconf/2\fR
+The Gconf is a \fI#gconf{}\fR record and the Group variable is
+a list of lists of \fI#sconf{}\fR records. Each sublist must
+contain \fI#sconf{}\fR records with the same IP/Port listen address.
+
.SH RETURN VALUES from out/1
.PP
View
18 src/yaws.erl
@@ -21,13 +21,25 @@ start() ->
stop() ->
application:stop(yaws).
-hup() ->
+hup(Sock) ->
spawn(fun() ->
group_leader(whereis(user), self()),
- stop(),
- start()
+ dohup(Sock)
end).
+dohup(Sock) ->
+ io:format("in dohup~n", []),
+ {Debug, Trace, Conf, RunMod, Embed} = yaws_server:get_app_args(),
+ Res = (catch case yaws_config:load(Conf, Trace, Debug) of
+ {ok, Gconf, Sconfs} ->
+ io:format("Call setconf ~n", []),
+ gen_server:call(yaws_server, {setconf, Gconf, Sconfs});
+ Err ->
+ Err
+ end),
+ gen_tcp:send(Sock, io_lib:format("hupped: ~p~n", [Res])),
+ gen_tcp:close(Sock).
+
%% use from cli only
restart() ->
View
8 src/yaws_api.erl
@@ -632,4 +632,10 @@ replace_cookie_session(Session, User) ->
-
+
+%% to be used in embedded mode, make it possible
+%% to pass a config to yaws from another data source
+%% than /etc/yaws.conf, for example from a database
+
+setconf(GC, Groups) ->
+ gen_server:call(yaws_server, {setconf, GC, Groups}).
View
3  src/yaws_config.erl
@@ -13,6 +13,9 @@
-compile(export_all).
%%-export([Function/Arity, ...]).
+-export([load/3,
+ make_default_gconf/1]).
+
%% where to look for yaws.conf
paths() ->
View
19 src/yaws_ctl.erl
@@ -56,19 +56,22 @@ aloop(L) ->
handle_a(A) ->
case gen_tcp:recv(A, 0) of
{ok, Data} ->
+ io:format("got ~p~n", [Data]),
case binary_to_term(Data) of
hup ->
- yaws:hup(),
- gen_tcp:send(A, "hupped\n");
+ Res = yaws:dohup(A),
+ Res;
stop ->
gen_tcp:send(A, "stopping\n"),
init:stop();
status ->
- a_status(A);
- _Other ->
- ignore
- end,
- gen_tcp:close(A);
+ a_status(A),
+ gen_tcp:close(A);
+ Other ->
+ gen_tcp:send(A, io_lib:format("Other: ~p~n", [Other])),
+ gen_tcp:close(A)
+
+ end;
_Err ->
ignore
end.
@@ -122,7 +125,7 @@ actl(Term, Uid) ->
{ok, Bin} ->
io:format("~s~n", [binary_to_list(Bin)]);
Err ->
- io:format("yaws server for uid ~s not responding ~n",[Uid])
+ io:format("yaws server for uid ~s not responding: ~p ~n",[Uid, Err])
end,
gen_tcp:close(Fd),
Res;
View
107 src/yaws_server.erl
@@ -55,6 +55,8 @@ start_link() ->
status() ->
gen_server:call(?MODULE, status).
+
+
stats() ->
{S, Time} = status(),
{_GC, Srvs, _} = S,
@@ -114,7 +116,13 @@ get_app_args() ->
{ok,Mod} ->
{ok,Mod}
end,
- {Debug, Trace, Conf, RunMod}.
+ Embed = case application:get_env(yaws, embedded) of
+ undefined ->
+ false;
+ Val ->
+ Val
+ end,
+ {Debug, Trace, Conf, RunMod, Embed}.
find_c([{conf, [File]} |_]) ->
{file, File};
@@ -144,36 +152,40 @@ l2a(A) when atom(A) -> A.
%%----------------------------------------------------------------------
init([]) ->
put(start_time, calendar:local_time()), %% for uptime
- {Debug, Trace, Conf, RunMod} = get_app_args(),
-
- case yaws_config:load(Conf, Trace, Debug) of
- {ok, Gconf, Sconfs} ->
- erase(logdir),
- ?Debug("Conf = ~p~n", [?format_record(Gconf, gconf)]),
- yaws_log:setdir(Gconf#gconf.logdir, Sconfs),
- case Gconf#gconf.trace of
- {true, What} ->
- yaws_log:open_trace(What);
- _ ->
- ok
- end,
- init2(Gconf, Sconfs, RunMod);
- {error, E} ->
- case erase(logdir) of
- undefined ->
- error_logger:format("Bad conf: ~p~n", [E]),
- init:stop(),
- {stop, E};
- Dir ->
- yaws_log:setdir(Dir, []),
- yaws_log:sync_errlog("bad conf: ~s~n",[E]),
- init:stop(),
- {stop, E}
- end
+ {Debug, Trace, Conf, RunMod, Embed} = get_app_args(),
+ case Embed of
+ false ->
+ case yaws_config:load(Conf, Trace, Debug) of
+ {ok, Gconf, Sconfs} ->
+ erase(logdir),
+ ?Debug("Conf = ~p~n", [?format_record(Gconf, gconf)]),
+ yaws_log:setdir(Gconf#gconf.logdir, Sconfs),
+ case Gconf#gconf.trace of
+ {true, What} ->
+ yaws_log:open_trace(What);
+ _ ->
+ ok
+ end,
+ init2(Gconf, Sconfs, RunMod, true);
+ {error, E} ->
+ case erase(logdir) of
+ undefined ->
+ error_logger:format("Bad conf: ~p~n", [E]),
+ init:stop(),
+ {stop, E};
+ Dir ->
+ yaws_log:setdir(Dir, []),
+ yaws_log:sync_errlog("bad conf: ~s~n",[E]),
+ init:stop(),
+ {stop, E}
+ end
+ end;
+ true ->
+ init2(yaws_config:make_default_gconf(Debug), [], undef, true)
end.
-init2(Gconf, Sconfs, RunMod) ->
+init2(Gconf, Sconfs, RunMod, FirstTime) ->
lists:foreach(
fun(D) ->
code:add_pathz(D)
@@ -203,7 +215,13 @@ init2(Gconf, Sconfs, RunMod) ->
io:format("L=~p~n", [L]),
if
length(L) == length(L2) ->
- proc_lib:spawn_link(yaws_ctl, start, [self(), Gconf#gconf.uid]),
+ if
+ FirstTime == true ->
+ proc_lib:spawn_link(yaws_ctl, start,
+ [self(), Gconf#gconf.uid]);
+ true ->
+ ok
+ end,
{ok, {Gconf, L2, 0}};
true ->
{stop, "failed to start server "}
@@ -226,8 +244,27 @@ handle_call(status, _From, State) ->
handle_call(pids, _From, State) -> %% for gprof
L = lists:map(fun(X) ->element(1, X) end, element(2, State)),
{reply, [self() | L], State};
+
handle_call(mnum, _From, {GC, Group, Mnum}) ->
- {reply, Mnum+1, {GC, Group, Mnum+1}}.
+ {reply, Mnum+1, {GC, Group, Mnum+1}};
+
+handle_call({setconf, GC, Groups}, From, State) ->
+ %% First off, terminate all currently running processes
+ Curr = lists:map(fun(X) ->element(1, X) end, element(2, State)),
+ lists:foreach(fun(Pid) ->
+ Pid ! {self(), stop},
+ receive
+ {Pid, ok} ->
+ ok
+ end
+ end, Curr),
+ case init2(GC, Groups, undef, false) of
+ {ok, State2} ->
+ {reply, ok, State2};
+ Err ->
+ {reply, Err, {GC, [], 0}}
+ end.
+
@@ -360,11 +397,18 @@ gserv(GS, Ready, Rnum) ->
gserv(GS2, [From | Ready], Rnum+1)
end;
{'EXIT', _Pid, _} ->
- gserv(GS, Ready, Rnum)
+ gserv(GS, Ready, Rnum);
+ {From, stop} ->
+ unlink(From),
+ {links, Ls} = process_info(self(), links),
+ lists:foreach(fun(X) -> unlink(X), exit(X, kill) end, Ls),
+ From ! {self(), ok},
+ exit(normal)
end.
+
opts(SC) ->
[binary,
{ip, SC#sconf.listen},
@@ -441,7 +485,6 @@ acceptor(GS) ->
proc_lib:spawn_link(yaws_server, acceptor0, [GS, self()]).
acceptor0(GS, Top) ->
?TC([{record, GS, gs}]),
- %%L = GS#gs.l,
X = do_accept(GS),
Top ! {self(), next},
case X of
View
10 www/configuration.yaws
@@ -72,6 +72,7 @@ yaws is then started as:
</pre>
+
<H2>Configuring Yaws</h2>
<p>
@@ -91,7 +92,14 @@ The yaws configuration is described in
<h3>Embedded mode</h3>
<p>
-Not documented.
+It is possible to run yaws in embedded mode where yaws is part of a
+larger application. When running yaws in embedded mode, it is often not
+possible to let yaws read its configuration data from /etc/yaws.conf.
+<p>The function <tt>yaws_api:setconf(Gconf, Groups)</tt> can be used by an
+other erlang process to explicitly set a yaws configuration at runtime.
+
+<p>Yaws must be started with the environment <tt>{embedded, true}\<tt>
+
<erl>
Please sign in to comment.
Something went wrong with that request. Please try again.