This project has moved. For the latest updates, please go here.

ObservableSocket

Topics: Reactive (Rx)
Jan 16, 2012 at 3:33 AM

Why the decision to use the FromBeginEndPattern for async socket use rather than wrapping the Socket.XyzAsync methods? The latter are far more efficient and reduce overall allocations.

Coordinator
Jan 16, 2012 at 6:19 AM
Edited Jan 16, 2012 at 6:20 AM

Hi,

There are two related questions here.  The first question is: Why doesn't Rxx expose wrappers for the EBAP methods?  The second question is: Why doesn't Rxx use the EBAP methods internally?  I believe both questions can be addressed simultaneously, but if you're not satisfied then please let me know :)

First, here's a related blog post that you've probably already read.  It describes the differences of these models in terms of async/await, which is similar to what we're doing with observables:

http://blogs.msdn.com/b/pfxteam/archive/2011/12/15/10248293.aspx

In a nutshell, Socket offers both implementations (an EBAP variant and the core APM) for a variety of reasons.  We can offer wrappers for both in Rxx, but for now we only offer APM because it fits better with Rxx.  I'll create a new work item and consider wrapping EBAP for a future release.

To elaborate, Rxx is a general-purpose library, so if we're only going to offer one model then it should be the model that is the easiest to consume and will meet the most needs.

  1. Most consumers do not need specialized high-performance sockets (*).  Perhaps the primary indicator of this is simply that a consumer is modeling socket computations using IObservable<T> in the first place.  Of course, just using IObservable<T> itself or the core unsynchronized implementations of Rx aren't necessarily good indicators of this, but certainly using LINQ operators or synchronization of any kind are indicators that the benefits provided by the EBAP methods may very well be micro-optimizations in most applications.
  2. The EBAP variant that is used is uncommon and more difficult to consume.
  3. I had assumed that the EBAP implementation used the current SynchronizationContext for its callback, similar to the other EBAP implementations in the FCL.  It would be a bad idea for a generalized socket wrapper to marshal callbacks onto the UI thread; however, despite my best efforts I can't find any documentation to back this up.  So I just threw together a quick lab to test it and discovered that ConnectAsync actually executes callbacks on a pooled thread even if the call originated from the UI thread.  So it seems that this was a bad assumption, though I haven't tested the other EBAP methods.

I'll consider refactoring our internal implementations to use EBAP instead, but I think points 1 and 2 alone are pretty reasonable to justify leaving it.

*  The MSDN documentation for SocketAsyncEventArgs states the following about the EBAP variant methods:

"The SocketAsyncEventArgs class is part of a set of enhancements to the System.Net.Sockets.Socket class that provide an alternative asynchronous pattern that can be used by specialized high-performance socket applications. This class was specifically designed for network server applications that require high performance."

- Dave

Coordinator
Jan 16, 2012 at 6:22 AM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Jan 16, 2012 at 1:33 PM

Thanks, Dave. I was really just curious. I've been working on the problem and thought you might have tried to tackle it. When I saw you hadn't, I thought I'd ask. I agree that for many the current implementation would work, so don't add this just on my account.

Thanks,

Ryan

Coordinator
Jan 16, 2012 at 4:28 PM

Hi Ryan,

It's worth considering.  If you have any other feedback on how to improve Rxx we'd appreciate it.

- Dave