Async Receive Return control before have filled in msg variable with received messages. How can this be useful? Wait syscall (until msg avail) Test syscall (has msg arrived) Condition receive (receive or announce no msg yet) interrupt none are beautiful Timeouts If have blocking primitive, send or receive could wait forever. Some systems/languages offer timeouts. HOMEWORK 10.3 To buffer or not to buffer (unbuffered) If unbuffered, the received tells where to put the msg Doesn't work if async send is before receive (where put msg). For buffered, the kernel keeps the msg (in a MAILBOX) until the receiver asks for it. Raises buffer management questions HOMEWORK 10.5 Acks Can assert msg delivery are not reliable Checked at higher level Kernel can ack every msg Senders and repliers keep msg until receive ack Kernel can use reply to ack every request but explicitly ack replies Kernel can use reply as ack to every request but NOT ack replies Client will resend request Not always good (if server had to work hard to calculate reply) Kernel at server end can deliver request and send ack if reply nor forthcoming soon enough. Again can either ack reply or not. Large design space. Several multiway choices for acks, buffers, ... Click for diagram in postscript or html.

Other messages (meta messages??)

    Are you alive?

    I am alive

    I am not alive (joke)

    Mailbox full

    No process listening on this port      

---------------- Remote Procedure Call (RPC) ----------------

Birrell and Nelson (1984)

Recall how different the client code for copying a file was from
normal centralized (uniprocessor) code.

Lets make client server request-reply look like a normal procedure
call and return.

Tanenbaum says C has call-by-value and call-by-reference.  I don't
like this.  In C you pass pointers by value (at least for scalars) and
I don't consider that the same.  But "this is not a programming
languages course"

HOMEWORK 10.7

Recall that getchar in the centralized version turns into a read
syscall (I know about buffering).  The following is for unix

    Read looks like a normal procedure to its caller.

    Read is a USER mode program (needs some assembler code)

    Read plays around with registers and then does a poof (trap)

    After the poof, the kernel plays with regs and then does a
    C-language routine and lots gets done (drivers, disks, etc)

    After the I/O the process get unblocked, the kernel read plays
    with regs, and does an unpoof.  The user mode read plays with regs
    and returns to the original caller

Lets do something similar with request reply

    User (client) does subroutine call to getchar (or read)

        Client knows nothing about messages

    We link in a user mode program called the client stub (analogous
    to the user mode read above).

        Takes the parameters to read and converts it to a msg
        (MARSHALLS the arguments)

        Sends a msg to machine containing the server directed to a
        SERVER STUB

        Does a blocking receive (of the reply msg)

    Server stub is linked with the server.

        Receives the msg from the client stub.

        Unmarshalls the arguments and calls the server (as a
        subroutine)

    The server procedure does what it does and returns (to the server
    stub)

        Server kows nothing about messages

    Server stub now converts this to a reply msg sent to the client
    stub

        Marshalls the arguments

    Client stub unblocks and receives the reply

        Unmarshalls the arguments

        RETURNS to the client

    Client believes (correctly) that the routine it calls has returned
    just like a normal procedure does.

Heterogeneity: Machines have different data formats

    Previously discussed

    Have conversions between all posibilities

        Done during marshalling and unmarshalling

    Adopt a std and convert to/from it.

HOMEWORK 10.8

Pointers

    Avoid them for RPC!

    Can put the object pointed to into the msg itself (assuming you
    know its length).

        Convert call-by-ref to copyin/copyout

        If have in or out param (instead of in out) can elim one of
        the copies

    Gummy up the server to handle pointers special

        Callback to client stub

        Ugh

Registering and name servers

    As we said before can use a name server.

    This permits the server to move

        deregister from the name server

        move

        reregister

    Sometimes called dynamic binding

    Client stub calls name server (binder) first time to get a HANDLE
    to use for the future

        Callback from binder to client stub if server deregisters or
        have the attempt to used the handle fail so client stub will
        goto to binder again.

HOMEWORK 10.12

Failures

    This gets hard and ugly

    Can't find the server.

        Need some sort of out-of-band response from client stub to
        client

            Ada exceptions

            C signals

            Multithread the CLIENT and start the "exception" thread

        Loses transparancy (centralized systems don't have this).

    Lost request msg

        This is easy if known.  That is, if sure request was lost.

        Also easy if idempotent and think might be lost.

        Simply retransmit request

            Assumes the client still knows the request

    Lost reply msg

        If it is known the reply was lost, have server retransmit

            Assumes the server still has the reply

            How long should the server hold the reply

                Wait forever for the reply to be ack'ed--NO

                Discard after "enough" time

                Discard after receive another request from this client

                Ask the client if the reply was received

                Keep resending reply

    What if not sure of whether lost request or reply?

        If server stateless, it doesn't know and client can't tell.

        If idempotent, simply retransmit the request

    What if not idempotent and can't tell if lost request or reply?

        Use sequence numbers so server can tell that this is a new
        request not a retransmission of a request it has already done.

        Doesn't work for stateless servers

HOMEWORK 10.13 10.14  Remind me to discuss these two next time

    Server crashes

        Did it crash before or after doing some nonidempotent action?

        Can't tell from messages.

        For databases, get idea of transactions and commits.

            This really does solve the problem but is not cheap.

        Fairly easy to get "at least once" (try request again if timer
        expires) or "at most once (give up if timer expires)"
        semantics.  Hard to get "exactly once" without transactions.

            To be more precise.  A tranaction either happens exactly
            one or not at all (sounds like at most once) AND the
            client knows which.

    Client crashes

        Orphan computations exist.

        Again transactions work but are expensive

        Can have rebooted client start another epoch and all
        computations of previous epoch are killed and clients
        resubmit.

            Better is to let continue old computations with owners
            that can be found.

        Not wonderful

            Orhpan may hold locks or might have done something not
            easily undone.

        Serious programming needed.

Implementation

    Protocol choice

        Existing ones like UDP are designed for harder (more general)
        cases so are not efficient.

        Often developers of distributed systems, invent their own
        protocol that is more efficient.

            But of course they are all different.

        On a lan would like large messages since they are more
        efficient and don't take so long considering the high
        datarate.

HOMEWORK 10.15