Implementing Remote Procedure Calls Andrew Birrell and Bruce
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!n"); return 0; }
What Happens main printf glibc kernel IO kernel update_window X update_display kernel IO kernel
But what if Linux Box X Server Console Window main Laptop X Client
What Happens Laptop Linux Box main printf X Client glibc update_display kernel IO update_window update_display kernel X X kernel IO kernel
How do you do this? • • Fork/Join? Send. Message/Await. Reply? Virtual Shared Memory? Remote Procedure Call?
Remote Procedure Call (RPC)
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 Database RPCRuntime Server Stub Update Database Export Interface Server Export Interface
Binding • Caller binds by specifying the type of the interface in a database query • Selects from a list of instances returned Caller User Stub RPCRuntime Import Interface Query Database Who’s available? Database Interface Info Available Interfaces
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 stuff 1; unsigned char stuff 2[4]; } my_var; my_var. stuff 1 = 0 x 12345678; printf("%X %Xn", my_var. stuff 2[0], my_var. stuff 2[1], my_var. stuff 2[2], my_var. stuff 2[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 Stub RPCRuntime Procedure call Pack arguments Transmit packet(s) Send packet procedure return Unpack result(s) Receive packet Network Callee RPCRuntime Server Stub Server Receive packet(s) Unpack arguments Procedure call Send packet Transmit packet(s) Pack result(s) Procedure return Network
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 Procedure call Transmit first packet Receive ack Call[Ids, packet=0] Ack[Ids, packet=0] Transmit ack Call[Ids, packet=1] Receive packet 1 Retransmit next packet Call[Ids, packet=1, need. Ack] Receive packet 1 Ack[Ids, packet=1] Result[Ids] Transmit result Receive result Result[Ids, need. Ack] Transmit ack request Ack[Ids] Procedure call Transmit ack Receive result Transmit ack Server Receive packet 0 Transmit next packet Receive ack procedure return RPCRuntime Receive ack procedure return
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"
- Slides: 32