Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Consume body without allocating or reading #335

Merged
merged 6 commits into from
Nov 16, 2015

Conversation

benaadams
Copy link
Contributor

Resolves #334

@benaadams benaadams force-pushed the used-pool-array branch 10 times, most recently from 08f774c to c4d2b74 Compare November 11, 2015 01:05
@benaadams benaadams changed the title Use pooled array Use pooled arrays Nov 11, 2015
@benaadams benaadams force-pushed the used-pool-array branch 2 times, most recently from 34b5fc3 to 79c4a42 Compare November 13, 2015 20:04
@davidfowl
Copy link
Member

This needs to be implemented in a non allocating way.

@benaadams
Copy link
Contributor Author

Not sure I understand, it only allocates if the header name > 4032 bytes so it shouldn't ever allocate?

@benaadams
Copy link
Contributor Author

Skip rather than Read

@benaadams benaadams changed the title Use pooled arrays Don't alloc header names, or consuming body Nov 14, 2015
@@ -566,7 +566,7 @@ public string GetString(MemoryPoolIterator2 end)
}
}

public ArraySegment<byte> GetArraySegment(MemoryPoolIterator2 end)
public ArraySegment<byte> GetArraySegment(MemoryPoolIterator2 end, ArraySegment<byte> scratchBuffer)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems unrelated

@benaadams benaadams changed the title Don't alloc header names, or consuming body Consume body without allocating or reading Nov 15, 2015
@benaadams
Copy link
Contributor Author

Moved unrelated to #390 and #391

@benaadams
Copy link
Contributor Author

@davidfowl does the last commit sort out your code reuse concerns?

@davidfowl
Copy link
Member

@benaadams Yes, exactly what I had in mind (except the 100 continue changes)

var firstLoop = true;
do
{
result = ReadAsyncImplementation(default(ArraySegment<byte>), cancellationToken);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not await here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was copying the function above. Following the logic of that function; the task hasn't completed because no data; check whether their is no data because the client is waiting for a 100 continue else the await will block infinitely as it waiting for data that's dependent on a send; if so do the send and return the incomplete task?

Since we are doing the full loop here; if we pass over that condition; we know the task has already completed. If the result is 0 then return as everything is done; otherwise move to next loop, no point in checking twice with the await for a condition we already know. Therefore we only await if the task is not complete.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also Interlocked is much more expensive than a local var and only one 100 continue is sent, so only check it once, as we know the results for every loop after that. Though firstLoop is probably the wrong name.

@davidfowl
Copy link
Member

/cc @rynowak @halter73

@@ -85,7 +85,7 @@ public override void Flush()

private Task<int> ReadAsync(ArraySegment<byte> buffer)
{
return _input.ReadAsync(buffer);
return _input.ReadAsync(buffer.Array, buffer.Offset, buffer.Count);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth just overloading this on SocketInput? Notice a bunch of other methods here create an array segment to call this method.

At least least, you could clean all of those up to avoid creating the ArraySegment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't create an ArraySegement with a null buffer + specified length or it will throw an exception.

However a consumption limit needs to be passed through to CopyTo else it will consume the whole input rather than just the input related to the current request. Is a bit of abstraction leakiness to make the code reusable; rather than copy paste repeated...

davidfowl added a commit that referenced this pull request Nov 16, 2015
Consume body without allocating or reading
@davidfowl davidfowl merged commit e3a62ff into aspnet:dev Nov 16, 2015
@benaadams benaadams deleted the used-pool-array branch November 16, 2015 19:48
@rynowak
Copy link
Member

rynowak commented Nov 16, 2015

🎆

benaadams added a commit to benaadams/KestrelHttpServer that referenced this pull request Nov 20, 2015
Was meant to be removed as part of aspnet#335

/cc @rynowak
@benaadams benaadams mentioned this pull request Nov 20, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants