Bit of a necro, but I'm doing something similar but ran into a few issues and am looking for advice.

In my case I'm proxying two connections as above, but both come in from listen sockets and thus have their own fibers. It would seem natural to use the two fibers for the two proxying directions, but I'm not sure how to most cleanly get the TCPConnection objects passed between the two.

I've tried to simply "send" one connection object across but of course that complains about mutable aliasing... which is exactly what I want in this case since there's no way for the language to know at compile time that what I'm doing is safe (i.e. only writing in one fiber, only reading in another). Making the TCPConnection "shared" causes other issues as most of the functionality doesn't work. This is yet another case where I don't even want parallelism (i.e. threading), just coroutines and the attempts to enforce "safety" are tiresome. It's a bit silly that the above example has exactly the same "sharing issue" but apparently it's all good since it's shared on the stack/closure vs. "sent" to another fiber.

I also tried simply having one of the fibers store its TCPConnection somewhere and then have the second one just pick it up as per the code segment above. The problem is, if you allow the first fiber to return/terminate, vibe closes/reuses the TCPConnection... thus you need to have the fiber sit there sleeping just to avoid falling through to the cleanup code which - while it does work - is hardly elegant.

The second part of the issue is that I need clean termination if one of the peers disconnects. My plan for this was for each of the two fibers to .interrupt the other and let each close their own sockets. However one needs to be a bit careful because closing a socket involves it taking both a reader and writer lock, so indeed you need both the fibers to sync out of the proxy loop before either returns. The above code can just do the cleanup after the join of course, but I'm not sure how to handle this with two fibers launched from listen sockets... other than somehow breaking the TCPConnection away from one and letting it terminate with the connection still alive, but unowned.

Thanks in advance for any advice!

[As an aside, I find the whole D concurrency design to be awkward and not really that helpful at avoiding errors (and I say that as someone who spends a significant amount of time doing parallel programming for work). I get the idea and know that people mean well, but I just don't think it helps to avoiding many non-trivial data races and it requires legitimate race-free code to bypass the illusion of "safety" frequently. But that's a rant for another day I guess :)]