4

I have a files controller that is responsible for handling uploaded files in chunks (1 MB chunks). I took my time testing this in development and everything is as expected. The following is the pseudo code of an action:

logger.Log("Getting InputStream");
var stream = Request.InputStream; // Here is the wait.
logger.Log("Got InputStream");
var bytes = GetByteArray(stream); // This is always less than 1 MB.
await FilesService.AppendToFileAsync(key, fileName, owner, bytes); // Write to the file.

// The GetByteArray method
private byte[] GetByteArray(Stream stream)
{
    var bytes = new byte[stream.Length];
    stream.Read(bytes, 0, bytes.Length);
    return bytes;
}

The specifics aren't terribly important. I'm getting the bytes then I'm appending them to the file on disk.

In production however, things get weird. This is the request timeline of one chunk being uploaded (in production): The request timeline

By means of logging I absolutely know that all the waiting time is being spent in the Request.InputStream prop.

The waiting time is somewhere between 1 min - 3 mins.

My Question

  • Does this mean the server is just taking that much time downloading the request? (though I really doubt that)
  • Or is it that I'm doing something wrong here?

And a small question: is the Request sent timeline telling me when the content bytes are done being received on the other side?

I know that perhaps I should write a file upload handler or something, but does that really make that much of a difference?

So, what's going on?

EDIT:

Of course, I looked into a lot of seemingly related issues but nothing hit the mark.

  • I firstly suspected that the appdomain was being recycled on every chunk request (because I'm writing to a file) but I confirmed that this not the case from the logs. Also it wouldn't make any sense since the wait is on Request.InputStream.

EDIT 2:

I just tested with GetBufferlessInputStream with manual reading inside the same action and the result is the same. Now I'm sure the wait is while reading the request stream. At this point, I'm getting the feeling that the server is just that slow with getting the request. I contacted my host and they said they don't put a limit on the speed and it shouldn't be slow.

To confirm this, this is one of my logs while a chunk was being uploaded:

2015-09-15 23:23:12.6419|Entered upload chunk // This is the action.
2015-09-15 23:23:12.6419|Got bufferless stream // var s = Request.GetBufferlessStream()
2015-09-15 23:23:12.6419|Stream length: 1048576 (1 MB) // s.Length
2015-09-15 23:23:12.6419|Reading stream... // Here is the wait, this time it was not much (~26 secs) but it's still a lot.
2015-09-15 23:23:38.8211|Read stream of size 1048576 bytes (1 MB)

and this is how I'm reading it:

var b = new byte[s.Length];
var read = 0;
var c = 0;
while ((c = s.Read(b, read, b.Length - read)) != 0)
{
    read += c;
}
mrahhal
  • 3,322
  • 1
  • 22
  • 41
  • Is there anything else going on with your network? Virus scanning or something else that would make this an external issue (not related directly to your code)? – Igor Sep 15 '15 at 19:00
  • @Igor I kept testing this issue for more than a couple of days and it doesn't seem to be temporary. Virus scanning and such is sure out of the question since like I said the wait is in aquiring `Request.InputStream` all the time. – mrahhal Sep 15 '15 at 19:03
  • The only remaining thing I could think of is that I'm doing it completely wrong. Perhaps the combination of small chunked uploads and `InputStream` is doing it. – mrahhal Sep 15 '15 at 19:06
  • @Igor I'm 100% sure the problem is not in the IO portion. As I said, through logging I confirmed that the wait is entirely in the `Request.InputStream`. Also please check the edit. – mrahhal Sep 15 '15 at 19:10
  • After some searching I can't come up with anything else so I think it might still be useful to see what you are doing with Request.InputStream inside of your GetByteArray method. Could you post the body of your GetByteArray method? – Igor Sep 15 '15 at 19:52
  • @Igor I found absolutely nothing about this also, this is super weird. Check the edited code please. – mrahhal Sep 15 '15 at 19:57
  • I've been thinking that maybe `InputStream` is not for handling big requests (>~1MB) because it buffers them. Maybe I should make an http handler and use `Request.GetBufferlessInputStream` though I'm just speculating. Even if so, it shouldn't take that much of a hit. – mrahhal Sep 15 '15 at 19:59
  • Does it make any difference if you use ReadAsync on the Stream object and change your method signature to async Task GetByteArrayAsync(Stream stream); ? Also what is the value of stream.Length? – Igor Sep 15 '15 at 19:59
  • @Igor nope. As I said, the wait is during the `get` of `Request.InputStream`. `Stream.Length` is always <= 1MB. Everything else runs super fast. I'm logging every corner and how much everything is taking. – mrahhal Sep 15 '15 at 20:02
  • So the initial call to Request.InputStream is the culprit? Can you duplicate that by doing var myTestStr = Request.InputStream; (which should be slow) and then pass that into your method which should then be fast again? – Igor Sep 15 '15 at 20:03
  • I did exactly that and yes, the initial call is the culprit. All other calls to `InputStream` are as fast as they can get (it should be so since all the content is being read on the first call). – mrahhal Sep 15 '15 at 20:05
  • @Igor please check **EDIT 2**. – mrahhal Sep 16 '15 at 06:37
  • I think your earlier suggestion of creating a HttpHandler is a good idea and see if that is also just as slow. Alternatively I am also curious to see what would happen if you create a new controller method that accepts a file to be uploaded via POST and see if that is also slow (something like this http://stackoverflow.com/a/15680783/1260204). At this point I think any test to help point if its a problem in code/configuration or is it a problem with your provider. – Igor Sep 16 '15 at 08:12
  • @Igor I did a normal upload as you're suggesting (just a plain old form with a file input that uploads a small file of 3 MB) and the problem persists. This makes my point about the server being just slow stronger. I think creating and testing with an HttpHandler is sure to confirm our suspicion. I'll do that when I have the time but for now I'm putting this on hold to continue development normally, also because no one seems to be facing the same issue. Thanks. – mrahhal Sep 16 '15 at 08:17

1 Answers1

1

You should change the plan , there are tons of sites on that server Get enrolled in an advanced plan to increase your download speed

Ibra Him
  • 155
  • 1
  • 2
  • 10