It has been about one year ago when I featured the Presentation Zen blog of Garr Reynolds. Today it's his book, once again named Presentation Zen. Reading his blog is really interesting and helpful, but as always with online documents it's more a quick scanning instead a lasting learning. With books that's different, at least for me. Here I take more time for reading and internalize it more - this time again. Garr has very good informations, hints, and examples about preparing, designing, and presenting. I've already had the chance to test his hints. And yes, it's really working. Instead of masses of bullet point lists with only some graphics I now create smaller presentations, with a story, with less text and more images, and step by step I'm presenting it more gripping. I've even organized a cordless presenter to be more flexible in moving and interacting with the audience. I'm still by far not perfect, but now I have a great mind to present and teach more than I've done the last years.
Wednesday, 27 February 2008
Next watch
I think I've found my next watch. It's the phosphor Ana-Digi Watch which is using the e-ink technology to support different dial themes. Color and style are changeable. So the watch fits always to mood and clothes.
Posted by
mue
at
9:13 PM
0
Comments
Link
Labels: misc
Saturday, 16 February 2008
Erlang guards
Like matches, which are a very powerful instrument to split a large complex function into short better maintainable, this can also be supported through guards. Lets take for example a server using internally a process pool. This pool shall only provide the managed active processes until a maximum number, and take them back until a maximum number of free ones is reached. So the functions may be
handle_cast({do_it, Task}, S) when S#state.actno >= ?MAX_ACT_NO ->
% Too much active processes, resend message.
gen_server:cast(?MODULE, {do_it, Task}),
{noreply, S};
handle_cast({do_it, Task}, S) when S#state.freeno > 0 ->
% Use a free process.
...
{noreply, NewS};
handle_cast({do_it, Task}, S) ->
% Create a new process and use it.
...
{noreply, NewS};
handle_cast({return_it, Proc}, S) when S#state.freeno >= ?MAX_FREE_NO ->
% Dispose process.
...
{noreply, NewS};
handle_cast({return_it, Proc}, S) ->
% Return the worker to the pool.
...
{noreply, NewS}.
Posted by
mue
at
10:52 PM
0
Comments
Link
Labels: erlang
Saturday, 9 February 2008
Experiences made with Erlang while developing the CEL
Since end of August last year I'm reading about and developing in Erlang. The current state is that I'll release the Tideland Common Erlang Library (CEL) as public beta in a few days. I've just to review those modules I havn't worked on the last weeks, but then I'll tag it in our subversion and also create a package for download. The modules inside the CEL are
- the CELSML for parsing documents in the Simple Markup Language,
- the CELSTH to convert SML into HTML,
- the CELETM for execution time monitoring,
- some helpful utility functions in CELUTL, and
- the Lightweight Message Bus CELLMB.
Especially the development of the last one devoured some time. First trials without the right knowledge about the system led to bad designs. But through those experiments and through reading the book of Joe Armstrong the concepts get better and the implementation more and more reliable. Especially those features of Erlang, the concentration on reliability, high-availability, and scalability, are fascinating me due to my personal professional background in mainframe and high-available Unix environments.
So one of the major experiences made is, that this Erlang support is really good and mechanisms like unchangeable variables and lightweight processes which share nothing are extreme powerful. But in return especially the asynchronous message handling needs special attention. Processes may die and never send an answer, so working with timeouts is really helpful. But in times of a vary high load those timeouts may be exceeded. So your applications need to handle those situations proper. After my functional unit test I made some stress tests where I discovered this behaviour and wondered why my tests failed. So I can recommend everyone to start those stress tests early. Another importand point handling high loads is to keep an eye on the number of active processes. If spawned too fast it may exceed the configured VM limit. So this shoud be set to a high level or the spawning of new processes should stopped until others finished their work. The CELLMB provides a configurable limit and received message are resent to the bus until there are free resources again.
Another feature of Erlang I really appreciate is the combination of pattern matching and guards, especially for the declaration of functions. So instead of a large and nested application logic inside one function a set of small and handy function bodies are used. Those are by far better maintainable. Many of those matchings and guards are base on single arguments. But very often tuples are used, a simple and powerful mechanism. But while short tuples are easy to handle it gets more and more awkward when they grow and are used over module borders. Especially modification of them is bad. So even if their syntax is a bit strange here this is the right situation to use records. They are helpful in both forms, externally included or just internally inside a module.
What's helpful for generic frameworks are callbacks. They provide an easy way to create extensible frameworks where the user can plug-in his own logic. So the subscribed services to the CELLMB are just modules providing defined callbacks for start, stop, the test if they are interested in a message, and a function for each command or one generic process function. When a service subscribes with
cellmb:subscribe(myshopmodule, SvcArgs)
it will be initialized with
myshopmodule:start(SvcArgs).
This function can be empty, e.g. for stateless services, but it can also be used to start a process. A message published by the client through
MH = cellmb:publish(shop, purchase, [MyBasket]).
leads to the call of
myshopmodule:purchase([MyBasket], Context, SvcArgs, Msg).
if the module answered with a well defined priority after being asked through
myshopmodule:processes(Msg, SvcArgs).
Why that priority? Several modules may be interested in processing this message. Through returning a priority in a defined span they can control the order of processing and pass informations between them using the context. This allows very flexible configurations. After all services have done their work their collected responses are sent back to the client process and can be retrieved with
Responses = cellmb:rcvres(MH, Timeout).
Additionally synchronous combinations of publish and receive, an unidirectional send function and many convenience functions are provided.
What else? Funs are always really useful, like in other dynamic languages, Exception handling is easy, the library is really great for distributed server-side applications, I still need more experience with the supervision tree and monitoring, and I'm looking forward my first experiences with Mnesia when now developing some standard services for authentication, a role-based authorization, a management of access control lists, a user management, and an address management using the structures defined in the vCard standard.
Posted by
mue
at
12:28 AM
0
Comments
Link
Labels: erlang
Subscribe to:
Posts (Atom)