1 / 14

RPC example II -- finding prime numbers

Client Server. main( ). find_primes( ). is_prime( ). RPC example II -- finding prime numbers. /* Return TRUE If n is prime */ int isprime(int n) { int I; for (I = 2; I*I <= n; I++){ if ((n % I) == 0) return 0; } return 1; }. /* print a list of primes between 1 and 1000 */

deiondre
Download Presentation

RPC example II -- finding prime numbers

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Client Server main( ) find_primes( ) is_prime( ) RPC example II -- finding prime numbers /* Return TRUE If n is prime */ int isprime(int n) { int I; for (I = 2; I*I <= n; I++){ if ((n % I) == 0) return 0; } return 1; } /* print a list of primes between 1 and 1000 */ main() { int I, how_many, primes[1000]; how_many = find_primes(1, 1000, primes); for (I = 0; I < how_many; I++) printf(“%d is prime\n”, primes[I]); } /* Find all primes between min and max, return them in an array */ int find_primes(int min, int max, int *array) { int I, count = 0; for (I = min; I <= max; I++) if (isprime(I)) array[count++] = I; return count; }

  2. primes.x const MAXPRIMES = 1000; struct prime_request{ int min; int max; }; struct prime_result{ int array<MAXPRIMES>; }; program PRIMEPROG{ version PRIMEVERS{ prime_result FIND_PRIMES(prime_request) = 1; } = 1; } = 0x32345678;

  3. p_server.c int isprime(int n) { int i; for (i = 2; i*i <= n; i++){ if ((n % i) == 0) return 0; } return 1; } #include <rpc/rpc.h> #include "primes.h" prime_result *find_primes_1(prime_request *request) { static prime_result result; static int prime_array[MAXPRIMES]; int i, count = 0; for (i = request->min; i <= request->max; i++) if (isprime(i)) prime_array[count++] = i; result.array.array_len = count; result.array.array_val = prime_array; return(&result); }

  4. p_client.c request.min = atoi(argv[2]); request.max = atoi(argv[3]); result = find_primes_1(&request, cl); if (result == NULL){ clnt_perror(cl, argv[1]); exit(3); } for (i = 0; i < result->array.array_len; i++) printf("%d is prime\n", result->array.array_val[i]); printf("count of primes found = %d\n", result->array.array_len); xdr_free(xdr_prime_result, result); clnt_destroy(cl); } #include <rpc/rpc.h> #include "primes.h" main(int argc, char *argv[]) { int i; CLIENT *cl; prime_result *result; prime_request request; if (argc != 4){ printf("usage: %s host min max\n", argv[0]); exit(1); } cl = clnt_create(argv[1], PRIMEPROG, PRIMEVERS, "tcp"); if (cl == NULL){ clnt_pcreateerror(argv[1]); exit(2); }

  5. One More Example on RPC /* Program: shop.x */ /* Limitation of RPC: Remote Procedure Call just supports single parameter passing. Hence, one have to define a specific data structure for passing more than one parameters */ /* you can define your data structure here */ struct items{ char name[10]; int qty; float amount; }; program SHOP_PROG{ version SHOP_VERS{ items ADD12IT(items) = 1; } = 1; } = 0x32345678; /* please use your student ID */

  6. One More Example on RPC /* shop_s.c - Shop Server; called by server stub * * This is sample code generated by rpcgen. * These are only templates and you can use them * as a guideline for developing your own functions. */ #include "shop.h" items * add12it_1_svc(items *product, struct svc_req *rqstp) { static items result; FILE *fptr; /* write the data out to a file */ fptr = fopen("shop.txt", "w"); fprintf(fptr,"<Old %s %d %f>\n", product->name, product->qty, product->amount); /* Add one to the data and send back to the client */ strcpy(result.name, product->name); strcat(result.name, "1"); result.qty = product->qty+1; result.amount = product->amount+1.0; fprintf(fptr,"<New %s %d %f>\n", result.name, result.qty, result.amount); fclose(fptr); return(&result); }

  7. One More Example on RPC #ifndef DEBUG clnt_destroy (clnt); #endif /* DEBUG */ } int main (int argc, char *argv[]) { char *host; if (argc < 2) { printf ("usage: %s server_host\n", argv[0]); exit (1); } host = argv[1]; shop_prog_1 (host); exit (0); } /* Program: shop_c.c * * This is sample code generated by rpcgen. * These are only templates and you can use them * as a guideline for developing your own functions. */ #include "shop.h" void shop_prog_1(char *host) { CLIENT *clnt; items *result; items product; #ifndef DEBUG clnt = clnt_create (host, SHOP_PROG, SHOP_VERS, "udp"); if (clnt == NULL) { clnt_pcreateerror (host); exit (1); } #endif /* DEBUG */ printf("Please type in a string, an integer, and a floating point:\n"); printf("For example:>hello 88 99.99\n>"); scanf("%s %d %f", product.name, &product.qty, &product.amount); result = add12it_1(&product, clnt); if (result == (items *) NULL) { clnt_perror (clnt, "call failed"); } printf("Result:<%s %d %f>\n", result->name, result->qty, result->amount);

  8. Identifying an RPC Service • There is a service registry called the port mapper, which keeps track of all RPC services registered on a machine, and their transport endpoint addresses. • In later implementations the port mapper is called “rpcbind”. • Remote procedure is identified by THREE numbers: {program number, version number, procedure number} • While {program number, version number} identify a specific server program, the procedure number identifies a procedure within that program • The followings are the steps involved in locating an RPC service: • When server starts, it create a endpoint to accept connection, so it binds an arbitrary port number for this purpose; • It then send a message to the portmapper registering the service; • Portmapper add this mapping to its list; • When client wants to find the service, it ask the portmapper by passing it the program number, version number and protocol it uses; • Portmapper returns the port number to the client; • Client call the server procedure by sending an RPC call message to the port it just got from the portmapper; • The call message contains the serialized arguments and the procedure number

  9. Identifying an RPC Service

  10. Identifying an RPC Service Program numbers: 00000000-1FFFFFFF Admin by Sun Microsystems 20000000-3FFFFFFF User-defined 40000000-5FFFFFFF Transient 60000000-FFFFFFFF Reserved for future use

  11. RPC External Data Representation • big-endian byte ordering vs. little-endian ordering • Big-endian byte ordering: 68000 family and Sun SPARC processors • Little-endian byte ordering: VAX, Intel x86 family processors • Little-endian machine (0x12345678) vs. Big-endian machine (0x78563412) • Alignment rules of different processors: struct demo{ char c; int i; long x; } • Language-specific differences in strings: (e.g. string in pascal and string in C) • Architecture-specific differences in pointer representation;

  12. RPC Semantics in the Presence of Failures • Five different classes of failures in RPC systems: • Client Cannot Locate the Server • Server might be down or New server with old client • return -1 for error is not good enough because the return value might be -1 (e.g. adding 7 to -8) • raise an exception (so write your own SIGNOSERVER) • Lost Request Messages • easiest to deal with , just have the kernel start a timer when sending the request, and resend it if time-out. • Lost Reply Messages • use timer again , but this time you cannot tell whether the reply is lost or the server is just slow • idempotent transactions • reading the first 1024 byte of a file is idempotent; • transferring 1 million $ from a bank account is non-idempotent • solution 1: construct all requests in an idempotent way • solution 2: have the client’s kernel assign each request a seq. number

  13. Server Server Server Request Request Request Receive Execute Reply Receive Execute Crash!!! Receive Crash!!! Reply No Reply No Reply RPC Semantics in the Presence of Failures (cond.) • Server Crashes • In the 2nd case, the system has to report failure back to the client • In the 3rd case, it can just retransmit the request • at least-once semantics • at most-once semantics • exactly once semantics

  14. RPC Semantics in the Presence of Failures (cond..) • Client Crashes • unwanted computation is called orphan • solution 1: extermination -- keeping log for every request • solution 2: reincarnation -- divide time into sequentially numbered epochs. Client broadcasts a message to all machines declaring a new epoch. All remote computations are killed. • solution 3: gentle reincarnation -- same as 2, but remote computations are killed only if they cannot find their owner • solution 4: expiration -- each RPC is given a standard time T to do a job, if it cannot finish within T, it have to ask the for another quantum. After the client crash, it wait for T unit of time to make sure that all orphans are gone, then it reboots. note: none of these methods are desirable. Worst yet, killing an orphan may have unforeseen consequences. For example, suppose that an orphan has obtained locks on one or more files or database records. If the orphan is killed suddenly, these locks may remain forever. Also, an orphan may have already made entries in various remote queues to start up other processes at some future time, so even killing the orphan may not remove all traces of it.

More Related