BAF's Ramblings » #programming

BAFIRC: Design Architecture

October 4, 2010bafirc

I’ve made a very important design decision in regards to BAFIRC and how processing of IRC actions (and, really, most anything else) will be handled. Perhaps some of you are familiar with *nix, and how, generally, everything is treated as a file. I’m adopting a similar approach - everything is a plugin.

Handling user registration and server ping/pongs? A plugin. Handling CTCP requests and replies? A plugin. Handling DCC? A plugin. Organizing messages into their respective user/channel buffers? You guessed it, a plugin.

I will implement a basic API that allows the plugins to interact with and control most anything in the core/client. Beyond that, a plugin will handle the rest. This allows me to keep everything very modular, and have no problems with figuring out where certain control logic fits in. The various layers in the code (such as the IRC layer) will be very minimal, and anything beyond the most basic of functionality will be implemented in a plugin.

I have, on paper, sketched out how some various pieces will look like, but nothing has been set in stone. I will implement my base plugin system using MEF (which, if I am not mistaken, was added to .NET as of 4.0). Plugins will be able to act on the core or on the client. There will be a basic API that will be the same whether the plugin is on the core or on the client, and there will be specific API extensions for core- and client- specific plugins. An example of a core-specific plugin would be the logging plugin, whereas an example of a client-specific plugin would be a /sysinfo or /winamp type of deal. It is also conceivable that a plugin could run on both the core and the client, and establish a communication channel between the two.

I have not yet decided how I am going to implement the core/client communications, but I do plan on supporting named channels between the two, so that plugins may talk with themselves, and other similar uses. I may just go with an XML channel, but I need to analyze whether or not this will fit my needs without being too wasteful. It’s an obvious solution for ease in developing clients for different platforms, but there is a bit of overhead, both in the XML itself, and the construction/parsing of it on either end.

DCC will be handled by the core and the client. I will likely support DCC proxying from the core, and for performance sake, support direct connection to the client in some cases. The core will be configurable with a default action, and clients will be able to override this action. I haven’t decided on how the client will be able to do this yet - whether there will be a notion of an ‘active client’ where the most recently used client can either handle or defer it to someone else, or if it will be more of a race, first client to respond gets it. In the case that all clients defer or none respond within a certain timeout (or if no clients are connected), the core performs its default action. Files can be sent from/received to either the core or the client (and transferred to/from core storage), though chats will likely always be proxied through the core.

I may have written down more things than I am remembering right now, but this is all that comes to mind. Perhaps I’ll be able to muster up the time to do some more coding tonight.

BAFIRC: Distracting

October 4, 2010

BAFIRC is too distracting to think about. During class, I was sketching out the architecture of my irc layer, plugins system, and core/client responsibilities. Yes, sketching on plain old analog paper.

I am posting this now from my phone. A more detailed posting with my thoughts will appear shortly, when I am on my laptop, rather than typing on my phone.

BAFIRC: IRC Message Parser

October 4, 2010bafirc

I began working on the IRC layer tonight. Part of that was implementing an IRC message parser.

I tested out the use regular expressions in writing it. I have a fairly complex expression that can capture the values from any RFC-compliant message. Works great!

I put this up against a non-regular expression implementation (from cbots) to benchmark. The non-regex version is roughly two times faster than my new regex version. I am currently debating if I should keep the regular expression parser (which has cleaner looking code, coupled with an ugly expression) or adopt an approach similar to what cbots does (which gives uglier code, but is faster). On my machine, the difference, in practice, is negligible. Regular expression parsing takes 77ms to parse 11000 messages, whereas the same set run through the cbots parser takes 33ms. Performance will be good enough in either case. So it comes down to which implementation I should use, and I’m not sure what I’m going to do.

On a side note, with school and work, it may be a few more nights before I can set aside enough time to make any more notable progress.

BAFIRC: The IRC Layer

October 3, 2010bafirc

The first piece of BAFIRC is going to be the IRC communication layer. This layer will be totally standalone, making it easy to write first and test. There are several standalone pieces, but moving beyond that, everything will build on what has come before it.

I have thrown together IRC connection layers many times, using several languages. I could pull in one I’ve written before, but I’m starting from a totally clean slate and attempting to take advantage of the latest language features.

The IRC layer is fairly simple. The basic layer will support basic RFC IRC, including message parsing, message sending, message queuing (including a throttling layer to prevent you from flooding out the server and getting killed), all RFC defined commands and responses, and likely CTCP support. I am still undecided as to whether or not to include CTCP support in the base layer, as it is sort of an addon. DCC support will be separate, so I may make CTCP separate as well. I will provide hooks for these “addon” layers to plug in to, just to keep everything clean and modular.

I think I’m going to adopt an architecture similar to cbots as far as processing messages goes. I’m planning on having a single background thread that will manage both waiting to receive messages and sending messages (timer-based, to support message queuing). Once a complete IRC message is received incoming, it will be parsed down into an object and sent off to event handlers. Events will be fired for everything, giving a place for the core (or plugins, or any other non-BAFIRC uses) to plug in to and control anything.

That’s about all that comes to mind right now. The layer needs to be standalone enough that I can write a simple test program to get it on IRC. Once that is complete, I can begin working on other parts of the client, including the core server, web-chat support, logging system, etc.

Introducing: BAFIRC

October 2, 2010bafirc

Man, I’m doing it again - putting off my school work. That’s alright, because I’m just going to do a braindump, and then start on the work I need to get done (unless other distractions present themselves, like fixing and eating dinner).

Anyhow, I was just talking with Sevalecan, and we got into an interesting discussion. Both of us, for many years, have always talked about creating our own IRC clients. Both of us, however, never manage to actually finish them. I guess the fact that it’s sort of a dreamy personal project takes its toll. My personal experience (and, I would bet the same thing that happens to Sevalecan) is that I end up wanting everything to be perfect. Analysis paralysis, as it’s called. You code one portion of the project (or, worse yet, don’t even finish coding it before scrapping it), and find some flaw in it and decide to rewrite it. This happens over and over again, and, as its name implies, it paralyzes you.

I have a pretty lengthy feature list for BAFIRC, and I really would like to have it finished. I’ve sort of lost interest in the project, which may actually be a blessing in disguise, insofar as I won’t be concerned with it being 100% perfect. But at the end of the day, I really would like the project to be complete.

I was inspired by the movie The Social Network and was intrigued to see Zuckerberg blogging his progress of creating facesmash (this may or may not be true, the movie is highly dramatized). At any rate, I’ve seen other people doing the same thing on their projects, and it finally seems like both an interesting and useful idea to me. So I’m going to give it a try.

Whew. Now that we’ve got that out of the way, let’s lay the groundwork for BAFIRC. I have a list of features in mind that would create a pretty awesome IRC client that totally owns anything out there today. I’m going to attempt to list all the features here, though I am sure I will miss some. BAFIRC will be coded in C#, likely with .NET 4.0. I will likely use either Forms or WPF for this, I haven’t decided which yet, but I’m leaning towards WPF if only for the learning experience.

more