Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Corrected links that should have been relative instead of absolute.

Work in progress.. Do not read..

High-level overview

Here is a simple diagram that shows the flow of data in the code.

Finding the Right Master

The client first has to find the right master to talk to - the master that holds the required data. To do this, RamCloud::read() invokes ObjectFinder::lookup(). It checks client's tabletMap - which is a cache of coordinator's tablet map. If that tablet is recovering or if the object was not found in any tablet, then the cache is refreshed. This is done by refresher(tabletMap) which is hardwired to CoordinatorClient::getTabletMap in the constructor.

...

MasterClient::read() creates the RPC Request. The structure for all RPCs is defined in Rpc.h. For Read requestRequest, the RPC contains the following fields:

...

Call to sendRecv() sends request over session and later gets response. sendRecv() is defined in Client.h.

Master Processing

<lookup in HT
Data is at fixed offset from SEH
Length is calculated
Forming response Buffer>

Image Removed

On the other hand:

BUFFER contains:

  • Transport Layer Header
  • Response Header, respHdr (see Rpc.h)
    • For ReadRpc, the Response struct has:
      • version
      • length
      • pad
  • Data (obj->data from above diagram)
Client Request Processing

<truncating response>

Image Removed

(TODO: sort / remove)
Other random code-related stuff

RamCloud.cc -> read()

  • get SessionRef by objectFinder.lookup(): SessionRef is a reference to a Session object on which we send client RPC requests.
  • create an instance of MasterClient - master
  • call read on master

MasterClient.cc -> read()

  • sendRecv sends request (Rpc - reqHdr, Buffer - req) and gets response (Rpc - respHdr, Buffer - value) over session.
  • checkStatus throws any exceptions at that point. HERE (macro) translates to current location in the code (line num and file name).

MasterServer.cc

...

It creates a AsyncState (called state) which contains:

  • pointer to responseBuffer
  • RPC

It sends the requestBuffer and responseBuffer over session by session->clientSend(), and waits for it to return by state.rpc->wait().

Master Processing

When a master is running, it continuously polls for RPCs by:

handleRpc<MasterServer>()

In Server.h, handleRpc<>() is hardwired to call dispatch() amongst doing other things.

...

 Thus, when an rpc is received, the following chain of functions are called in MasterServer.cc:

dispatch() -> callHandler<>() -> read()

MasterServer::read()

...

NOTE about code flow:
When xClient - sendRecv,   ?where x is Coordinator or Master
then xServer - handleRpc<>() -> dispatch() -> callHandler<>() -> ..

Client.h -> sendRecv()

...

  • pointer to responseBuffer
  • rpc

...

function looks up the requested object in Hash Table. A segment entry is structured such that the data is at fixed offset from the Segment Entry Handler. Thus the actual length of data can be calculated. This is illustrated in the figure below.

Image Added

Finally, the response buffer to be returned is formed by appending this obj->data as a Chunk. The Buffer contains:

  • Transport Layer Header
  • RPC, respHdr (see Rpc.h). For Read Response, the RPC contains:
    • status
    • version
    • length (actual data length, calculated as shown above)
    • pad
  • Data (obj->data from above)
Client Request Processing

The SendRecv() (originally called by MasterClient::read()) resumes from state.rpc->wait() and returns the respHdr RPC to MasterClient.cc. Finally the response is truncated to only contain the actual value (data) as illustrated in the figure below.

Image Added

This value is returned back to the calling read() function.

EndNode: What? Why? How?

What: A simple introduction to understanding how a "read" works in RAMCloud based on my current understanding.

...