320 likes | 463 Views
Implementing Remote Procedure Calls. Andrew Birrell and Bruce Nelson. Slide Set by Phil Howard and others. Why?. Consider. #include <stdio.h> int main() { printf("hello world!<br>"); return 0; }. What Happens. main. main. printf glibc. kernel IO kernel.
E N D
Implementing Remote Procedure Calls Andrew Birrell and Bruce Nelson Slide Set by Phil Howard and others
Consider #include <stdio.h> int main() { printf("hello world!\n"); return 0; }
What Happens main main printf glibc kernel IO kernel update_window X update_display kernel IO kernel
But what if Laptop Linux Box X Client X Server Console Window main
What Happens Laptop Linux Box main main X Client printf glibc update_display X kernel IO kernel kernel IO kernel update_window X update_display
How do you do this? • Fork/Join? • SendMessage/AwaitReply? • Virtual Shared Memory? • Remote Procedure Call?
What's Involved in RPC • Remote Procedure Call should look and feel like local call • Remote Procedure Call should be independent of where it executes • Remote Procedure Call should be "efficient"
Issues • Finding the callee • Passing data • Implementation • Exceptions • Optimizations
Finding the Callee(Binding) • Where - Either server has known static address - Or client broadcasts request - Or use central database of interfaces • What - Servers export named interfaces - Clients request a particular interface - Need Globally Unique Identifiers for interfaces
Interfaces • Type • - Like object oriented programming interfaces • - Method names, parameter and result types • - Underlying functionality is hidden • Instance • - Which specific provider of this type
Binding • Callee exports an interface via a network accessible database. Callee RPCRuntime Server Stub Server Database ExportInterface ExportInterface UpdateDatabase
Binding • Caller binds by specifying the type of the interface in a database query • Selects from a list of instances returned Caller User User Stub RPCRuntime Database Who’s available? ImportInterface ImportInterface QueryDatabase InterfaceInfo InterfaceInfo InterfaceInfo AvailableInterfaces
Issues • Finding the callee • Passing data • Implementation • Exceptions • Optimizations
Passing Data • Can't use the stack! • Can't use shared memory! • Generally use message passing
Passing Data #include <stdio.h> int main() { union { unsigned long stuff1; unsigned char stuff2[4]; } my_var; my_var.stuff1 = 0x12345678; printf("%X %X %X %X\n", my_var.stuff2[0], my_var.stuff2[1], my_var.stuff2[2], my_var.stuff2[3]); return 0; }
Passing Data What's the output? • 12 34 56 78 • or • 78 56 34 12
Passing data Build a message that includes: • Who and what's being called • Identity of the caller • Data values in known byte order • Using an intermediate data representation
Issues • Finding the callee • Passing data • Implementation • Exceptions • Optimizations
Implementation foo(a,&b) foo(int a, int *b) return;
Implementation • foo(int a; int *b) • { • build_msg(a,b); • send_msg(); • wait_for_reply(); • get_from_msg(&b); • } • do_foo(msg_t msg) • { • int a,b; • get_from_msg(&a,&b); • foo(a,&b); • build_msg(b); • send_reply(); • }
Implementation • Function prototype is (almost) all that's needed to build the client stub • Also need binding information • Function prototype is (almost) all that's needed to build server stuff • Also need method to wait for message
Implementation Caller User User Stub RPCRuntime Network Send packet Procedure call Packarguments Transmit packet(s) Unpackresult(s) Receive packet(s) procedure return Receive packet Callee RPCRuntime Server Stub Server Network Receive packet Unpackarguments Procedure call Receivepacket(s) Transmitpacket(s) Packresult(s) Send packet Procedure return
Implementation • Clients • Threaded • Servers • Event Driven
Issues • Finding the callee • Passing data • Implementation • Exceptions • Optimizations
Exceptions • What can happen in "normal" procedures? • Procedure generates an exception • Procedure infinite loops • Procedure generates wrong results
Exceptions • What can happen in "remote" procedures? • Client stub generates exception • Transmission failure • knowable failure • unknowable failure • Remote procedure generates an exception • Remote procedure infinite loops • Remote procedure generates wrong results
Issues • Finding the callee • Passing data • Implementation • Exceptions • Optimizations
Optimizations • Servers maintain no state on clients • No penalty for a large number of clients • Messages must be ack'd • for short calls, result serves as ack • for frequent calls, next call ack's last result • for long requests, only last request message gets ack'd • for long results, only last result message gets ack'd • Bound to "closest" server • Minimum transmission delay
Protocol-Level Optimizations Caller Callee User RPCRuntime Server RPCRuntime Procedure call Call[Ids, packet=0] Receivepacket 0 Transmit first packet Ack[Ids, packet=0] Transmit ack Receive ack Call[Ids, packet=1] Transmit next packet Receivepacket 1 Procedure call Call[Ids, packet=1, needAck] Retransmit next packet Receivepacket 1 Ack[Ids, packet=1] Transmit ack Receive ack Result[Ids] procedure return Receiveresult Transmitresult procedure return Result[Ids, needAck] Receiveresult Transmit ackrequest Ack[Ids] Transmit ack Receive ack
Conclusion • Remote Procedure Call should look and feel like local call • Remote Procedure Call should be independent of where it executes • Remote Procedure Call should be "efficient"