Added emergency monitoring of UDP Outgoing packets thread. Just type "emergency-monitoring on/off"

0.7.1-dev
Diva Canto 2011-02-08 12:06:14 -08:00
parent 34bd41d186
commit ac7bc78555
3 changed files with 130 additions and 2 deletions

View File

@ -27,6 +27,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
@ -1053,6 +1054,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#endregion Update Timers #endregion Update Timers
if (m_scene.EmergencyMonitoring)
clientPacketHandler = MonitoredClientOutgoingPacketHandler;
// Handle outgoing packets, resends, acknowledgements, and pings for each // Handle outgoing packets, resends, acknowledgements, and pings for each
// client. m_packetSent will be set to true if a packet is sent // client. m_packetSent will be set to true if a packet is sent
m_scene.ForEachClient(clientPacketHandler); m_scene.ForEachClient(clientPacketHandler);
@ -1068,6 +1072,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler loop threw an exception: " + ex.Message, ex); m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler loop threw an exception: " + ex.Message, ex);
} }
} }
Watchdog.RemoveThread(); Watchdog.RemoveThread();
@ -1105,6 +1110,101 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
} }
#region Emergency Monitoring
private Stopwatch watch1 = new Stopwatch();
private Stopwatch watch2 = new Stopwatch();
private float avgProcessingTicks = 0;
private float avgResendUnackedTicks = 0;
private float avgSendAcksTicks = 0;
private float avgSendPingTicks = 0;
private float avgDequeueTicks = 0;
private long nticks = 0;
private long nticksUnack = 0;
private long nticksAck = 0;
private long nticksPing = 0;
private void MonitoredClientOutgoingPacketHandler(IClientAPI client)
{
nticks++;
watch1.Start();
try
{
if (client is LLClientView)
{
LLUDPClient udpClient = ((LLClientView)client).UDPClient;
if (udpClient.IsConnected)
{
if (m_resendUnacked)
{
nticksUnack++;
watch2.Start();
ResendUnacked(udpClient);
watch2.Stop();
avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack);
watch2.Reset();
}
if (m_sendAcks)
{
nticksAck++;
watch2.Start();
SendAcks(udpClient);
watch2.Stop();
avgSendAcksTicks = (nticksAck - 1) / (float)nticksAck * avgSendAcksTicks + (watch2.ElapsedTicks / (float)nticksAck);
watch2.Reset();
}
if (m_sendPing)
{
nticksPing++;
watch2.Start();
SendPing(udpClient);
watch2.Stop();
avgSendPingTicks = (nticksPing - 1) / (float)nticksPing * avgSendPingTicks + (watch2.ElapsedTicks / (float)nticksPing);
watch2.Reset();
}
watch2.Start();
// Dequeue any outgoing packets that are within the throttle limits
if (udpClient.DequeueOutgoing())
m_packetSent = true;
watch2.Stop();
avgDequeueTicks = (nticks - 1) / (float)nticks * avgDequeueTicks + (watch2.ElapsedTicks / (float)nticks);
watch2.Reset();
}
else
m_log.WarnFormat("[LLUDPSERVER]: Client is not connected");
}
}
catch (Exception ex)
{
m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler iteration for " + client.Name +
" threw an exception: " + ex.Message, ex);
}
watch1.Stop();
avgProcessingTicks = (nticks - 1) / (float)nticks * avgProcessingTicks + (watch1.ElapsedTicks / (float)nticks);
watch1.Reset();
// reuse this -- it's every 100ms
if (m_scene.EmergencyMonitoring && nticks % 100 == 0)
{
m_log.InfoFormat("[LLUDPSERVER]: avg processing ticks: {0} avg unacked: {1} avg acks: {2} avg ping: {3} avg dequeue: {4} (pack sent? {5})",
avgProcessingTicks, avgResendUnackedTicks, avgSendAcksTicks, avgSendPingTicks, avgDequeueTicks, m_packetSent);
}
}
#endregion
private void ProcessInPacket(object state) private void ProcessInPacket(object state)
{ {
IncomingPacket incomingPacket = (IncomingPacket)state; IncomingPacket incomingPacket = (IncomingPacket)state;

View File

@ -64,6 +64,8 @@ namespace OpenSim.Region.Framework.Scenes
#region Fields #region Fields
public bool EmergencyMonitoring = false;
public SynchronizeSceneHandler SynchronizeScene; public SynchronizeSceneHandler SynchronizeScene;
public SimStatsReporter StatsReporter; public SimStatsReporter StatsReporter;
public List<Border> NorthBorders = new List<Border>(); public List<Border> NorthBorders = new List<Border>();

View File

@ -96,6 +96,14 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
"Without the 'full' option, only root agents are shown." "Without the 'full' option, only root agents are shown."
+ " With the 'full' option child agents are also shown.", + " With the 'full' option child agents are also shown.",
ShowThrottlesReport); ShowThrottlesReport);
scene.AddCommand(
this, "emergency-monitoring",
"Go on/off emergency monitoring mode",
"Go on/off emergency monitoring mode",
"Go on/off emergency monitoring mode",
EmergencyMonitoring);
} }
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
@ -121,6 +129,24 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
MainConsole.Instance.Output(GetThrottlesReport(cmd)); MainConsole.Instance.Output(GetThrottlesReport(cmd));
} }
protected void EmergencyMonitoring(string module, string[] cmd)
{
bool mode = true;
if (cmd.Length == 1 || (cmd.Length > 1 && cmd[1] == "on"))
{
mode = true;
MainConsole.Instance.Output("Emergency Monitoring ON");
}
else
{
mode = false;
MainConsole.Instance.Output("Emergency Monitoring OFF");
}
foreach (Scene s in m_scenes.Values)
s.EmergencyMonitoring = mode;
}
protected string GetColumnEntry(string entry, int maxLength, int columnPadding) protected string GetColumnEntry(string entry, int maxLength, int columnPadding)
{ {
return string.Format( return string.Format(