A New IRC::Client
Raku IRC Programming — Published on .
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
- Adding the
IRC::Client::Plugin
role toGeth::Plugin::Info
; - And to
Geth::Plugin::Uptime
; - Using
nicks
instead ofnick
; - Using
start
instead ofrun
; - Using
privmsg
instead ofsend
;
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!