Skip to content

Commit d9049ba

Browse files
committed
Handle AISAPI throttling and status 410 a bit better.
1 parent f75ac3e commit d9049ba

1 file changed

Lines changed: 54 additions & 10 deletions

File tree

indra/newview/llaisapi.cpp

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ class AISCommand final : public LLHTTPClient::ResponderWithCompleted
4747
public:
4848
typedef boost::function<void()> command_func_type;
4949
// AISCommand - base class for retry-able HTTP requests using the AISv3 cap.
50+
51+
// Limit max in flight requests to 2. Server was aggressively throttling otherwise.
52+
constexpr static U8 sMaxActiveAISCommands = 4;
53+
static U8 sActiveAISCommands;
54+
static std::queue< boost::intrusive_ptr< AISCommand > > sPendingAISCommands;
55+
56+
virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return AISAPIResponder_timeout; }
57+
5058
AISCommand(AISAPI::COMMAND_TYPE type, const char* name, const LLUUID& targetId, AISAPI::completion_t callback) :
5159
mCommandFunc(NULL),
5260
mRetryPolicy(new LLAdaptiveRetryPolicy(1.0, 32.0, 2.0, 10)),
@@ -55,13 +63,30 @@ class AISCommand final : public LLHTTPClient::ResponderWithCompleted
5563
mName(name),
5664
mType(type)
5765
{}
58-
59-
virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return AISAPIResponder_timeout; }
66+
virtual ~AISCommand()
67+
{
68+
if (mActive)
69+
{
70+
--sActiveAISCommands;
71+
while (sActiveAISCommands < sMaxActiveAISCommands && !sPendingAISCommands.empty())
72+
{
73+
sPendingAISCommands.front()->dispatch();
74+
sPendingAISCommands.pop();
75+
}
76+
}
77+
}
6078

6179
void run( command_func_type func )
6280
{
63-
LL_WARNS("Inventory") << "Sending request for " << getName() <<": " << mURL << LL_ENDL;
64-
(mCommandFunc = func)();
81+
mCommandFunc = func;
82+
if (sActiveAISCommands >= sMaxActiveAISCommands)
83+
{
84+
sPendingAISCommands.push(this);
85+
}
86+
else
87+
{
88+
dispatch();
89+
}
6590
}
6691

6792
char const* getName(void) const override
@@ -70,6 +95,16 @@ class AISCommand final : public LLHTTPClient::ResponderWithCompleted
7095
}
7196

7297
private:
98+
void dispatch()
99+
{
100+
if (LLApp::isQuitting())
101+
{
102+
return;
103+
}
104+
++sActiveAISCommands;
105+
mActive = true;
106+
(mCommandFunc)();
107+
}
73108
void markComplete()
74109
{
75110
// Command func holds a reference to self, need to release it
@@ -84,6 +119,11 @@ class AISCommand final : public LLHTTPClient::ResponderWithCompleted
84119
F32 seconds_to_wait;
85120
if (mRetryPolicy->shouldRetry(seconds_to_wait))
86121
{
122+
if (mStatus == 503)
123+
{
124+
// Pad delay a bit more since we're getting throttled.
125+
seconds_to_wait += 10.f + ll_frand(4.f);
126+
}
87127
LL_WARNS("Inventory") << "Retrying in " << seconds_to_wait << "seconds due to inventory error for " << getName() <<": " << dumpResponse() << LL_ENDL;
88128
doAfterInterval(mCommandFunc,seconds_to_wait);
89129
return true;
@@ -116,9 +156,13 @@ class AISCommand final : public LLHTTPClient::ResponderWithCompleted
116156
AISAPI::completion_t mCompletionFunc;
117157
const LLUUID mTargetId;
118158
const char* mName;
159+
bool mActive = false;
119160
AISAPI::COMMAND_TYPE mType;
120161
};
121162

163+
U8 AISCommand::sActiveAISCommands = 0;
164+
std::queue< boost::intrusive_ptr< AISCommand > > AISCommand::sPendingAISCommands;
165+
122166
//=========================================================================
123167
const std::string AISAPI::INVENTORY_CAP_NAME("InventoryAPIv3");
124168
const std::string AISAPI::LIBRARY_CAP_NAME("LibraryAPIv3");
@@ -333,11 +377,8 @@ void AISAPI::InvokeAISCommandCoro(LLHTTPClient::ResponderWithCompleted* responde
333377

334378
if (!responder->isGoodStatus(status) || !result.isMap())
335379
{
336-
if (!result.isMap())
337-
{
338-
LL_WARNS("Inventory") << "Inventory error: " << HTTP_INTERNAL_ERROR_OTHER << ": " << "Malformed response contents" << LL_ENDL;
339-
}
340-
else if (status == 410) //GONE
380+
LL_WARNS("Inventory") << "Inventory error: " << status << ": " << responder->getReason() << LL_ENDL;
381+
if (status == 410) //GONE
341382
{
342383
// Item does not exist or was already deleted from server.
343384
// parent folder is out of sync
@@ -370,7 +411,10 @@ void AISAPI::InvokeAISCommandCoro(LLHTTPClient::ResponderWithCompleted* responde
370411
gInventory.onObjectDeletedFromServer(targetId);
371412
}
372413
}
373-
LL_WARNS("Inventory") << "Inventory error: " << status << ": " << responder->getReason() << LL_ENDL;
414+
}
415+
if (!result.isMap())
416+
{
417+
LL_WARNS("Inventory") << "Inventory error: Malformed response contents" << LL_ENDL;
374418
}
375419
LL_WARNS("Inventory") << ll_pretty_print_sd(result) << LL_ENDL;
376420
}

0 commit comments

Comments
 (0)