Closed laumann closed 9 years ago
I wonder if having a different type for before connect/accept and after would work better.
I considered the same thing, something like
struct SessionSender<P>(Sender<Chan<(), P>>); // Impl accept on this
struct SessionReceiver<P>(Receiver<Chan<(), P>>); // Impl request on this
fn init_session<P: HasDual>() -> (SessionSender<P>, SessionReceiver<P::Dual>) {
let (tx, rx) = channel();
(SessionSender(tx), SessionReceiver(unsafe { transmute(rx) }))
}
But I think the session_channel
function does what we want. The crucial factors seems to be to (a) disallow manual construction of Chan
s and (b) ensure the entry points cannot produce two end-points with incompatible protocol types
Disallowing manual construction of chans is trivially easy with a lint :)
Can it be done now? Its fields are private...
We just want to disallow using the SessionSender()
/SessionReceiver
constructors and accept(..)
, right?
If marking them private will do it I don't mind.
I can write a lint if you just specify what patterns should be disallowed. (What sort of functions, and if you want you can specify specific types which should or should not be fed to them)
AFAIK having private fields disallows manual construction outside the defining crate
Yep.
I think that is enough then. As long as we control how Chan
s are constructed we should be able to ensure protocol consistency. But I wonder if there is another way...
Otherwise we should just remove accept and request? Do we actually need them?
@laumann and I have discussed this a bit. It seems that accept
and request
have their uses. Specifically, one might imagine a case where multiple clients need to be able to establish a session with a single server. Cloning a Sender
to all the clients allows them to accept
a session from the server.
I think #9 will be an adequate fix for this issue.
This just occured to me:
Compiles and fails in our current version:
Arguably it is not using the API "fully correctly", but it still manages to obtain connected session-typed channels with incompatible types