Alo Sarv
lead developer

Donate via

Latest Builds

version 0.3
tar.gz tar.bz2
Boost 1.33.1 Headers
MLDonkey Downloads Import Module Development
Payment completed
Development in progress.
Developer's Diary

Saturday, May 28, 2005

Thoughts on LibCGComm

First of all, why on earth didn't anyone tell me earlier that the download links on front-page were still pointing to v0.1.0 for two days after 0.1.1 release? *doh*. It's fixed now, but I wonder how many people downloaded wrong version during that time...

Anyway, to the topic. I wrote up the preamble and overview of Hydranode Core/GUI Comminication Library document, viewable here, but moving on some difficulties appeared. First of all - how does one initialize the library? Consider that the library on it's own does not include any networking code (it simply creates the data for sending to core, and parses data received from core, but the sending/receiving must be implemented in client-side code) - this is done in order to be non-intrusive - including networking in the library would create large dependencies and make the library intrusive.

Obviously we need some kind of "main" class in the library, which provides some startup-code, e.g. authentication, some protocol negotiations (compression, endianess etc)... Other classes of the library shouldn't be available until a proper initialization is performed. However, this raises the question of how the other classes behave at all.

One idea was to design them as Singleton's, with lazy initialization (performed by the "main" class). The problem with Singleton pattern is that it becomes rather tiresome to type on constant basis - all major Engine structures are Singeltons, and I find myself rather tired of typing FilesList::instance().someFunc() instead of simply m_flist->someFunc(), if it was a variable. Approaching the problem in the object-oriented way, rather than using Singletons (at least not everwhere) allows somewhat more flexible, and intuitive API. For example, searches could be carried out like this:
m_curSearch = new Engine::Search("hello world");
m_curSearch->registerHandler(this, &MyClass::onSearchResult);
When going with full Singleton-based model, it would instead read something like this:
Engine::Search::instance().newSearch("hello world");
Engine::Search::instance().registerHandler(this, &MyClass::onSearchResult);
Clumsy and evil indeed. Or perhaps a combination of those two:
Engine::Search srch = Engine::SubSearch::instance().newSearch("hello world");
srch.registerHandler(this, &MyClass::onSearchResult);
Not getting any better either, so seems at least Searching should use the first example.

Actually, the entire API could be implemented without using any Singletons - you want download list? Create a Engine::DownloadList object. Likewise for other subsystems. Personally, I'm rather tired of Singletons everywhere. They do make sense in a program, but in a library, I'm not so sure any more. From the memory usage viewpoint (not that we'd have memory-usage issues nowadays, but worth a note anway), there isn't much of a difference, since lazily initialized singletons don't take up space when they aren't used.

A point, however, is when client code would like to disable some subsystems on runtime - this is where Singletons fall short - you can't really destroy a singleton object once it's created.

So, the bottom line is, singleton's don't really seem to cut it when writing libraries. Looking at the Engine, and notably, HNBase section (cross-platform API layer), there are no singletons there either, since it didn't make sense to create any there.

Madcat, ZzZz

PS: You might have noticed some changes/confusion in the naming scheme of Hydranode and related names. The most obvious change was HydraNode -> Hydranode casing change (there are still some places using the old casing - if you find some, let me know). Other change was calling the core "the Engine", or even "HydraEngine". This was done to allow "Hydranode Project" to include more standalone-software than simply "Hydranode" itself, considering that we'r releasing separate products, such as the engine itself, LibCGComm, web interface, mini-interface etc etc etc - there's a lot of additional product plans for the future. Yes, I'm aware the HydraEngine tarballs use the name "hydranode" right now - that's intentional, altough it might change in the future.

Hope this made any sense, it's 6am :)

Comments: Post a Comment

<< Home

This page is powered by Blogger. Isn't yours?