Skip to content

Commit

Permalink
Ack every 30 seconds for EQ. Wish this requirement was documented
Browse files Browse the repository at this point in the history
  • Loading branch information
cinderblocks committed Feb 3, 2023
1 parent 1a96838 commit 8119fe8
Showing 1 changed file with 22 additions and 11 deletions.
33 changes: 22 additions & 11 deletions LibreMetaverse/Capabilities/EventQueueClient.cs
Expand Up @@ -54,7 +54,7 @@ public class EventQueueClient
protected readonly Simulator _Simulator;
protected bool _Dead;
protected bool _Running;
private CancellationTokenSource _HttpCts;
private CancellationTokenSource _QueueCts;

/// <summary>Number of times we've received an unknown CAPS exception in series.</summary>
private int _errorCount;
Expand All @@ -73,9 +73,15 @@ public void Start()
// Create an EventQueueGet request
OSDMap payload = new OSDMap {["ack"] = new OSD(), ["done"] = OSD.FromBoolean(false)};

_HttpCts = new CancellationTokenSource();
Task req = _Simulator.Client.HttpCapsClient.PostRequestAsync(_Address, OSDFormat.Xml, payload, _HttpCts.Token,
RequestCompletedHandler, null, ConnectedResponseHandler);
_QueueCts = new CancellationTokenSource();
CancellationTokenSource timeoutCts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
using (CancellationTokenSource linkedCts =
CancellationTokenSource.CreateLinkedTokenSource(_QueueCts.Token, timeoutCts.Token))
{
Task req = _Simulator.Client.HttpCapsClient.PostRequestAsync(_Address, OSDFormat.Xml, payload,
linkedCts.Token,
RequestCompletedHandler, null, ConnectedResponseHandler);
}
}

public void Stop(bool immediate)
Expand All @@ -87,7 +93,7 @@ public void Stop(bool immediate)
_Running = false;
}

_HttpCts.Cancel();
_QueueCts.Cancel();
}

void ConnectedResponseHandler(HttpResponseMessage response)
Expand Down Expand Up @@ -233,26 +239,31 @@ void RequestCompletedHandler(HttpResponseMessage response, byte[] responseData,

if (_Running)
{
CancellationToken cancelToken = _HttpCts.Token;
CancellationToken queueCancelToken = _QueueCts.Token;
OSDMap payload = new OSDMap();
if (ack != 0) { payload["ack"] = OSD.FromInteger(ack); }
else { payload["ack"] = new OSD(); }
payload["done"] = OSD.FromBoolean(_Dead);

if (_errorCount > 0)
{ // Exponentially back off, so we don't hammer the CPU
while (!cancelToken.IsCancellationRequested)
while (!queueCancelToken.IsCancellationRequested)
{
cancelToken.WaitHandle.WaitOne(
queueCancelToken.WaitHandle.WaitOne(
Math.Min(REQUEST_BACKOFF_SECONDS + _errorCount * REQUEST_BACKOFF_SECONDS_INC,
REQUEST_BACKOFF_SECONDS_MAX));
}
}
// Resume the connection.
if (!cancelToken.IsCancellationRequested)
if (!queueCancelToken.IsCancellationRequested)
{
Task req = _Simulator.Client.HttpCapsClient.PostRequestAsync(_Address, OSDFormat.Xml,
payload, cancelToken, RequestCompletedHandler);
CancellationTokenSource timeoutCts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
using (CancellationTokenSource linkedCts =
CancellationTokenSource.CreateLinkedTokenSource(queueCancelToken, timeoutCts.Token))
{
Task req = _Simulator.Client.HttpCapsClient.PostRequestAsync(_Address, OSDFormat.Xml,
payload, queueCancelToken, RequestCompletedHandler);
}
}

// If the event queue is dead at this point, turn it off since
Expand Down

0 comments on commit 8119fe8

Please sign in to comment.