Runtime Session Types in C# Per Andersson Christian Genne http://www.pean.se/sessiontypes/
Runtime Checking Idea: Generate and check types when parties connect +Problems can be detected in a determinstic way with a single test run + Small (hopefully no) changes to C# - Problems can't be detected at compile time
Session Class User interface implemented in the class Session Sessions are started with Accept or Open Accept and Open takes a delegate that is called twice 1:st call infers session type 2:nd call executes the session User must encapsulate side effects in Session.Do
public class Buyer { public void Run() { Session.Open (sellerHost, sellerPort, delegate( Session s ) { Log( s, "I want to buy " + productid ); s.Send (productid); int price = s.Recv <int>(); s.SendIf (price < maxPrice, delegate() { Log(s, "Fair price, i'm buying! Here is my address."); s.Send (address); DateTime delivdate = s.Recv <DateTime>(); s.Do (delegate() { notifyUser(delivTime); }); }, delegate() { Log(s, price + "? That is to expensive for me."); }); }); } }
public class Seller { public void Run() { Session.Accept (IPAddress.Loopback, port, delegate( Session s ) { String prodId = s.Recv <String>(); int price = 50; Log(s, "So you want to buy " + prodId + ". " + price + " sounds like a nice deal?"); string prodDetails = prodId + " details"; s.Send (price); s.RecvIf (delegate() { Log(s, "Good choice. I'll transfer your request to the shipper"); s.OpenNew ( shipperHost, shipperPort, delegate( Session s2 ) { s2.Send (prodDetails); s2.SendS (s); }); s.Do (delegate() { createOrder(prodid); }); }, delegate() { Log(s, "Yes we are expensive!"); }); }); } void createOrder(String prodid, Address address) { ... } }
public class Shipper { public void Run() { Session.Accept (IPAddress.Loopback, port, delegate( Session s ) { string prodDetails = s.Recv <string>(); Log(s, "So you want me to ship a " + prodDetails + ". Let me talk to the buyer!" ); s.RecvS (delegate( Session s2 ) { Address address = s2.Recv <Address>(); s2.Do (delegate() { Log(s2, "Ok, i've got the address. " + address.mStreet + " " + address.mNr); Log(s2, "I'm creating an order"); }); DateTime delivdate = null; s2.Do (delegate() { delivdate = createShipment(prodDetails, address); }); s2.Send (delivDate); }); }); } DateTime createShipment(String prodid, Address address) { ... } }
Problem 1 – Side Effects The type inference step must not execute side effects like DB transactions A) Create a custom type system for C# with better control on side effects + Safe - Time consuming to implement - May break with new C# version B) Move responsibility to user by using Session.Do - Unsafe + Easy to implement + Just a new method, no C# language changes
Problem 2 – Higher Order Sessions How does Seller know its type when Buyer connects? It depends on Shippers type! A) Type infer Seller-Shipper when type infering Seller-Buyer + Type errors occur at Buyer-Seller connection, or not at all - Shipper IP must be static B) Delay higer order type checking - Type errors becomes runtime errors + No restriction on Shipper IP
User Restrictions All communication through a Session s Encapsulate side effects in s.Do s.Do( delegate() { WriteDB( value ); } ); If-statements must be replaced by s.SendIf and s.RecvIf Other conditional statements are not allowed Only server sessions are allowed to send sessions
Conclusions Session types can be implemented reasonbly well in pure C# Syntax would be nicer with C# 3.0 support for lambda expressions Easy implementation but requires more from the user compared to static type checking Any conditional statement can easily be added to the Session class
Questions?
Recommend
More recommend