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

SocketOutput exception completes all waiting tasks#567

Merged
halter73 merged 7 commits into
aspnet:devfrom
benaadams:socket-error
Jan 27, 2016
Merged

SocketOutput exception completes all waiting tasks#567
halter73 merged 7 commits into
aspnet:devfrom
benaadams:socket-error

Conversation

@benaadams
Copy link
Copy Markdown
Contributor

Lightens #565
Resolves #450
Resolves #566

@benaadams
Copy link
Copy Markdown
Contributor Author

Confirmed this resolves the issue we were experiencing with Ssl (forced sync) and high connection churn; while triggering pending tasks (> maxBytesPreCompleted, websocket streaming) .

Essentially thrashing the server with our worse case situation.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for doing this. I agree with this approach. This is type of change is what @rynowak and I were considering when he filed the issues at the end of last week.

I think we also want to fail all pending tasks if OnWriteCompleted is called after a SocketDisconnect just to be safe.

Another consideration is how this is going to interact with the per-request IgnoreWriteExceptions property we are likely to add. We still haven't decided whether or not it will be opt in or out, but I'm personally leaning toward opt-in.

This PR also conflicts a little with #562 so one of us is going to have to rebase depending on the order these get in (and we know who controls that 😛). Seriously though, I'm going to try to merge #562 today and the rebase shouldn't be too difficult.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

so one of us is going to have to rebase depending on the order these get in (and we know who controls that 😛

😆

Another consideration is how this is going to interact with the per-request IgnoreWriteExceptions property we are likely to add.

Isn't too hard; though would be an issue if someone was streaming something large but the client had disconnected as if they weren't listening for it they'd just keep writing to null?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We decided not to add an IgnoreWriteExceptions property. We will never throw from SocketOutput.WriteAsync. FrameResponseStream will be modified to honor the CancellationToken that is passed in for async writes.

If you want the IgnoreWriteExceptions = false behavior you will always pass in the IHttpRequestLifetimeFeature.RequestAborted token to your writes. If FrameResponseStream ever throws due to a canceled token it will abort the connection.

We will also plan to log all write failures using LogLevel.Debug correlated with the connection id. The connection id will be made accessible from user code via a new IHttpConnectionFeature.ConnectionId property.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

What about lines new lines 86-89 ---^

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Are you talking about if (_lastWriteError != null) throw ...? If so, we'd remove that and just ignore the write while returning a completed task.

@benaadams
Copy link
Copy Markdown
Contributor Author

Going to roll this into #485; if that works for you?

@benaadams benaadams closed this Jan 12, 2016
@halter73
Copy link
Copy Markdown
Member

That will probably fine. We definitely appreciate the work. Try to separate the changes related to #566 (comment) into their own commit if you can.

@benaadams
Copy link
Copy Markdown
Contributor Author

Will split into 2 commits when I know the shape of it

@benaadams
Copy link
Copy Markdown
Contributor Author

Reopening. Need to sort out a new test

@benaadams
Copy link
Copy Markdown
Contributor Author

@halter73 Added test, probably could do with some comments - but otherwise seem ok?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: add new line before method

@benaadams
Copy link
Copy Markdown
Contributor Author

Made behaviour same between frameworks and added comments to new test

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Should return cancelled task rather than throwing TaskCanceledException?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't think we should swallow this error. I think there is a chance that exceptions from callbacks registered with the token will bubble up through this call. I would probably use KestrelTrace.ApplicationError.

@benaadams benaadams force-pushed the socket-error branch 2 times, most recently from ca11bce to 74626a1 Compare January 22, 2016 01:22
@benaadams
Copy link
Copy Markdown
Contributor Author

Need to run through this again in morning; though I just think need a fake connection for tests to remove ? in _connection?.Abort();

@benaadams benaadams force-pushed the socket-error branch 2 times, most recently from 76c2fa8 to 22934a4 Compare January 22, 2016 14:18
@benaadams
Copy link
Copy Markdown
Contributor Author

@halter73 should be there? Issues with CI on Github though (libuv copy)

@halter73
Copy link
Copy Markdown
Member

@CesarBS should have a fix for the libuv copy issue. He discovered the issue is that the Libuv-Copier is looking for libuv in ~/.dnx/packages instead of the now used ~/.nuget/packages directory.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It seems to me that this is only getting called if the user passes in a canceled token, but that's only one scenario where this is getting called.

We need to complete all writes whenever there is an error, even if we don't wind up cancelling them.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Hmm... let me run through the logic again

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed, though I have it Completing written ones first on Error, then doing the others. Probably should just do all regardless of counts? Also reworded the commits

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I have it Completing written ones first on Error, then doing the others

This has no functional impact vs completing all the writes at once on error, right? If so, that's fine, as long as the code stays simple.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

No, but it looks a bit weird. Let me change it since the CI is failing anyway.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Resolved, was just a case of moving one line of code - looks better now

@benaadams
Copy link
Copy Markdown
Contributor Author

libuv copy grumpy

@benaadams benaadams force-pushed the socket-error branch 2 times, most recently from a1ad405 to 49fb5aa Compare January 22, 2016 19:23
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Note to self: We should add a test where a bunch of pending writes that get completed b/c of a failed write instead of a canceled token before merging.

I can do this myself since this will require some small modifications to MockLibuv (I know _uv_err_name and _uv_strerror will need to be implemented.)

There's also a pretty big chance that we might need to merge a more limited version of this PR that only ensures writes always get completed, and merge the CancellationToken related chances post-RC2.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Pre-newer CancellationToken changes, needs to only throw if given CancellationToken is cancelled otherwise it should return null.

@benaadams
Copy link
Copy Markdown
Contributor Author

Linked #599

@benaadams
Copy link
Copy Markdown
Contributor Author

Rebased

@halter73 halter73 merged commit de34d14 into aspnet:dev Jan 27, 2016
@benaadams benaadams deleted the socket-error branch May 10, 2016 11:05
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.

5 participants