Let statemachine honor approvements.

The inventory bulk fetch is not thread-safe, so the it doesn't start
right away, causing the approvement not to be honored upon return from
post_approved (formerly post_nb).

This patch renames wantsMoreHTTPReqestsFor to approveHTTPRequestFor,
and has it return NULL or a AIPerService::Approvement object.
The latter is now passed to the CurlEasyHandle object instead of just a
boolean mQueueIfTooMuchBandwidthUsage, and then the Approvement is
honored by the state machine right after the request is actually added
to the command queue.

This should avoid a flood of inventory requests in the case
approveHTTPRequestFor is called multiple times before the main thread
adds the requests to the command queue. I don't think that actually ever
happens, but I added debug code (to find some problem) that is so damn
strictly checking everything that I need to be this precise in order to
do that testing.
This commit is contained in:
Aleric Inglewood
2013-05-12 04:19:44 +02:00
parent 3d63f9cd24
commit 929badb110
11 changed files with 86 additions and 81 deletions

View File

@@ -1331,8 +1331,8 @@ void AICurlThread::process_commands(AICurlMultiHandle_wat const& multi_handle_w)
case cmd_boost: // FIXME: future stuff
break;
case cmd_add:
PerService_wat(*AICurlEasyRequest_wat(*command_being_processed_r->easy_request())->getPerServicePtr())->removed_from_command_queue();
multi_handle_w->add_easy_request(AICurlEasyRequest(command_being_processed_r->easy_request()));
PerService_wat(*AICurlEasyRequest_wat(*command_being_processed_r->easy_request())->getPerServicePtr())->removed_from_command_queue();
break;
case cmd_remove:
PerService_wat(*AICurlEasyRequest_wat(*command_being_processed_r->easy_request())->getPerServicePtr())->added_to_command_queue(); // Not really, but this has the same effect as 'removed a remove command'.
@@ -1708,7 +1708,7 @@ void MultiHandle::add_easy_request(AICurlEasyRequest const& easy_request)
{
AICurlEasyRequest_wat curl_easy_request_w(*easy_request);
per_service = curl_easy_request_w->getPerServicePtr();
bool too_much_bandwidth = curl_easy_request_w->queueIfTooMuchBandwidthUsage() && AIPerService::checkBandwidthUsage(per_service, get_clock_count() * HTTPTimeout::sClockWidth_40ms);
bool too_much_bandwidth = !curl_easy_request_w->approved() && AIPerService::checkBandwidthUsage(per_service, get_clock_count() * HTTPTimeout::sClockWidth_40ms);
PerService_wat per_service_w(*per_service);
if (!too_much_bandwidth && mAddedEasyRequests.size() < curl_max_total_concurrent_connections && !per_service_w->throttled())
{
@@ -2608,7 +2608,7 @@ bool AIPerService::sNoHTTPBandwidthThrottling;
// running requests (in MultiHandle::mAddedEasyRequests)).
//
//static
bool AIPerService::wantsMoreHTTPRequestsFor(AIPerServicePtr const& per_service)
AIPerService::Approvement* AIPerService::approveHTTPRequestFor(AIPerServicePtr const& per_service)
{
using namespace AICurlPrivate;
using namespace AICurlPrivate::curlthread;
@@ -2684,7 +2684,7 @@ bool AIPerService::wantsMoreHTTPRequestsFor(AIPerServicePtr const& per_service)
if (reject)
{
// Too many request for this service already.
return false;
return NULL;
}
// Throttle on bandwidth usage.
@@ -2692,7 +2692,7 @@ bool AIPerService::wantsMoreHTTPRequestsFor(AIPerServicePtr const& per_service)
{
// Too much bandwidth is being used, either in total or for this service.
PerService_wat(*per_service)->mApprovedRequests--; // Not approved after all.
return false;
return NULL;
}
// Check if it's ok to get a new request based on the total number of requests and increment the threshold if appropriate.
@@ -2726,8 +2726,9 @@ bool AIPerService::wantsMoreHTTPRequestsFor(AIPerServicePtr const& per_service)
if (reject)
{
PerService_wat(*per_service)->mApprovedRequests--; // Not approved after all.
return NULL;
}
return !reject;
return new Approvement(per_service);
}
bool AIPerService::checkBandwidthUsage(AIPerServicePtr const& per_service, U64 sTime_40ms)