Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 332 lines (258 sloc) 11.516 kb
5037386 @klacke ""
authored
1 <erl>
6b26557 @vinoski improved embedded support
vinoski authored
2 out(A) ->
20ece13 @klacke more css hackery
authored
3 {ssi, "TAB.inc", "%%",[{"embed", "choosen"}]}.
5037386 @klacke ""
authored
4 </erl>
5
6
bea8261 @klacke added log_wrap_size, configurable wrap size for all logs, fixed a bug in...
authored
7 <div id="entry">
8
9
6b26557 @vinoski improved embedded support
vinoski authored
10 <h1>Running yaws embedded in another application</h1>
e35a591 @klacke more w3c compliance
authored
11 <p>
6b26557 @vinoski improved embedded support
vinoski authored
12 Yaws is ideal for embedding within another larger erlang application.
13 Many typical erlang applications are control applications in need of a
14 webgui specific to the actual application.
e35a591 @klacke more w3c compliance
authored
15 </p>
16
17 <p>In order to run Yaws inside another application, we need to
18 perform the following steps.
19 </p>
20
21 <ol>
6b26557 @vinoski improved embedded support
vinoski authored
22 <li> <p>Either integrate Yaws into the build system of the larger
23 application, or specifically provide the <code>ebin</code> path to Yaws
24 for the larger application. </p>
e35a591 @klacke more w3c compliance
authored
25 </li>
26
6b26557 @vinoski improved embedded support
vinoski authored
27 <li><p> Provide the application environment <code>{embedded,
28 true}</code> to Yaws.</p>
e35a591 @klacke more w3c compliance
authored
29 </li>
30 </ol>
31
6b26557 @vinoski improved embedded support
vinoski authored
32 <p>Since the containing application typically has its configuration data
33 fed from internal databases or other sources, it's usually not feasible
34 to let Yaws read its configuration data from
35 <code>/etc/yaws/yaws.conf</code> when it's running in embedded mode.</p>
36
37 <p>To solve this, when Yaws is started in embedded mode, it doesn't read
38 its configuration from <code>/etc/yaws/yaws.conf</code>, but rather it
39 expects the larger application to feed its configuration through the
40 function call <code>yaws_api:setconf(GC, Groups)</code>. The two
41 arguments to this function are:</p>
42 <ul>
43 <li><p><code>GC</code>, which is a <code>#gconf{}</code> record</p></li>
44 <li><p><code>Groups</code>, which is a list of lists of <code>#sconf</code>
45 records</p></li>
46 </ul>
47
48 <p>The details of these records are unimportant, and we'll talk more
49 about the <code>yaws_api:setconf</code> function later. First, let's
50 discuss two ways applications can start Yaws in embedded mode.</p>
51
52 <h2>Starting under your own supervisor</h2>
53
54 <p>When not embedded, Yaws starts and runs as a regular application, but
55 typically an application embedding Yaws wants to control it under its own
56 supervisor(s). This means that an embedding application requires access
57 to the Yaws supervisor child specifications. The exact list of Yaws child
58 specifications depends on how the application intends to configure
59 Yaws.</p>
60
61 <p>The <code>yaws_api:embedded_start_conf/1,2,3,4</code> functions return
62 the information an application needs to configure Yaws and start it under
63 application supervisors. There are four variants of this function:</p>
e35a591 @klacke more w3c compliance
authored
64
65 <ol>
5037386 @klacke ""
authored
66
6b26557 @vinoski improved embedded support
vinoski authored
67 <li><p><code>yaws_api:embedded_start_conf/1</code> takes a single
68 argument, which is the document root path for the web server. This
69 variant uses default values for the <code>#gconf{}</code> and
70 <code>#sconf{}</code> records.</p></li>
71
72 <li><p><code>yaws_api:embedded_start_conf/2</code> takes a document
73 root, same as the first variant above, and also a server configuration
74 list. Such a list is either a list of properties for a single web
75 server, or a list of property lists for multiple servers. We'll explain
76 more about server configuration lists later, but for now note that
77 they're used to create suitable <code>#sconf{}</code> record
78 values. This variant uses a default value of the <code>#gconf{}</code>
79 record.</p></li>
80
81 <li><p><code>yaws_api:embedded_start_conf/3</code> takes a document
82 root and a server configuration list, same as the second variant above,
83 and also a global configuration list. Such a list is a property list
84 that provides global configuration settings for the embedded Yaws
85 instance, and is used to create a suitable <code>#gconf{}</code> record
86 value. We'll explain more about global configuration lists
87 later.</p></li>
88
89 <li><p><code>yaws_api:embedded_start_conf/4</code>, the final variant,
90 takes the same 3 arguments as the previous variant and also takes a
91 string to identify the embedded Yaws instance.</p>
e35a591 @klacke more w3c compliance
authored
92 </ol>
5037386 @klacke ""
authored
93
6b26557 @vinoski improved embedded support
vinoski authored
94 <p>The values returned from these functions are described later.</p>
95
96 <h3>Global configuration list</h3>
97
98 <p>A global configuration list is a property list that provides global
99 configuration settings for an embedded Yaws instance. Each property is a
100 tuple consisting of property name and value. Allowed property names are
101 those of the field names of the <code>#gconf{}</code> record type; see
102 <code>yaws.hrl</code> for more details. An example global configuration
103 list is shown below:</p>
104
105 <div class="box">
106 <pre>
107 [{logdir, "/var/log/my_server"},
108 {ebin_dir, ["/example1/ebin", "/example2/ebin"]},
109 {id, "my_server"}].
110 </pre>
111 </div>
112 <br/>
113
114 <h3>Server configuration list</h3>
115
116 <p>A server configuration list is a property list that provides
117 configuration settings for a given web server instance. Because Yaws
118 supports multiple servers simultaneously listening for requests, it's
119 possible to supply a list of server configuration lists so that multiple
120 servers can be configured in a single <code>yaws_api:setconf</code>
121 function call. Each element in a server configuration list is a tuple
122 consisting of property name and value. Allowed property names are those
123 of the field names of the <code>#sconf{}</code> record type; see
124 <code>yaws.hrl</code> for more details. An example server configuration
125 list is shown below:</p>
126
127 <div class="box">
128 <pre>
129 [{docroot, "/var/yaws/www"},
130 {port, 8080},
131 {listen, {127,0,0,1}},
132 {appmods, [{"/", my_appmod}]}].
133 </pre>
134 </div>
135 <br/>
136
137 <h3>Using embedded_start_conf</h3>
138
139 <p>The <code>yaws_api:embedded_start_conf/1,2,3,4</code> functions return
140 <code>{ok, SCList, GC, ChildSpecs}</code>. The latter three elements of
141 this tuple are described below.</p>
142
143 <ul>
144
145 <li><p><code>SCList</code> is a list of <code>#sconf{}</code> records
146 created using the values from the passed-in server configuration
147 lists</p></li>
148
149 <li><p><code>GC</code> is a <code>#gconf{}</code> record created using
150 the values from the passed-in global configuration list</p></li>
151
152 <li><p><code>ChildSpecs</code> is a list of supervisor child
153 specifications for the components of Yaws the application wants to
154 start</p></li>
155
156 </ul>
157
158 <p>Below is an example of using the
159 <code>yaws_api:embedded_start_conf/1,2,3,4</code> functions. It follows
160 the steps of obtaining the embedded configuration and child
161 specifications, starting the Yaws children under its own supervisor, and
162 then setting the Yaws configuration.</p>
163
164 <div class="box">
165 <pre>
166 Id = "my_server",
167 GconfList = [{logdir, "/var/log/my_server"},
168 {ebin_dir, ["/example1/ebin", "/example2/ebin"]},
169 {id, Id}],
170 Docroot = "/var/yaws/www",
171 SconfList = [{docroot, Docroot},
172 {port, 8080},
173 {listen, {127,0,0,1}},
174 {appmods, [{"/", my_appmod}]}],
175 {ok, SCList, GC, ChildSpecs} =
176 yaws_api:embedded_start_conf(Docroot, SconfList, GconfList, Id),
177
178 %% assume our supervisor is registered as my_sup
179 [supervisor:start_child(my_sup, Ch) || Ch <- ChildSpecs],
180
181 %% now configure Yaws
182 yaws_api:setconf(GC, SCList),
183 </pre>
184 </div>
185
186 <h2>Starting yaws as an embedded application</h2>
187
188 <p>The four functions <code>yaws:start_embedded/1,2,3,4</code> start Yaws
189 in embedded mode using <code>application:start</code>. This approach
190 differs from the one above in that the embedding application need not
191 start any Yaws components under its own supervisors, nor does it need to
192 explicitly call <code>yaws:setconf</code> to set the Yaws
193 configuration. This approach is slightly simpler but also gives the
194 embedding application less control over Yaws.</p>
195
196 <p>The arguments for these four functions are identical to those for the
197 <code>yaws_api:embedded_start_conf/1,2,3,4</code> functions described
198 earlier.</p>
199
200 <p>See the example below:</p>
5037386 @klacke ""
authored
201
a3f0f90 Updated to reflect the yaws:start_embedded/N functions.
Tobbe Tornquist authored
202 <div class="box">
203 <pre>
204 %%
707d272 Reworked the start_embedded functions into three functions.
Tobbe Tornquist authored
205 %% Check with inet:i(). that you are listening to port 8000!
a3f0f90 Updated to reflect the yaws:start_embedded/N functions.
Tobbe Tornquist authored
206 %%
207 1> yaws:start_embedded("/home/tobbe/docroot").
208
209 %%
707d272 Reworked the start_embedded functions into three functions.
Tobbe Tornquist authored
210 %% Alternative ways
a3f0f90 Updated to reflect the yaws:start_embedded/N functions.
Tobbe Tornquist authored
211 %%
6b26557 @vinoski improved embedded support
vinoski authored
212 1> yaws:start_embedded("/home/tobbe/docroot",
213 [{servername, "sej"}, {listen, {0,0,0,0}}]).
707d272 Reworked the start_embedded functions into three functions.
Tobbe Tornquist authored
214
6b26557 @vinoski improved embedded support
vinoski authored
215 1> yaws:start_embedded("/home/tobbe/docroot",
d9342f8 server-specific logger_mod and auth_mod (capflam)
Christopher Faulet authored
216 [{servername, "sej"}, {auth_log, false},
217 {listen, {0,0,0,0}}],
218 [{copy_errlog, false}]).
707d272 Reworked the start_embedded functions into three functions.
Tobbe Tornquist authored
219
a3f0f90 Updated to reflect the yaws:start_embedded/N functions.
Tobbe Tornquist authored
220 </pre>
221 </div>
222
6b26557 @vinoski improved embedded support
vinoski authored
223 <p>If you need more control on how to setup Yaws in embedded mode, use
224 the <code>yaws_api:embedded_start_conf</code> functions instead.
a3f0f90 Updated to reflect the yaws:start_embedded/N functions.
Tobbe Tornquist authored
225
226
6b26557 @vinoski improved embedded support
vinoski authored
227 <h2>A very small example</h2>
5037386 @klacke ""
authored
228
6b26557 @vinoski improved embedded support
vinoski authored
229 <p>We provide a minimal example that embeds Yaws in a small Erlang
230 function.</p>
5037386 @klacke ""
authored
231
6b26557 @vinoski improved embedded support
vinoski authored
232 <p>The <code>ybed</code> module is very small and is named <a
233 href="code.yaws?file=/ybed.erl"><code>ybed.erl</code></a>. It has an
234 accompanying simple supervisor named <a
235 href="code.yaws?file=/ybed_sup.erl"><code>ybed_sup.erl</code></a>.</p>
236
237 <p>If you compile both modules, you can run them as shown below:</p>
5037386 @klacke ""
authored
238
f875c2b @klacke added <verbatim> tag for .yaws files, It works as the pre (or the code) ...
authored
239 <div class="box">
240 <verbatim>
6b26557 @vinoski improved embedded support
vinoski authored
241 1> {ok, Sup} = ybed_sup:start_link().
242 {ok,<0.40.0>}
7811247 @vinoski whitespace cleanup
vinoski authored
243 2>
6b26557 @vinoski improved embedded support
vinoski authored
244 =INFO REPORT==== 12-Apr-2010::02:42:09 ===
245 Yaws: Listening to 0.0.0.0:8888 for <1> virtual servers:
246 - http://foobar:8888 under /tmp
247
248 2>
249 </verbatim>
f875c2b @klacke added <verbatim> tag for .yaws files, It works as the pre (or the code) ...
authored
250 </div>
5037386 @klacke ""
authored
251
6b26557 @vinoski improved embedded support
vinoski authored
252 <p>The actual web server runs inside the larger application. The
253 configuration of the web server was programmatically fed into Yaws from the
254 surrounding application, in this case, the <a
255 href="code.yaws?file=/ybed.erl"><code>ybed.erl</code></a> module. Note also
256 how the Yaws children are started under the same <a
257 href="code.yaws?file=/ybed_sup.erl"><code>ybed_sup.erl</code></a>
258 supervisor as the code in the <code>ybed</code> module itself.
5037386 @klacke ""
authored
259
260 <h2>The opaque field in the sconf structure </h2>
261
6b26557 @vinoski improved embedded support
vinoski authored
262 <p>The <code>#sconf{}</code> record, which is constructed by the program
263 that starts and configures Yaws, contains a field,
264 <code>SC#sconf.opaque</code>.</p>
5037386 @klacke ""
authored
265
6b26557 @vinoski improved embedded support
vinoski authored
266 <p>This field is passed into the <code>#arg{}</code> record, so that any
267 application specific configuration data which is needed by the
268 <code>.yaws</code> pages that make up the web GUI application, is easily
269 available there.</p>
e35a591 @klacke more w3c compliance
authored
270
5037386 @klacke ""
authored
271
6b26557 @vinoski improved embedded support
vinoski authored
272 <p>In essence, if we construct the <code>#sconf</code> as</p>
f875c2b @klacke added <verbatim> tag for .yaws files, It works as the pre (or the code) ...
authored
273
274 <div class="box">
6b26557 @vinoski improved embedded support
vinoski authored
275 <verbatim>
5037386 @klacke ""
authored
276 SC#sconf{opaque = {mystruct, foobar},
277 .....
6b26557 @vinoski improved embedded support
vinoski authored
278 </verbatim>
f875c2b @klacke added <verbatim> tag for .yaws files, It works as the pre (or the code) ...
authored
279 </div>
280
5037386 @klacke ""
authored
281
6b26557 @vinoski improved embedded support
vinoski authored
282 <p>A <code>.yaws</code> web page can then do:</p>
f875c2b @klacke added <verbatim> tag for .yaws files, It works as the pre (or the code) ...
authored
283
284 <div class="box">
6b26557 @vinoski improved embedded support
vinoski authored
285 <verbatim>
5037386 @klacke ""
authored
286 out(Arg) ->
287 MyStruct = Arg#arg.opaque
288 .....
289
6b26557 @vinoski improved embedded support
vinoski authored
290 </verbatim>
f875c2b @klacke added <verbatim> tag for .yaws files, It works as the pre (or the code) ...
authored
291 </div>
5037386 @klacke ""
authored
292
6b26557 @vinoski improved embedded support
vinoski authored
293 <p>thus passing data from the surrounding applications configuration
294 routines down to each <code>.yaws</code> web page.</p>
5037386 @klacke ""
authored
295
6b26557 @vinoski improved embedded support
vinoski authored
296 <p>Another important fact to consider when choosing whether to run your
297 Yaws application as an embedded yaws app or not is that all the Yaws
298 control functions are disabled when we use Yaws as an embedded web server,
299 including capabilities such as <code>yaws --ls</code> and <code>yaws
300 --stop</code>. Embedding thusassumes that you already have support for this
301 type of functionality in your application.</p>
302
303 <p>Finally, an interesting appmod definition that may apply to many
304 embedded yaws installations is the <code>/</code> appmod with a set of
305 exclude dirs. Here is an example server configuration list:</p>
5037386 @klacke ""
authored
306
b7656de @klacke Added support for excluding dirs from an appmod. This is useful for / ap...
authored
307 <div class="box">
6b26557 @vinoski improved embedded support
vinoski authored
308 <verbatim>
309 [...
310 {appmods, [{"/", myapp, [["js"], ["top", "static"], ["icons"]]}]},
311 ...].
312 </verbatim>
313 </div>
314
315 <p>or in <code>#sconf{}</code> record terms:</p>
316
317 <div class="box">
318 <verbatim>
b7656de @klacke Added support for excluding dirs from an appmod. This is useful for / ap...
authored
319 SC#sconf{.....
320 appmods = {"/", myapp, [["js"], ["top", "static"], ["icons"]]},
321 ....
6b26557 @vinoski improved embedded support
vinoski authored
322 </verbatim>
b7656de @klacke Added support for excluding dirs from an appmod. This is useful for / ap...
authored
323 </div>
324
5037386 @klacke ""
authored
325
bea8261 @klacke added log_wrap_size, configurable wrap size for all logs, fixed a bug in...
authored
326 </div>
327
328
5037386 @klacke ""
authored
329 <erl>
bea8261 @klacke added log_wrap_size, configurable wrap size for all logs, fixed a bug in...
authored
330 out(A) -> {ssi, "END2",[],[]}.
5037386 @klacke ""
authored
331 </erl>
Something went wrong with that request. Please try again.