From: Alan M Webb <alan_webb@us.ibm.com>

Some other IRC timing wrinkles  showed up:

[1] If connect processing blocked in socket activation, then
    the watch dog saw the session as connected, and eventually
    tried to ping, but because the socket create was still
    blocked, it barfed on a null reference. This then drove
    reconnect. Changed the watchdog handler so that it only
    tries to ping connections that are connected and not pending.
[2] If the socket creation actually fails, then the connect and
    pending flags were reset. This resulted in the connection
    being retried at the earliest possible opportunity. The
    longer login-timeout is preferrable, so the status flags
    are not reset, and the failed login is eventually timed
    out.
[3] The Inter-connection interval is primed so that the first
    session can connect without delay.
0.6.5-rc1
Dr Scofield 2009-04-23 09:06:36 +00:00
parent 1e54b0642e
commit 4b7a208559
1 changed files with 27 additions and 14 deletions

View File

@ -61,7 +61,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
private static int _idk_ = 0; // core connector identifier private static int _idk_ = 0; // core connector identifier
private static int _pdk_ = 0; // ping interval counter private static int _pdk_ = 0; // ping interval counter
private static int _icc_ = 0; // IRC connect counter private static int _icc_ = ICCD_PERIOD; // IRC connect counter
// List of configured connectors // List of configured connectors
@ -71,6 +71,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
private static System.Timers.Timer m_watchdog = null; private static System.Timers.Timer m_watchdog = null;
// The watch-dog gets started as soon as the class is instantiated, and
// ticks once every second (WD_INTERVAL)
static IRCConnector() static IRCConnector()
{ {
m_log.DebugFormat("[IRC-Connector]: Static initialization started"); m_log.DebugFormat("[IRC-Connector]: Static initialization started");
@ -234,10 +237,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
m_nick = m_baseNick + Util.RandomClass.Next(1, 99); m_nick = m_baseNick + Util.RandomClass.Next(1, 99);
} }
// Add the newly created connector to the known connectors list
// m_connectors.Add(this);
m_log.InfoFormat("[IRC-Connector-{0}]: Initialization complete", idn); m_log.InfoFormat("[IRC-Connector-{0}]: Initialization complete", idn);
} }
@ -255,14 +254,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
if (!m_enabled) if (!m_enabled)
{ {
m_connectors.Add(this);
m_enabled = true;
if (!Connected) if (!Connected)
{ {
Connect(); Connect();
} }
lock(m_connectors)
m_connectors.Add(this);
m_enabled = true;
} }
} }
@ -305,7 +306,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
} }
m_connectors.Remove(this); lock(m_connectors)
m_connectors.Remove(this);
} }
} }
@ -340,6 +342,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
try try
{ {
if (m_connected) return; if (m_connected) return;
m_connected = true; m_connected = true;
@ -376,8 +379,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
{ {
m_log.ErrorFormat("[IRC-Connector-{0}] cannot connect {1} to {2}:{3}: {4}", m_log.ErrorFormat("[IRC-Connector-{0}] cannot connect {1} to {2}:{3}: {4}",
idn, m_nick, m_server, m_port, e.Message); idn, m_nick, m_server, m_port, e.Message);
m_connected = false; // It might seem reasonable to reset connected and pending status here
m_pending = false; // Seeing as we know that the login has failed, but if we do that, then
// connection will be retried each time the interconnection interval
// expires. By leaving them as they are, the connection will be retried
// when the login timeout expires. Which is preferred.
} }
} }
@ -834,14 +840,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
protected static void WatchdogHandler(Object source, ElapsedEventArgs args) protected static void WatchdogHandler(Object source, ElapsedEventArgs args)
{ {
// m_log.InfoFormat("[IRC-Watchdog] Status scan"); // m_log.InfoFormat("[IRC-Watchdog] Status scan, pdk = {0}, icc = {1}", _pdk_, _icc_);
_pdk_ = (_pdk_+1)%PING_PERIOD; // cycle the ping trigger _pdk_ = (_pdk_+1)%PING_PERIOD; // cycle the ping trigger
_icc_++; // increment the inter-consecutive-connect-delay counter _icc_++; // increment the inter-consecutive-connect-delay counter
lock(m_connectors)
foreach (IRCConnector connector in m_connectors) foreach (IRCConnector connector in m_connectors)
{ {
// m_log.InfoFormat("[IRC-Watchdog] Scanning {0}", connector); // m_log.InfoFormat("[IRC-Watchdog] Scanning {0}", connector);
if (connector.Enabled) if (connector.Enabled)
{ {
if (!connector.Connected) if (!connector.Connected)
@ -863,14 +872,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
{ {
if (connector.m_timeout == 0) if (connector.m_timeout == 0)
{ {
// m_log.ErrorFormat("[IRC-Watchdog] Login timed-out for connector {0}, reconnecting", connector.idn); m_log.ErrorFormat("[IRC-Watchdog] Login timed-out for connector {0}, reconnecting", connector.idn);
connector.Reconnect(); connector.Reconnect();
} }
else else
connector.m_timeout--; connector.m_timeout--;
} }
if (_pdk_ == 0) // Being marked connected is not enough to ping. Socket establishment can sometimes take a long
// time, in which case the watch dog might try to ping the server before the socket has been
// set up, with nasty side-effects.
else if (_pdk_ == 0)
{ {
try try
{ {