Click here to load reader
Date post: | 10-Nov-2014 |
Category: |
Documents |
Upload: | omesh-dhanushka |
View: | 17 times |
Download: | 5 times |
Click here to load reader
Remote Procedure Call
Andrew Whitaker
CSE451
Remote Procedure Call
RPC exposes a programming interface across machines:
interface PriceService { float getPrice(ASIN uniqueID);}
Client Server
PriceImpl
RPCSystem
Caller
RPCSystem
getPrice
461 in two slides
Network software is arranged in layers
Higher layers offer more convenient programming abstractions TCP provides in-order,
reliable delivery of a byte stream
Application (HTTP, FTP)
Transport (TCP, UDP)
Network (IP)
Link (Ethernet, 802.11)
What TCP Does (Not) Provide
TCP allows one machine to send a reliable byte stream to another machine: Socket.send(byte[] byteBuffer);
TCP does not provide: Mapping to/from programming language types
Called “marshalling” Thread management Intelligent failure semantics Discovery
RCP packages build on TCP (or sometimes UDP) to provide these services
What Uses RPC?
Web services Allow arbitrary clients and servers to
communicate using XML-based exchange formats
Distributed file systems e.g., NFS (network file system)
Multiplayer network gamesMany other distributed systems
RPC at 10,000 feet
The key to an RPC system is its Interface Definition Language (IDL) An interface provides the contract between
clients and servers
Given an interface, an RPC compiler generates RPC “stubs” Which abstract away the network
RPC Visualized
interface PriceService { float getPrice(ASIN uniqueID);}
Client Server
PriceImpl
ServerStub
Caller
ClientStub
RPC Compiler
RPC stubs
The client program thinks it’s invoking the server But, it’s really calling the client-side stub
The server program thinks it’s called by the client But it’s really called by the server-side stub
The stubs send messages to each other to make the RPC happen transparently
RPC Example: An Add() ServiceClient Program:
…sum = server->Add(3,4);…
Server Program:
int Add(int x, int y) { return x + y;}
client-side stub:
int Add(int x, int y) { alloc message buffer; mark as “add” call; store x,y in buffer; send message; receive response; unpack response; return response;}
RPC runtime system:
send message to server;receive response;
server-side stub:
Message Add_Stub(Message m) { remove x,y from m; r = Add(x,y); allocate response buffer; store r in response; return response;}
RPC runtime system:
receive message m;response = Add_Stub(m);send response to client;
IDL Example #1: Java RMI
Interface definition language is Java itself
interface PriceServices extends Remote { Price getPrice(ASIN uniqueID) throws RemoteException;}
IDL Example #2: CORBA IDL
module BankSimple{ struct CustomerDetails { string name; short age; };
interface Bank { CustomerDetails getCustomerDetails (in string name); };};
Note: compound typesmust be explicitly defined
IDL Example #3: WSDL????
<?xml version="1.0"?><!-- root element wsdl:definitions defines set of related services --><definitions name="StockQuote" targetNamespace="http://example.com/stockquote.wsdl" xmlns:tns=http://example.com/stockquote.wsdl xmlns:xsd1=http://example.com/stockquote.xsd xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> <!-- wsdl:types encapsulates schema definitions of communication types; here using xsd --> <wsdl:types> <!-- all type declarations are in a chunk of xsd --> <xsd:schema targetNamespace=http://example.com/stockquote.xsd xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"> <!-- xsd definition: TradePriceRequest [... tickerSymbol string ...] --> <xsd:element name="TradePriceRequest"> <xsd:complexType> <xsd:all> <xsd:element name="tickerSymbol" type="string"/> </xsd:all> </xsd:complexType> </xsd:element> <!-- xsd definition: TradePrice [... price float ...] --> <xsd:element name="TradePrice"> xsd:<complexType> <xsd:all> <xsd:element name="price" type="float"/> </xsd:all> </xsd:complexType> </xsd:element> </xsd:schema> </wsdl:types> <!-- request GetLastTradePriceInput is of type TradePriceRequest --> <wsdl:message name="GetLastTradePriceInput"> <wsdl:part name="body" element="xsd1:TradePriceRequest"/> </wsdl:message> <!-- request GetLastTradePriceOutput is of type TradePrice --> <wsdl:message name="GetLastTradePriceOutput"> <wsdl:part name="body" element="xsd1:TradePrice"/>
Design Issues in RPC
Transparency: to be or not to be?Marshalling and unmarshalling
Converting types to byte streams
Discovery and namingVersioning
Transparency
General distributed systems issue: does a remote service look identical to a local service
Transparency allows programmers to ignore the network
But, transparency can impose poor performance and complexity
In practice File systems try for transparency RPC systems do not
A Java RMI Example
interface FileStream extends Remote { // read from a (possibly) remote file into a buffer int read (byte[] buffer, int offset, int howManyBytes)
throws RemoteException;}
This doesn’t work! Java RMI is call-by-value
Revised Java RMI Example
interface FileStream extends Remote { // read from a (possibly) remote file into a buffer byte[] read (int howManyBytes)
throws RemoteException;}
Data Marshalling
Marshalling is the task of converting programming language types into a byte stream Unmarshalling is the reverse
This is boring, but potentially complex How many bits are in an integer? How are floating point numbers represented? Is the architecture big-endian or little-endian?
Complex Types
Object-oriented languages allow programmer-defined types
Two basic strategies: Push the type definition into the IDL (CORBA) Add implicit support to the language
Java Serialization
Java Serialization
public class Person implements Serializable { private int age; private String name; private float salary; private transient boolean gender;}
transient turns off serialization
Instances of Serializable can automatically converted into a byte stream Thus, RMI allows serializable arguments
Discovery and Lookup
Clients must locate a remote object or service