-
Notifications
You must be signed in to change notification settings - Fork 523
Simplify SocketInput, remove lock, only use pooled blocks #525
Conversation
Complete(); | ||
} | ||
|
||
public void AbortAwaiting() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: move this back after ConsumingComplete
so there's less impact on the diff.
@CesarBS yes the idea came from something @halter73 pointed out in the SocketOutput
Likewise the In the cross over between the two:
If if (!consumed.IsDefault)
{
returnStart = _head;
returnEnd = consumed.Block;
_head = consumed.Block;
_head.Start = consumed.Index;
} So there isn't really any cross over; with the data so the lock isn't needed. The timing between the |
ac0edce
to
e9b4039
Compare
Rebased so can make another PR based on it |
👍 It does seem very similar to SocketOutput (which shouldn't be to surprising), and I think you're right that the lock was unnecessary. I wouldn't mind a second opinion from @lodejard though. |
I love this PR because I think it'll make my life easier when I get to work on #304 😁 |
Still can't workout why the |
e9b4039
to
cf77efc
Compare
@lodejard is worried about removing the locks, but I think it's safe (assuming there aren't concurrent reads) and there is a nice perf gain. Here are my numbers: dev:
benaadams/socket-input-merged:
benaadams/socket-input-merged-lock (all your changes with the
shalter/socket-input-safe-consume:
I added a small change on top of yours to throw for concurrent non-async reads. This should actually catch potential bugs that weren't caught before. And, as shown above, it doesn't seem too detrimental to perf. At least it's not blocking the libuv thread. @benaadams What do you think? |
Your change is good and is better than the lock, as it works across the ConsumingStart/Complete and will surface bugs in user code - which wasn't covered by the lock. The Interlocked also acts a memory barrier at cpu level (as does lock). It could be argued that's its overly defensive as nowhere is it ever suggested an instance socket read is a threadsafe operation; but its potentially a public port; RTM is approaching - safety first, and more importantly I clearly managed to do it at some point in our application with the way we were using websockets ;) The strong synchronisation is still covered by it having interlocked awaitable states and perhaps overly covered with the addition of the ManualResetEventSlim (async all the things!); however I never saw it show up as an item of interest in perf testing. I'd go with your addition; revisit post RTM if everything gets so fast it starts showing up as an hot spot? |
LGTM (with 7e9dd9e) looking to see if it will trigger exceptions on the issues I experienced earlier in the application lifetime |
Though maybe some tests for the double read ;-) |
In testing I don't trigger overlapped consumes; but have managed to get a confirmation of previous related fix
(e.g. it just closes the connection, doesn't get more upset) |
Also found where it was previously going wrong; in somewhere in my or middlewere handling of websockets close - which is a weird area anyway. |
From #519
Partial #516