CHANNEL_MAX = 18 # Max channels open per socket (default)
ANTI_FLOOD_DELAY = 0.5 # Anti-flood delay after transmissions, seconds
ANTI_BUZZ_DELAY = 0.09 # Anti-buzz delay after queue-empty check
+CONNECTION_MAX = 200 # To avoid hitting a thread limit
# No user-serviceable parts below this line
-version = "1.9"
+version = "1.10"
-# This black magic imports support for green threads (coroutines),
-# then has kinky sex with the import library internals, replacing
-# "threading" with a coroutine-using imposter. Threads then become
-# ultra-light-weight and cooperatively scheduled.
-try:
- import eventlet
- eventlet.monkey_patch()
- green_threads = True
- # With greenlets we don't worry about thread exhaustion, only the
- # file descriptor limit (typically 1024 on modern Unixes). Thus we
- # can handle a lot more concurrent sessions and generate less
- # join/leave spam under heavy load.
- CONNECTION_MAX = 1000
-except ImportError:
- # Threads are more expensive if we have to use OS-level ones
- # rather than greenlets. We need to avoid pushing thread limits
- # as well as fd limits. See security.txt for discussion.
- CONNECTION_MAX = 200
- green_threads = False
-
-import sys, getopt, urlparse, time, random, socket
+import sys, getopt, urlparse, time, random, socket, signal
import threading, Queue, SocketServer
import irc.client, logging
try:
# even if the queue is nonempty but efforts to connect have failed for
# a long time.
#
-# There are multiple threads. One accepts incoming traffic from all servers.
-# Each Connection also has a consumer thread and a thread-safe message queue.
-# The program main appends messages to queues as JSON requests are received;
-# the consumer threads try to ship them to servers. When a socket write
-# stalls, it only blocks an individual consumer thread; if it stalls long
-# enough, the session will be timed out.
+# There are multiple threads. One accepts incoming traffic from all
+# servers. Each Connection also has a consumer thread and a
+# thread-safe message queue. The program main appends messages to
+# queues as JSON requests are received; the consumer threads try to
+# ship them to servers. When a socket write stalls, it only blocks an
+# individual consumer thread; if it stalls long enough, the session
+# will be timed out. This solves the biggest problem with a
+# single-threaded implementation, which is that you can't count on a
+# single stalled write not hanging all other traffic - you're at the
+# mercy of the length of the buffers in the TCP/IP layer.
#
# Message delivery is thus not reliable in the face of network stalls,
# but this was considered acceptable because IRC (notoriously) has the
self.status = "handshaking"
self.irker.debug(1, "XMIT_TTL bump (%s connection) at %s" % (self.servername, time.asctime()))
self.last_xmit = time.time()
+ self.last_ping = time.time()
except irc.client.ServerConnectionError:
self.status = "disconnected"
elif self.status == "handshaking":
server.setDaemon(True)
server.start()
try:
- while True:
- time.sleep(10)
+ signal.pause()
except KeyboardInterrupt:
raise SystemExit(1)
except socket.error, e: