-
Notifications
You must be signed in to change notification settings - Fork 0
/
README.html
345 lines (266 loc) · 11.9 KB
/
README.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- src/erlang/README.html 2018-3-17 Alan U. Kennington. -->
<html lang="en"><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<title>erltest: Some Erlang/OTP experiments</title>
<style type="text/css"><!--
a:link { text-decoration:none; color:#0000FF; }
/* Note: "visited" must appear before "hover" here. I don't know why!!! */
a:visited { text-decoration:none; color:#D00000; }
a:hover { text-decoration:none; color:#009000; }
body { font-family:"Liberation Sans",arial,verdana,helvetica,sans-serif;
background-color:#f0f8ce; }
td, th { padding-left:3pt; padding-right:3pt; }
td.bookpart { padding-left:3pt; padding-right:3pt;
background-color:#f7f2c8; white-space:nowrap;
text-align:center; font-weight:bold; }
td.hyper { padding-left:3pt; padding-right:3pt; vertical-align:text-top; }
td.topic, th.topic { padding-left:3pt; padding-right:3pt;
background-color:#e7e2b8; white-space:nowrap; }
td.items, th.items { padding-left:3pt; padding-right:3pt;
background-color:#dbce92; font-size:90%; }
.equation { white-space:nowrap; }
--></style>
</head>
<body><center>
<span style="font-size:150%;font-weight:bold;"><b>erltest</b>:
Some Erlang/OTP experiments</span><br>
Alan U. Kennington<br>
<span style="font-size:90%;">(work in progress)</span><br>
</center>
<!-- ===================================================================== -->
<p>Some <a href="https://www.erlang.org/docs">Erlang</a>/OTP experiments.
<ul>
<li><b><a href="test1.erl">test1.erl</a></b>:
Some trivial exercises with Erlang functions.
<li><b><a href="proc1.erl">proc1.erl</a></b>:
Some trivial distributed Erlang processes, including a Poisson process.
</ul>
<!-- ===================================================================== -->
<p>Some <a href="http://erlang.org/doc/apps/wx/index.html">wxErlang</a>
experiments.
<ul>
<li><b><a href="wx1.erl">wx1.erl</a></b>:
A minimal wxErlang application to see how it works.
<li><b><a href="mobsim1.erl">mobsim1.erl</a></b>:
A trivial mobile object simulation using wxErlang.
<li><b><a href="mobsim2.erl">mobsim2.erl</a></b>:
Development module for simulation of a simple mobile network.
<li><b><a href="mobsim3.erl">mobsim3.erl</a></b>:
Version 3 of mobile network simulation. Added server-side display list, double
buffering, window re-painting, multiple options for node appearance, and some
trace filtering options.
</ul>
<!-- ===================================================================== -->
<p>Some <a href="http://erlang.org/doc/man/gen_server.html">gen_server</a>
experiments.
<ul>
<li><b><a href="gs1a.erl">gs1a.erl</a></b>, <b><a
href="gs1b.erl">gs1b.erl</a></b>, <b><a href="gs1c.erl">gs1c.erl</a></b>:
Modules A, B and C to dissect and investigate the gen_server concept.
<ul>
<li>The call chain is:<br>
<span class=equation>Erlang shell <==> A <==> GS-module <-->
GS-daemon <==> B <==> C.</span>
<ul>
<li>Erlang shell: <tt>erl</tt>
<li>Module A: <tt>gs1a.erl</tt>
<li>GS-module: <tt>gen_server.erl</tt>
<li>GS-daemon: <tt>proc_lib.erl</tt> [the <q>gen_server process</q>]
<li>Module B: <tt>gs1b.erl</tt> [the <q>callback module</q>]
<li>Module C: <tt>gs1c.erl</tt>
</ul>
<li>Module A converts Erlang shell commands to calls to the GS-module.<br>
Module B is the <q>callback module</q> which handles the GS-daemon's calls.<br>
Module C provides some basic low-level functions to Module B for demonstration
purposes.<br>
<li>The GS-daemon is called a <q>gen_server process</q> in the Erlang/OTP
documentation.
<li>Communication between the GS-module and GS-daemon uses inter-process
messages.<br>
The other links use plain function calls.<br>
<li>The Erlang/OTP documentation recommends putting A, B and C in a single
module.<br>
But then it is not immediately clear how the whole system works.<br>
</ul>
<!-- ===================================================================== -->
<li><b><a href="gsup1a.erl">gsup1a.erl</a></b>, <b><a
href="gsup1b.erl">gsup1b.erl</a></b>, <b><a
href="gsup1c.erl">gsup1c.erl</a></b>:
Modules SV-A, SV-B and SV-C to <a
href="http://erlang.org/doc/man/supervisor.html">supervise</a> the GS-daemon.
<ul>
<li>The supervisor's own call chain is:<br>
<span class=equation>Erlang shell <==> SV-A <==> SV-module
<--> SV-daemon <==> SV-B <==> SV-C.</span>
<ul>
<li>Erlang shell: <tt>erl</tt>
<li>Module SV-A: <tt>gsup1a.erl</tt>
<li>SV-module: <tt>supervisor.erl</tt>
<li>SV-daemon: <tt>proc_lib.erl</tt> [the supervisor gen_server process]
<li>Module SV-B: <tt>gsup1b.erl</tt> [the supervisor's <q>callback module</q>]
<li>Module SV-C: <tt>gsup1c.erl</tt> [basic common services for SV-A and SV-B]
</ul>
<!-- - - - - - - - - - - - - - - - -->
<li>The supervisor's initialization sequence is as follows for a single child
process.
<ol>
<li>User (Erlang shell) calls <tt>gsup1a:start_link/0</tt>.
<li><tt>gsup1a:start_link/0</tt> calls <tt>supervisor:start_link/3</tt> with
these parameters.
<ul>
<li>Supervisor registered name: <tt>gsup1reg</tt>
<li>Supervisor callback module: <tt>gsup1b</tt>
</ul>
<li><tt>supervisor:start_link/3</tt> spawns a gen_server, and registers it as
<tt>gsup1reg</tt>.
<li>The process <tt>gsup1reg</tt> calls <tt>gsup1b:init/1</tt>.
<li><tt>gsup1b:init/1</tt> returns a list of child processes to be
supervised.<br>
In this case, there is only one child process on the list, which has the
following specifications.
<ul>
<li>Child ID: <tt>gs1id1</tt>
<li>Child user module: <tt>gs1a</tt>
<li>Child user module entry point: <tt>start_link/1</tt>
<li>Child registered name: <tt>gs1reg1</tt>
<li>Child callback module: <tt>gs1b</tt>
</ul>
<li>The process <tt>gsup1reg</tt> calls <tt>gs1a:start_link/1</tt>.
<li>The function <tt>gs1a:start_link/1</tt> calls
<tt>gen_server:start_link/4</tt> with parameters:
<ul>
<li>Registered name: <tt>gs1reg1</tt>
<li>Callback module: <tt>gs1b</tt>
</ul>
(<tt>gs1a:start_link/1</tt> obtains the registered name from the function
argument passed by the process <tt>gsup1reg</tt>.)
<li><tt>gen_server:start_link/4</tt> spawns a gen_server process, and registers
it as <tt>gs1reg1</tt>.
<li>The process <tt>gs1reg1</tt> calls <tt>gs1b:init/1</tt>.
<li>The function <tt>gs1b:init/1</tt> returns the initial state for process
<tt>gs1reg1</tt>.<br>
(Currently <tt>gs1b:init/1</tt> ignores its single argument.)
<li>The child process <tt>gs1reg1</tt> is included in the supervisor's child
list with the ID <tt>gs1id1</tt>.
<li>Processes <tt>gsup1reg</tt> and <tt>gs1reg1</tt> both enter a loop
(<tt>gen_server:loop/7</tt>), and wait a while.
</ol>
That's a brief outline anyway!
<!-- - - - - - - - - - - - - - - - -->
<li>The supervisor's initialization sequence is as follows for <i>N</i> child
processes.
<ol>
<li>User (Erlang shell) calls <tt>gsup1a:start_link/1</tt> with parameter
<i>N</i>.
<li><tt>gsup1a:start_link/0</tt> calls <tt>supervisor:start_link/3</tt> with
these parameters.
<ul>
<li>Supervisor registered name: <tt>gsup1reg</tt>
<li>Supervisor callback module: <tt>gsup1b</tt>
<li>Number <i>N</i> of child processes to be created.
</ul>
<li><tt>supervisor:start_link/3</tt> spawns a gen_server, and registers it as
<tt>gsup1reg</tt>.
<li>The process <tt>gsup1reg</tt> calls <tt>gsup1b:init/1</tt> with parameter
<i>N</i>.
<li><tt>gsup1b:init/1</tt> returns a list of <i>N</i> child processes to be
supervised.<br>
These <i>N</i> child processes have the following specifications for <i>X</i> =
1 up to <i>N</i>.
<ul>
<li>Child ID: <tt>gs1id</tt><i>X</i>
<li>Child user module: <tt>gs1a</tt>
<li>Child user module entry point: <tt>start_link/1</tt>
<li>Child registered name: <tt>gs1reg</tt><i>X</i>
<li>Child callback module: <tt>gs1b</tt>
</ul>
<li>The process <tt>gsup1reg</tt> calls <tt>gs1a:start_link/1</tt> <i>N</i>
times, with registration names <tt>gs1reg</tt><i>X</i>.
<li>The function <tt>gs1a:start_link/1</tt> calls
<tt>gen_server:start_link/4</tt> with parameters:
<ul>
<li>Registered name: <tt>gs1reg</tt><i>X</i>
<li>Callback module: <tt>gs1b</tt>
</ul>
(<tt>gs1a:start_link/1</tt> obtains the registered name from the function
argument passed by the process <tt>gsup1reg</tt>.)
<li><tt>gen_server:start_link/4</tt> spawns a gen_server process, and registers
it as <tt>gs1reg</tt><i>X</i>.
<li>The process <tt>gs1reg</tt><i>X</i> calls <tt>gs1b:init/1</tt>.
<li>The function <tt>gs1b:init/1</tt> returns the initial state for process
<tt>gs1reg</tt><i>X</i>.<br>
(Currently <tt>gs1b:init/1</tt> ignores its single argument.)
<li>Each child process <tt>gs1reg</tt><i>X</i> is included in the supervisor's
child list with the ID <tt>gs1id</tt><i>X</i>.
<li>Processes <tt>gsup1reg</tt> and <tt>gs1reg</tt><i>X</i> enter a loop
(<tt>gen_server:loop/7</tt>), and wait a while.
</ol>
<!-- - - - - - - - - - - - - - - - -->
</ul>
</ul>
<!-- ===================================================================== -->
<p>Some <a href="http://erlang.org/doc/man/wx_object.html">wx_object</a>
experiments.
<ul>
<li><b><a href="mobsim4a.erl">mobsim4a.erl</a></b>, <b><a
href="mobsim4b.erl">mobsim4b.erl</a></b>, <b><a
href="mobsim4c.erl">mobsim4c.erl</a></b>, <b><a
href="mobsim4d.erl">mobsim4d.erl</a></b>:<br>
Modules A, B, C and D to port <a href="mobsim3.erl">mobsim3.erl</a> to the
wx_object framework.
<ul>
<li>The call chain is:<br>
<span class=equation>Erlang shell <==> A,D <==> WX-module <-->
WX-daemon <==> B <==> C.</span>
<ul>
<li>Erlang shell: <tt>erl</tt>
<li>Module A: <tt>mobsim4a.erl</tt>
<li>WX-module: [the wx_object module]
<li>WX-daemon: [the <q>wx_server client</q>]
<li>Module B: <tt>mobsim4b.erl</tt> [the <q>callback module</q>]
<li>Module C: <tt>mobsim4c.erl</tt> [wxWidgets functions]
<li>Module D: <tt>mobsim4d.erl</tt> [mobile node functions]
</ul>
<li>Module A converts Erlang shell commands to calls to the WX-module.<br>
Module B is the <q>callback module</q> which handles the WX-daemon's calls.<br>
Module C provides wxWidgets functions to Module B to show a window frame.<br>
Module D simulates some toy mobile nodes, which call the WX-daemon via the
WX-module's functions.<br>
<li>Communication between the WX-module and WX-daemon uses inter-process
messages.<br>
The other links use plain function calls.<br>
</ul>
</ul>
<!-- ===================================================================== -->
<p> Some general comments on <a
href="http://erlang.org/doc/apps/wx/index.html">wxErlang</a>.
<ul>
<li>I am finding that wxErlang is extremely slow. This is particularly true
because I am redrawing the entire window, containing up to 50 objects, every
time a single object moves. The Erlang functions which draw those objects are
moderately computationally demanding, but the redrawing of objects by wxErlang
is also quite slow.
<li>The main noticeable consequence of the slow drawing is that the simulation
of the objects progresses many seconds ahead of the window drawing updates.
Therefore the responses by the wxWidgets erlang-process to the mobile-node
processes are too slow. Consequently the size of the window, for example, is
communicated too slowly, and the mobile nodes repeatedly request this
information, which amplifies the problem.
<li>My conclusion from this is that wxErlang should only be used for low
bandwidth communications between the window-server process and the active
processes in any simulation.
<li>More generally, I do wonder whether monitoring of erlang processes via
messaging could be a serious bottleneck in any system. Too much monitoring can
impair the performance of the system being monitored. When processes written in
C or C++ communicate with <a href="http://erlang.org/doc/man/gen_udp.html">UDP
packets</a>, the overheads are not so great, maybe. So perhaps any kind of
higher bandwidth monitoring should be assisted by some non-Erlang code.
</ul>
<p><hr>
<a href="https://github.com/drauk/erltest">GitHub location of this
software</a>.<br>
<a href="http://validator.w3.org/check?uri=referer">W3C markup
validation</a>.<br>
</body></html>