i see Phoenix rise from the ashes ... ;)

+1 for all

2) libuv is used by node.js - good choice
4) i'm coming from telco side - https://wiki.asterisk.org/wiki/display/AST/ARI+Push+Configuration
6) important is easy integration with ELK stack
7) i hope its better than unixODBC

Dne 30.5.2016 v 10:31 Tomasz Sterna napsal(a):
There are some things we already talked about on Gitter channel [1],
but I would like to raise them on the ML for peer review.

As you can see from late activity, jabberd2 project is far from dead.
With the inclusion of new features like WebSocket support, C99 code
compatibility, IPv6 improvements, modern TLS handling, SASL Anonymous,
password hashing, CRAM-MD5 and more... it is not a stale codebase

But it is far from modern too...
There are some changes I would like to introduce in the near future and
I would like to hear your thoughts about:

1. Merging separate daemons to one.
Current design of jabberd2 with separate router, sm, c2s, s2s processes
is designed to allow nice separation of concerns and distribution of
processing. Separate processes are proved to be better approach than
threads too.
But most installations of jabberd are not distributed, with one
instance of each component. Especially when c2s and sm got vhost
support and are able to handle more than one domain.
Also, modern OS architectures are tuned for event processing rather
than multithreading, so event based architecture is better suited for
them. Even jabberd2 process internally is event based on MIO.
So, it makes sense to allow for running all component instances in one
process, especially on amateur, low load servers.
Merging processes will allow for having one main loop only, so
maintaining bugfixes in it will be easier (main.c of all processes is a
copy-paste, with all the bugs, so bugs are also multiplied).

2. Phasing out MIO.
This is closely related to above. MIO used by jabberd2 does not have
clerar main loop support, which is implemented separately in each
component main.c and is hardly pluggable.
Also, the way MIO is implemented (in .h file, with platform specific
bits in .c) makes it a maintanance nightmare.
I would really like to replace it with a modern, upstream maintained
event library. The nicest one I know is libuv, which also gives us nice
platform independence layer.
I already have a working c2s port to libuv as a PoC.

3. Phasing out router.
router component is the one binding all the others.
In current design it is the single point of failure. Other components
already support multiple instances, but router proved to be difficult
to multiply.
The most radical, yet compelling solution to this problem is getting
rid of the router at all. There are many cooked solutions for local
packet distribution, which Local Message Bus [2] looks like most
promising solution. I would see either Mbus [3] or NN_BUS [4] taking
role of router component.
The added advantage of using a Message Bus is the ability to connect to
the bus with alternative implementations to perform own actions.
i.e. having the ability to use CLI tools to eavesdrop and send messages
to the bus proved to be priceless when I implemented a PoC of the Bus
in experimental jabberd branch.
Bus also solves the problem of distribution - it is up to the
deployment administrator whether one sets up local, one-machine only
bus or a network distributed one.

4. Configuration interface.
A the moment jabberd is configured with static XML files loaded at
daemon startup. It is close to impossible to change the values in
runtime, as random places of the process are using copies of values or
direct pointers to values from config structure.
This heavily impedes implementation of features such as XEP-0133
Service Administration or Web interface.
 From my experience, the best handling of such requirements is to
provide write-only/change-subscribe interface similar to GConf/dconf.
This interface does not allow reading on-demand of random values, but
allows only subscription to change and write-value + publish change.
This approach forces programmer to write value-change handlers in
application code, which allows changing the value by anyone at any
Do you know any standalone library that implements such approach,
or do I need to implement custom solution in jabberd codebase?

5. JavaScript support.
Let's face it - JavaScript is all the hype today :-) It also is a very
good language for data processing. I think it would be a good solution
for implementation of modern XEP logic in sm component.
sm is implemented in C with all RFC required logic, and all XEPs are
loadable modules to sm and these add JEP/XEP functionality.
Having an option to implement XEP logic in JS instead of plain C,
should speed up recent and experimental XEP adoption in jabberd.
This gives concerns to jabberd2 as an embedded server though - current
jabberd2 is perfectly able to work fine on low resource machines such
as DD-WRT router. Introducing heavy JS JIT machine could change that.
But with the raise of fast, embeddable JavaScript interpreters like
Duktape [5] it should be non-issue.

6. Proper logging.
jabberd2 has two logging facilities: log and debug_log, with log
logging only most interesting events and debug_log all the rest.
To aid debugging issues with your deployment you may enable -D switch
or send SIGUSR2 to your demon. But this will flood you with all the
debug and trace information, only programmers can make us off.
I am already working on replacing the logging with more fine-tuned
log4c [6] implementation.

7. DBI interface to RDBM.
sm storage backends for SQL RDBMs are a copy-pasted clones of the same
implementation sprinkled with improvements here and bugfixes there.
Porting new features and fixes between backends is painful and
unnecessary. I would rather see one backend for all these - it's SQL
after all.
I plan on merging all SQL storage backends to one, libdbi [7] based one
merging all the features and fixes, pushing all the discrepancies of
RDBMs to libdbi-drivers upstream implementation. Then slowply phasing
out individual implementations.

8. String handling.
Every seasoned programmer knows that C "strings" are not Strings.
char* is not a String. String is a sequence of characters of known
length. char[] comes close, but it immediately degrades to char*.
Also, contrary to its name, char is not a character. Characters are
coded with natural numbers and char is signed. Also, UTF-8 encoding
(the only one we care about) does not fit in 8bits of char.
To mitigate these issues I am in the process of introducing sds [8]
and libunistring [9] for all string handling.

What do you think of these ideas, guys?
Do you have any suggestions for even more disturbing improvements? :-)
I would love to hear all feedback.

You may take a look at experimental/PoC codebase at ashnazg [10] branch on 

[1] http://gitter.im/jabberd2/jabberd2
[2] http://en.wikipedia.org/wiki/Message-oriented_middleware
[3] http://www.mbus.org/
[4] http://nanomsg.org/v0.9/nn_bus.7.html
[5] http://duktape.org/
[6] http://log4c.sourceforge.net/
[7] http://libdbi.sourceforge.net/
[8] http://github.com/antirez/sds
[9] http://www.gnu.org/software/libunistring/
[10] http://github.com/jabberd2/jabberd2/tree/ashnazg

Marek Cervenka

Reply via email to