Commit Graph

82 Commits

Author SHA1 Message Date
Aleric Inglewood
67e88561dc Queue/throttle fix.
If AIPerService::add_queued_to fails because a new request is throttled,
then do not add the request to the end of the queue, nor remove it from
the queue: do nothing: it makes no sense to move the request to the back
because they all belong to the same service and all of them will be
either throttled or not.

Note: Still need to fix that in this case we should look in queues of
other services.
2013-05-12 18:10:49 +02:00
Aleric Inglewood
929badb110 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.
2013-05-12 04:19:44 +02:00
Aleric Inglewood
d2af4a3c23 WIP: comment out llasserts.
This way my master isn't totally broken, at least ;).
2013-05-07 23:02:56 +02:00
Aleric Inglewood
5b1984ed0c WIP: Added AIPerService::Approvement 2013-05-07 19:36:10 +02:00
Aleric Inglewood
e3fec7c715 AIPerService improvements.
* Removed the 'RequestQueue' from other PerServiceRequestQueue occurances
  in the code.
* Made wantsMoreHTTPRequestsFor and checkBandwidthUsage threadsafe (by
  grouping the static variables of AIPerService into thread ThreadSafe
  groups.
2013-05-07 16:10:09 +02:00
Aleric Inglewood
84e7f15dc5 Fix initialization list order (compiler warnings) 2013-05-06 03:26:22 +02:00
Aleric Inglewood
1d629438c0 Add HTTP bandwidth throttling for every other responder.
Most notably getMesh (the only one possibly using any significant
bandwidth), but in general every type of requests that just have to
happen anyway and in the order they are requested: they are just passed
to the curl thread, but now the curl thread will queue them and hold
back if the (general) service they use is loaded too heavily.
2013-05-06 02:54:10 +02:00
Aleric Inglewood
75a45f501e Moved a part of AIPerService::wantsMoreHTTPRequestsFor to a new function.
The new function is AIPerService::checkBandwidthUsage.
No functional changes were made.
2013-05-06 02:54:10 +02:00
Aleric Inglewood
fd3e8e4a23 Preparation for AIPerService::checkBandwidthUsage.
Don't pass arguments to wantsMoreHTTPRequestsFor, but use globals in
llmessage: AIPerService::sHTTPThrottleBandwidth125 and
AIPerService::sNoHTTPBandwidthThrottling instead.

This is needed later on.
2013-05-06 02:54:03 +02:00
Aleric Inglewood
32a5494c79 Limit sMaxPipelinedRequests changes to once per 40ms, plus code clean up.
Mostly renaming stuff and moving static variables to class AIPerSerive.
2013-05-04 20:02:21 +02:00
Aleric Inglewood
873b61c39d Fix comment. 2013-04-30 22:16:29 +02:00
Aleric Inglewood
ebfb76c284 Renamed AIPerServiceRequestQueue[Ptr] to AIPerService[Ptr]
This because AIPerService now contains a lot more than just the request
queue.
2013-04-26 19:20:10 +02:00
Aleric Inglewood
6c1335af50 Moved connect limits per service to AIPerServiceRequestQueue.
Added AIPerServiceRequestQueue::mConcurrectConnections and
AIPerServiceRequestQueue::mMaxPipelinedRequests.
2013-04-26 19:13:18 +02:00
Aleric Inglewood
304e2b4958 Pass LLControlGroup* to AICurlInterface::startCurlThread instead of each Debug Setting separately. 2013-04-26 16:47:22 +02:00
Aleric Inglewood
45e6b7975f First version of HTTP bandwidth throttling.
Adds throttling based on on average bandwidth usage per HTTP service.
Since only HTTP textures are using this, they are still starved by other
services like inventory and mesh dowloads. Also, it will be needed to
move the maximum number of connections per service the to the PerService
class, and dynamically tune them: reducing the number of connections is
the first thing to do when using too much bandwidth.

I also added a graph for HTTP texture bandwidth to the stats floater.
For some reason the average bandwidth (over 1 second) look almost like
scattered noise... weird for something that is averaged...
2013-04-24 22:04:21 +02:00
Latif Khalifa
f1ce3c89c3 Silence warnings 2013-04-23 12:57:02 +02:00
Aleric Inglewood
734d2e658d Rename HTTPTimeout::sClockCount (in clock ticks) to sTime_10ms (in 10ms units).
Note that HTTPTimeout::sClockWidth is no longer used for HTTPTimeout (as
if it's value became a constant of 0.01, the fraction 10ms / 1s).
A new variable, HTTPTimeout::sClockWidth_10ms is used to calculate
sTime_10ms (only).

Also HTTPTimeout::mStalled and HTTPTimeout::mLowSpeedClock changed units
to the same as of sTime_10ms (time since epoch in 10ms units).
2013-04-09 22:27:23 +02:00
Aleric Inglewood
fce106f7e2 PerHost became PerService
Reflect the fact that we include port number in its name.
2013-04-09 05:06:32 +02:00
Aleric Inglewood
29a1d0e4e1 Renamed aicurlperhost.{cpp,h} --> aicurlperservice.{cpp,h}
Next commit will rename everything else.
2013-04-09 04:40:47 +02:00
Aleric Inglewood
3af89dd685 Temporarily add old bandwidth throttle method back. 2013-04-09 04:25:28 +02:00
Aleric Inglewood
748d339ee6 Move decision whether or not to add new HTTP request from texture fetcher to AICurl
After commit things compile again :).
The HTTP bandwidth throttling is not yet implemented. I'll put a
temporary fix back the next commit that just does it the "old way"...
2013-04-08 22:46:01 +02:00
Aleric Inglewood
79bcb1ec07 Print info in texture console about curl request queuing
This includes also non-texture requests (not sure if it's worth it to
explicitely separate this data for just textures).

The texture console now prints: HTTP:c/q/a/r
Where, c = number of 'add' request commands in the command queue
(minus the number of 'remove' request in the command queue and not
taking into account the command_being_processed, nor entirely being
thread-safe with regard to adding requests to 'q' or 'a' next: it is
possible that a request is no longer counted in 'c' but not yet is added
to 'q' or 'a'.
q = number of queued (throttled) requests (by the curl thread).
a = number of actually added requests (to the multi handle).
r = last returned value of 'running handles' by libcurl.

Obviously, c and q should be small (0 or 1) most of the time and a and r
should be equal and maxed out. This turns out to be the case.
2013-04-08 06:41:07 +02:00
Aleric Inglewood
c20e33c7f4 Added AIPerHostRequestQueue::queued_commands()
Returns the number of add commands minus the number of remove commands
in the command_queue for this host.
2013-04-08 06:41:07 +02:00
Aleric Inglewood
7866c68ab2 Moved PerHostRequestQueue[Ptr] outside of AICurlPrivate.
Renamed PerHostRequestQueue and PerHostRequestQueuePtr to
AIPerHostRequestQueue and AIPerHostRequestQueuePtr respectively and
moved them to global namespace. This in preparation for using them in
the texture fetcher (as function of the hostname of the url that is
contructed there).
2013-04-08 06:41:07 +02:00
Aleric Inglewood
db7c378160 Added MultiHandle::sTotalAdded
This new variable is updated to contain the total number of requests in
MultiHandle::mAddedEasyRequests. It can be a static because MultiHandle
is a singleton (there is only one curl thread) and it has to be an
(atomic) static because we don't want to need to take the lock on
MultiHandle for accessing this variable.
2013-04-08 06:40:48 +02:00
Aleric Inglewood
f58bc148ba Add a 'size' to command_queue.
This adds a size (command_queue_st::size) to the ThreadSafe deque<Command> that was
AICurlPrivate::command_queue that is kept equal to the number of 'add'
commands in the deque minus the number of 'remove' commands in the
deque. The deque itself is now command_queue_st::commands.
2013-04-08 06:39:51 +02:00
Aleric Inglewood
07201a5cfe Add AICurlInterface::getNumHTTPRunning
Replaces LLTextureFetch::getNumHTTPRequests.
Returns AICurlInterface::Stats::running_handles.
This is work in progress that temporarily doesn't compile because
LLTextureFetch::getNumHTTPRequests is still being used somewhere.
2013-04-08 06:39:06 +02:00
Aleric Inglewood
b20886a481 Allow TOS redirect. Fix upload finished detection when redirecting.
This fixes https://code.google.com/p/singularity-viewer/issues/detail?id=705

Adds 'bool redirect_status_ok(void) const { return true; }' to LLIamHere,
because it's ok to receive a 302 status there. Likewise added to LLIamHereVoice,
because that has the same comment in its error() method.

Also fixes the problem that if two redirects occur on a row, then the
upload_finished detection asserted because it would detect the third
time that libcurl turned off writing to the socket as a failure (the
second time wasn't a problem because mUploadFinished was reset upon
receiving the first 302 header, but not upon receiving the second
header).
2013-03-25 04:41:07 +01:00
Aleric Inglewood
835240fda1 Fix crash in LLTextureFetch::getWorker upon viewer exit.
This is now necessary since the curl thread no longer syncs with the
main thread: it is possible that a request finishes after a texture
fetch thread was shot down but before curl was stopped, and curl
calling BufferedCurlEasyRequest::processOutput while objects that the
responder uses were already destructed (most notably
LLTextureFetch itself).
2013-03-21 20:26:01 +01:00
Aleric Inglewood
5a8308109b Lowered CurlTimeoutLowSpeedLimit from 56 kB/s to 7 kB/s.
This value really IS in bytes/s (not for the total), and apparently 56
kB/s is too optimistic. The value was used by LL for transfers that went
beyond the total download time (2 minutes?), adding enough seconds per
received bytes to the timeout to allow a download at 56 kB/s to finish.

Our meaning is different however: we time out immediately and whenever
the download drops below this speed.

Perhaps a better algorithm is where the speed demand is based on the
total size of the download, but I'm not sure we always know the size of
downloads at this point.
2013-03-10 17:45:39 +01:00
Aleric Inglewood
7dfef31469 Possible upload timeout improvement.
When uploading finishes, but is not detected, the timeout should be for
"reply delay", the time that the server takes before it replies, and not
CurlTimeoutLowSpeedTime. This patch adds code that takes this failure
into account (which happened only ONCE for me on Metropolis while flying
around and using trickle (not sure if that is relevant), so it's not
that likely to improvement anything in practise. Note that it is
detected by an assertion when it happens, so that we can safely assume
it normally never happened on SL).

* Generalized PUT / POST configuration by adding
  CurlEasyRequest::setPut, which now also supports keep-alive (which
  still isn't used).
* Upload content length is now stored in CurlEasyRequest::mContentLength
* CurlEasyRequest::has_stalled() now return false if it was possbile
  that the 'upload finished' detect failed AND calls upload_finished()
  itself in that case, so it is no longer 'const'.
* If low speed is detect exactly when the last bytes are being attempted
  to be sent (unlikely scenario), then the upload gets 4 more seconds
  after which is switches to CurlTimeoutReplyDelay.
* Added EDoesAuthentication and EAllowCompressedReply to replace
  booleans, for readability and type-safety, as did EKeepAlive. Note
  that this change inverts the meaning of the compression related parameter.
* Unrelated: removed an unnecessary #include "llurlrequest.h" from
  llxmlrpcresponder.h
2013-03-10 16:43:15 +01:00
Aleric Inglewood
96d302aa42 Be more verbose about internal (curl / timeout) errors.
Translates the CURLE_WRITE_ERROR into what it really means: that the low
speed check failed.
2013-03-09 05:26:52 +01:00
Aleric Inglewood
13e032fb04 Make AICurlThread::wakeup_thread thread-safe. 2013-02-23 23:29:43 +01:00
Aleric Inglewood
803e92020b Renamed AICurlThread::mWakeUpMutex --> AICurlThread::mWakeUpFlagMutex 2013-02-23 23:23:48 +01:00
Aleric Inglewood
83fb898852 Bug fix: Wake up curl thread at exit of viewer. 2013-02-03 17:24:26 +01:00
Aleric Inglewood
fc4b02cee8 Moved HTTPTimeout to it's own files. 2013-01-12 23:00:21 +01:00
Aleric Inglewood
e56f14502e Fill fd_sets AFTER processing command queue. 2013-01-12 02:51:44 +01:00
Aleric Inglewood
741a160913 Fine tune of private (libcwd) assertion.
It turns out that it's possible to receive data before an upload
finished when the server sends HTTP_BAD_REQUEST in the middle of the
upload (this happens to me when I try to upload a 6000x6000 image to my
profile feed, with is a 44MB file). So, in that case the finished upload
detection did not fail and we shouldn't assert.
2013-01-11 01:28:46 +01:00
Aleric Inglewood
63ae33eca7 Fix crash in AICurlPrivate::curlthread::PollSet::next
Introduced in
6dcda3595e
(Add recovery for randomly closed socket desciptors.)

By copying CurlSocketInfo* into mCopiedFileDescriptors, it was possible
that we accessed a deleted CurlSocketInfo for it's filedescriptor,
returning a random value, which, when passed to FD_ISSET could cause a
SIGSEGV.

I reverted this change and now store the literal socket descriptors in
mCopiedFileDescriptors again. It is not a problem when libcurl deletes
the corresponding CurlSocketInfo (through a callback to
MultiHandle::socket_callback) in that case, because the fd_set we test
against isn't updated as a result of that, not until we're down with
mCopiedFileDescriptors (at the re-entry of select()).
2013-01-08 23:43:25 +01:00
Aleric Inglewood
5188693469 Compile fix for last commit and Release 2013-01-08 20:33:29 +01:00
Aleric Inglewood
d8485350e7 Address clang warnings.
* Split off AIThreadSafeBitsPOD, because offsetof may only be used on POD types.
* Added ASSERT_ONLY and ASSERT_ONLY_COMMA
* Removed a few unused class members
* Fixed a bug in AIHTTPReceivedHeaders::equal that more or less only
  compared the length of the headers before :/
2013-01-08 17:50:09 +01:00
Aleric Inglewood
639b264d2d Do not crash upon corrupted HTTP header.
This addresses the reported assertion by luis thibodeaux.
2013-01-03 21:06:20 +01:00
Aleric Inglewood
6dcda3595e Add recovery for randomly closed socket desciptors.
Although it should never happen that a file descriptor is suddenly
closed, it appeared that this happens on linux 64bit when using
FMODex... Not really sure how useful this is, but at least now the
viewer just continues to work, as if -say- the socket was closed
remotely. Before the curl thread would go into a tight loop that it
wouldn't recover from until the watchdog thread terminated the viewer.
2012-12-31 19:24:37 +01:00
Aleric Inglewood
2f3841d7e6 Update of print_diagnostics.
CURLE_COULDNT_CONNECT only happens when we actually get
an error (ie, 'connection refused'). If we time out while the connect
attempt is still running then we get CURLE_OPERATION_TIMEDOUT.
2012-12-30 21:11:10 +01:00
Aleric Inglewood
6a45e68c73 Merge branch 'master' into llwebprofile 2012-12-29 17:03:46 +01:00
Aleric Inglewood
88bf01fe6f Avoid crashing at exit by joining the curl thread. 2012-12-28 16:59:04 +01:00
Aleric Inglewood
fac3fc67b6 Add filtering for curl debug output.
Add CURLTR debug channel for libcurl API calls,
and use CURLIO only for libcurl debug output.
Note: need to set gDebugCurlTerse to true for
filtering to take effect, then pass 'debug_on'
to the LLHttpClient methods that require debugging.
2012-12-24 02:54:36 +01:00
Aleric Inglewood
8095d6c48c Large snapshot update (part 3) 2012-12-22 19:07:08 +01:00
Aleric Inglewood
12171f6cd9 Merge commit '5947769812369a7988a7f1db30df79e6fc0e4787'
Adds important commits from llwebprofile branch
into master which need to go into the next release.
2012-12-05 22:27:21 +01:00
Aleric Inglewood
e788ee5faf Merge branch 'master' into llwebprofile 2012-11-28 18:50:31 +01:00