Update: Replaced the pre tags around the code with code tags, per tye's recommendation.
This question comes up a lot, so I've written a response
for the FAQ at POE's wiki.
The rest of this node is a copy of that FAQ answer.
POE::Component::IRC seems slow for three reasons.
IRC servers have evolved in hostile environments. Less mature users
send messages in rapid succession as a form of denial of service
attack against networks and other users.
IRC servers buffer and rate-limit input to minimize the effects of
these "flood" attacks. Client input is released from the server's
buffers at human typing speeds. This is the first reason why
POE::Component::IRC seems slow.
IRC servers detect floods by watching their buffer sizes. The backlog
between what a client sends and what a channel sees increases as a
client continues to flood. The IRC server disconnects clients with
backlogs beyond a configurable limit. This is known as "flooding
yourself off" a server.
POE::Component::IRC performs its own rate limiting. It uses the
hybrid same rate limiting algorithm as the hybrid IRC server to send
data as fast as possible without overflowing the IRC server's buffers.
This prevents bots written with POE::Component::IRC from flooding
themselves off, even if the developer does something stupid (like
sending 100 lines of text all at once). This is the second reason
why POE::Component::IRC seems slow.
POE::Component::IRC's flood protection can be disabled. When
connecting to an IRC server, include a Flood => 1 parameter.
$kernel->post(
bot => connect => {
Nick => "my_nick",
Server => "irc.wherever.com",
Port => 6667,
Username => "my_user_name",
Ircname => "my_irc_name",
LocalAddr => "my.v.host",
Flood => 1, # Allow flooding.
}
);
|
This is mostly useful when you manage your own IRC server and can
disable its flood protection.
The third reason for POE::Component::IRC's seemingly slow output has
to do with the way its rate limiting works. The component must buffer
its own output to perform rate limiting. For fairness, messages being
transmitted to a server are kept more or less in the same order
they've been sent.
For example, a 100-line help message is kept together in the outgoing
message buffer. It will be transmitted at human typing speeds to
prevent the bot from flooding itself off the IRC server.
Meanwhile, any responses to other users will be put into the buffer
behind that 100-line message. The bot will seem unresponsive, even
though it has received and handled user requests. The other responses
will be sent in their turn, after the 100-line message.
A workaround has been suggested on POE's mailing list. Rather than
have all responses go through a single queue, split them into one
queue per destination. If POE::Component::IRC services each
destination in turn, then short responses won't need to wait for
longer ones to finish.
This workaround does have its drawbacks:
It only works in flood-protected mode. When Flood => 1, there is no
client buffer. All the flood protection will happen on the server side,
which may or may not be under your control.
The lag for each user increases as the number of simultaneous
responses increases. If there are 2 simultaneous responses, each is
serviced in 2x the usual time. If there are 10, then each response
takes 10x as much time to be sent. This is because the overall rate
limiting must be maintained to avoid the bot flooding itself off.
The workaround has not been implemented as of this writing.