diff options
author | Monty Brandenberg <monty@lindenlab.com> | 2012-06-22 19:13:50 -0400 |
---|---|---|
committer | Monty Brandenberg <monty@lindenlab.com> | 2012-06-22 19:13:50 -0400 |
commit | bc7d5b24d16963a2715e880c518a4706a99f02fa (patch) | |
tree | db91cb215ecf88fa57bbe599cba9df699fd46334 /indra/llcorehttp/_httppolicy.cpp | |
parent | 5ff1758b633f1984f601aacbb7920c3c744b87f7 (diff) |
This sets down the groundwork for dynamic policy classes.
Groundwork is used for the default class which currently represents
texture fetching. Class options implemented from API user into
HttpLibcurl. Policy layer is going to start doing some traffic
shaping like work to solve problems with consumer-grade gear.
Need to have dynamic aspects to policies and that starts now...
Diffstat (limited to 'indra/llcorehttp/_httppolicy.cpp')
-rw-r--r-- | indra/llcorehttp/_httppolicy.cpp | 69 |
1 files changed, 58 insertions, 11 deletions
diff --git a/indra/llcorehttp/_httppolicy.cpp b/indra/llcorehttp/_httppolicy.cpp index 4be9f1d45f..1dae20add6 100644 --- a/indra/llcorehttp/_httppolicy.cpp +++ b/indra/llcorehttp/_httppolicy.cpp @@ -31,6 +31,7 @@ #include "_httpoprequest.h" #include "_httpservice.h" #include "_httplibcurl.h" +#include "_httppolicyclass.h" #include "lltimer.h" @@ -38,14 +39,44 @@ namespace LLCore { + +struct HttpPolicy::State +{ +public: + State() + : mConnMax(DEFAULT_CONNECTIONS), + mConnAt(DEFAULT_CONNECTIONS), + mConnMin(2), + mNextSample(0), + mErrorCount(0), + mErrorFactor(0) + {} + + HttpReadyQueue mReadyQueue; + HttpRetryQueue mRetryQueue; + + HttpPolicyClass mOptions; + + long mConnMax; + long mConnAt; + long mConnMin; + + HttpTime mNextSample; + unsigned long mErrorCount; + unsigned long mErrorFactor; +}; + + HttpPolicy::HttpPolicy(HttpService * service) - : mService(service) + : mActiveClasses(0), + mState(NULL), + mService(service) {} HttpPolicy::~HttpPolicy() { - for (int policy_class(0); policy_class < LL_ARRAY_SIZE(mState); ++policy_class) + for (int policy_class(0); policy_class < mActiveClasses; ++policy_class) { HttpRetryQueue & retryq(mState[policy_class].mRetryQueue); while (! retryq.empty()) @@ -67,13 +98,27 @@ HttpPolicy::~HttpPolicy() readyq.pop(); } } + delete [] mState; + mState = NULL; mService = NULL; } -void HttpPolicy::setPolicies(const HttpPolicyGlobal & global) +void HttpPolicy::setPolicies(const HttpPolicyGlobal & global, + const std::vector<HttpPolicyClass> & classes) { + llassert_always(! mState); + mGlobalOptions = global; + mActiveClasses = classes.size(); + mState = new State [mActiveClasses]; + for (int i(0); i < mActiveClasses; ++i) + { + mState[i].mOptions = classes[i]; + mState[i].mConnMax = classes[i].mConnectionLimit; + mState[i].mConnAt = mState[i].mConnMax; + mState[i].mConnMin = 2; + } } @@ -123,13 +168,14 @@ HttpService::ELoopSpeed HttpPolicy::processReadyQueue() HttpService::ELoopSpeed result(HttpService::REQUEST_SLEEP); HttpLibcurl & transport(mService->getTransport()); - for (int policy_class(0); policy_class < LL_ARRAY_SIZE(mState); ++policy_class) + for (int policy_class(0); policy_class < mActiveClasses; ++policy_class) { + State & state(mState[policy_class]); int active(transport.getActiveCountInClass(policy_class)); - int needed(DEFAULT_CONNECTIONS - active); // *FIXME: move to policy class + int needed(state.mConnAt - active); // Expect negatives here - HttpRetryQueue & retryq(mState[policy_class].mRetryQueue); - HttpReadyQueue & readyq(mState[policy_class].mReadyQueue); + HttpRetryQueue & retryq(state.mRetryQueue); + HttpReadyQueue & readyq(state.mReadyQueue); if (needed > 0) { @@ -174,9 +220,10 @@ HttpService::ELoopSpeed HttpPolicy::processReadyQueue() bool HttpPolicy::changePriority(HttpHandle handle, HttpRequest::priority_t priority) { - for (int policy_class(0); policy_class < LL_ARRAY_SIZE(mState); ++policy_class) + for (int policy_class(0); policy_class < mActiveClasses; ++policy_class) { - HttpReadyQueue::container_type & c(mState[policy_class].mReadyQueue.get_container()); + State & state(mState[policy_class]); + HttpReadyQueue::container_type & c(state.mReadyQueue.get_container()); // Scan ready queue for requests that match policy for (HttpReadyQueue::container_type::iterator iter(c.begin()); c.end() != iter;) @@ -188,7 +235,7 @@ bool HttpPolicy::changePriority(HttpHandle handle, HttpRequest::priority_t prior HttpOpRequest * op(*cur); c.erase(cur); // All iterators are now invalidated op->mReqPriority = priority; - mState[policy_class].mReadyQueue.push(op); // Re-insert using adapter class + state.mReadyQueue.push(op); // Re-insert using adapter class return true; } } @@ -242,7 +289,7 @@ bool HttpPolicy::stageAfterCompletion(HttpOpRequest * op) int HttpPolicy::getReadyCount(HttpRequest::policy_t policy_class) { - if (policy_class < POLICY_CLASS_LIMIT) // *FIXME: use actual active class count + if (policy_class < mActiveClasses) { return (mState[policy_class].mReadyQueue.size() + mState[policy_class].mRetryQueue.size()); |