add queue transition code needs review/more testing
parent
fa59cddc28
commit
70890e211a
|
@ -175,27 +175,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Always returns a valid queue
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="agentId"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private Queue<OSD> TryGetQueue(UUID agentId)
|
|
||||||
{
|
|
||||||
lock (queues)
|
|
||||||
{
|
|
||||||
if (!queues.ContainsKey(agentId))
|
|
||||||
{
|
|
||||||
m_log.DebugFormat(
|
|
||||||
"[EVENTQUEUE]: Adding new queue for agent {0} in region {1}",
|
|
||||||
agentId, m_scene.RegionInfo.RegionName);
|
|
||||||
queues[agentId] = new Queue<OSD>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return queues[agentId];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// May return a null queue
|
/// May return a null queue
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -278,47 +257,95 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
public void OnRegisterCaps(UUID agentID, Caps caps)
|
public void OnRegisterCaps(UUID agentID, Caps caps)
|
||||||
{
|
{
|
||||||
// Register an event queue for the client
|
// Register an event queue for the client
|
||||||
|
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
|
"[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
|
||||||
agentID, caps, m_scene.RegionInfo.RegionName);
|
agentID, caps, m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
// Let's instantiate a Queue for this agent right now
|
|
||||||
TryGetQueue(agentID);
|
|
||||||
|
|
||||||
UUID eventQueueGetUUID;
|
UUID eventQueueGetUUID;
|
||||||
|
Queue<OSD> queue;
|
||||||
|
Random rnd = new Random(Environment.TickCount);
|
||||||
|
int nrnd = rnd.Next(30000000);
|
||||||
|
if (nrnd < 0)
|
||||||
|
nrnd = -nrnd;
|
||||||
|
|
||||||
lock (m_AvatarQueueUUIDMapping)
|
lock (queues)
|
||||||
{
|
{
|
||||||
// Reuse open queues. The client does!
|
if (queues.ContainsKey(agentID))
|
||||||
// Its reuse caps path not queues those are been reused already
|
queue = queues[agentID];
|
||||||
if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
|
else
|
||||||
|
queue = null;
|
||||||
|
|
||||||
|
if (queue == null)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
|
queue = new Queue<OSD>();
|
||||||
eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
|
queues[agentID] = queue;
|
||||||
|
|
||||||
|
// push markers to handle old responses still waiting
|
||||||
|
// this will cost at most viewer getting two forced noevents
|
||||||
|
// even being a new queue better be safe
|
||||||
|
queue.Enqueue(null);
|
||||||
|
queue.Enqueue(null); // one should be enough
|
||||||
|
|
||||||
|
lock (m_AvatarQueueUUIDMapping)
|
||||||
|
{
|
||||||
|
eventQueueGetUUID = UUID.Random();
|
||||||
|
if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
|
||||||
|
{
|
||||||
|
// oops this should not happen ?
|
||||||
|
m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID without a queue");
|
||||||
|
eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
|
||||||
|
}
|
||||||
|
m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
|
||||||
|
}
|
||||||
|
lock (m_ids)
|
||||||
|
{
|
||||||
|
if (!m_ids.ContainsKey(agentID))
|
||||||
|
m_ids.Add(agentID, nrnd);
|
||||||
|
else
|
||||||
|
m_ids[agentID] = nrnd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
eventQueueGetUUID = UUID.Random();
|
// push markers to handle old responses still waiting
|
||||||
m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
|
// this will cost at most viewer getting two forced noevents
|
||||||
m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
|
// even being a new queue better be safe
|
||||||
|
queue.Enqueue(null);
|
||||||
|
queue.Enqueue(null); // one should be enough
|
||||||
|
|
||||||
|
// reuse or not to reuse TODO FIX
|
||||||
|
lock (m_AvatarQueueUUIDMapping)
|
||||||
|
{
|
||||||
|
// Reuse open queues. The client does!
|
||||||
|
// Its reuse caps path not queues those are been reused already
|
||||||
|
if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
|
||||||
|
eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eventQueueGetUUID = UUID.Random();
|
||||||
|
m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
|
||||||
|
m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lock (m_ids)
|
||||||
|
{
|
||||||
|
// change to negative numbers so they are changed at end of sending first marker
|
||||||
|
// old data on a queue may be sent on a response for a new caps
|
||||||
|
// but at least will be sent with coerent IDs
|
||||||
|
if (!m_ids.ContainsKey(agentID))
|
||||||
|
m_ids.Add(agentID, -nrnd); // should not happen
|
||||||
|
else
|
||||||
|
m_ids[agentID] = -m_ids[agentID];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
caps.RegisterPollHandler(
|
caps.RegisterPollHandler(
|
||||||
"EventQueueGet",
|
"EventQueueGet",
|
||||||
new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS));
|
new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS));
|
||||||
|
|
||||||
Random rnd = new Random(Environment.TickCount);
|
|
||||||
int nrnd = rnd.Next(30000000);
|
|
||||||
|
|
||||||
lock (m_ids)
|
|
||||||
{
|
|
||||||
if (!m_ids.ContainsKey(agentID))
|
|
||||||
m_ids.Add(agentID, nrnd);
|
|
||||||
else
|
|
||||||
m_ids[agentID] = nrnd;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasEvents(UUID requestID, UUID agentID)
|
public bool HasEvents(UUID requestID, UUID agentID)
|
||||||
|
@ -361,55 +388,65 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
return NoEvents(requestID, pAgentId);
|
return NoEvents(requestID, pAgentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
OSD element;
|
OSD element = null;;
|
||||||
|
OSDArray array = new OSDArray();
|
||||||
|
int thisID = 0;
|
||||||
|
bool negativeID = false;
|
||||||
|
|
||||||
lock (queue)
|
lock (queue)
|
||||||
{
|
{
|
||||||
if (queue.Count == 0)
|
if (queue.Count == 0)
|
||||||
return NoEvents(requestID, pAgentId);
|
return NoEvents(requestID, pAgentId);
|
||||||
element = queue.Dequeue(); // 15s timeout
|
|
||||||
}
|
|
||||||
|
|
||||||
int thisID = 0;
|
lock (m_ids)
|
||||||
lock (m_ids)
|
thisID = m_ids[pAgentId];
|
||||||
thisID = m_ids[pAgentId];
|
|
||||||
|
|
||||||
OSDArray array = new OSDArray();
|
if (thisID < 0)
|
||||||
if (element == null) // didn't have an event in 15s
|
|
||||||
{
|
|
||||||
// Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
|
|
||||||
array.Add(EventQueueHelper.KeepAliveEvent());
|
|
||||||
//m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", pAgentId, m_scene.RegionInfo.RegionName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (DebugLevel > 0)
|
|
||||||
LogOutboundDebugMessage(element, pAgentId);
|
|
||||||
|
|
||||||
array.Add(element);
|
|
||||||
|
|
||||||
lock (queue)
|
|
||||||
{
|
{
|
||||||
while (queue.Count > 0)
|
negativeID = true;
|
||||||
{
|
thisID = -thisID;
|
||||||
element = queue.Dequeue();
|
}
|
||||||
|
|
||||||
if (DebugLevel > 0)
|
while (queue.Count > 0)
|
||||||
LogOutboundDebugMessage(element, pAgentId);
|
{
|
||||||
|
element = queue.Dequeue();
|
||||||
array.Add(element);
|
// add elements until a marker is found
|
||||||
thisID++;
|
// so they get into a response
|
||||||
}
|
if (element == null)
|
||||||
|
break;
|
||||||
|
if (DebugLevel > 0)
|
||||||
|
LogOutboundDebugMessage(element, pAgentId);
|
||||||
|
array.Add(element);
|
||||||
|
thisID++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OSDMap events = new OSDMap();
|
OSDMap events = null;
|
||||||
events.Add("events", array);
|
|
||||||
|
if (array.Count > 0)
|
||||||
|
{
|
||||||
|
events = new OSDMap();
|
||||||
|
events.Add("events", array);
|
||||||
|
events.Add("id", new OSDInteger(thisID));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (negativeID && element == null)
|
||||||
|
{
|
||||||
|
Random rnd = new Random(Environment.TickCount);
|
||||||
|
thisID = rnd.Next(30000000);
|
||||||
|
if (thisID < 0)
|
||||||
|
thisID = -thisID;
|
||||||
|
}
|
||||||
|
|
||||||
events.Add("id", new OSDInteger(thisID));
|
|
||||||
lock (m_ids)
|
lock (m_ids)
|
||||||
{
|
{
|
||||||
m_ids[pAgentId] = thisID + 1;
|
m_ids[pAgentId] = thisID + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if there where no elements before a marker send a NoEvents
|
||||||
|
if (array.Count == 0)
|
||||||
|
return NoEvents(requestID, pAgentId);
|
||||||
|
|
||||||
Hashtable responsedata = new Hashtable();
|
Hashtable responsedata = new Hashtable();
|
||||||
responsedata["int_response_code"] = 200;
|
responsedata["int_response_code"] = 200;
|
||||||
responsedata["content_type"] = "application/xml";
|
responsedata["content_type"] = "application/xml";
|
||||||
|
@ -433,7 +470,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
return responsedata;
|
return responsedata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void DisableSimulator(ulong handle, UUID avatarID)
|
public void DisableSimulator(ulong handle, UUID avatarID)
|
||||||
{
|
{
|
||||||
OSD item = EventQueueHelper.DisableSimulator(handle);
|
OSD item = EventQueueHelper.DisableSimulator(handle);
|
||||||
|
|
Loading…
Reference in New Issue