A New IRC::Client

#raku #irc #programming

The Raku programming language has a popular module for creating IRC bots, IRC::Client. However, it’s been stale for quite a while, and one of the bots I host, Geth, is having troubles on a regular basis.

I’ve looked at the source code, and found a lot of neat tricks, but when maintaining a library, I generally want clean and straightforward code instead. To that end, I decided to just write my own from scratch. Given that the IRC protocol is rather simple, this was the easiest way to go about it.

Sure enough, after a couple hours of playing around, I had something that worked reasonably well. A few more hours a day afterwards brought me to an IRC::Client that is usable in mostly the same way as the current IRC::Client, to save me effort in getting my current bots to make use of it for a few test runs.

Geth was my main target, as I wanted it to stop from getting timed out so often. For the past week, Geth has been running stable, without any time out, so I think I’ve succeeded in the main goal.

However, how to continue next? Since it is mostly compatible, but not completely compatible, if I were to adopt IRC::Client from the Raku ecosystem and push my version, many people’s IRC bots would break when people update their dependencies. There is a solution for this built into the entire ecosystem, which is using the correct :ver and :auth (and in some cases, :api) so you can ensure your project is always getting the “correct” dependency. However, from personal experience, I know these additional dependency restrictions are rarely used in practice.

I hope that with this blog post, I can inform the community in time about the changes that are coming to IRC::Client, so people have ample time to set their dependencies just right to keep their projects working. Of course, the real solution for the long term would be to make the small changes required to use the latest IRC::Client again.

For convenience sake, I’ve added a small number of methods for backwards compatibility as well, though these will generate a deprecation warning, and will be removed in a later IRC::Client release.

There’s two major changes that are not backwards compatible, however. The first one is the removal of the ability to have a single IRC::Client connect to multiple servers. This is also the easiest to remedy, by simply creating multiple instances of IRC::Client.

The second major incompatible change is how events are dispatched to plugins. This used to be handled by going through all the plugins sequentially, allowing one plugin to stop the dispatch to another plugin. In my new version, events are dispatched to all plugins in parallel. This allows for faster execution, and for multiple plugins to handle an event without having to use $*NEXT (which has been removed). My main motivation is that a buggy plugin will no longer interfere with the interactions provided by other plugins. The ordering of your plugins will also stop being an issue to worry about.

Geth’s updates to actually use my updated IRC::Client module was introduced in edc6b08, and most if it was updates to the way it handled logging. The actual changes needed to make Geth play nice were

The last two changes aren’t strictly necessary, as there are backwards compatibility methods made for these, but it’s a rather small change and reduces the amount of noise in the logs.

With this, I hope everyone using IRC::Client is prepared for the coming changes. If you have any comments or questions, do not hesitate to reach out to me and share your thoughts!