1 Thrift for Racket Architecture
The Apache Thrift Concepts page introduces the following diagram showing the architectural layers that make up the Thrift framework. The documentation below will describe how these layers and the features within them are provided by this package.
+-------------------------------------------+
| Server |
| (single-threaded, event-driven etc) |
+-------------------------------------------+
| Processor |
| (compiler generated) |
+-------------------------------------------+
| Protocol |
| (JSON, compact etc) |
+-------------------------------------------+
| Transport |
| (raw TCP, HTTP etc) |
+-------------------------------------------+
Additionally, the Thrift Roadmap for adding new language bindings specifies required, recommended, and optional features for each of the architecture layers above.
Finally, there is no attempt to utilize the existing and comprehensive integration test suite.
1.1 Interface Definition Language
The tools provided in this package do not, currently, provide a parser for the Thrift interface description language as-is. Instead it uses a set of macros in the module thrift/idl/language to describe an interface and can code generate from a module that uses these macros.
The following table lists the major components of the Thrift IDL language and their corresponding Racket macros.
Thrift | Racket |
include | not yet defined |
namespace | |
const | not yet defined |
typedef | not yet defined |
enum | |
senum | not yet defined |
struct | |
union | define-thrift-union |
exception | not yet defined |
service | not yet defined |
1.2 Transport Layer
The transport layer consists of wrappers around standard Racket I/O capabilities and specifically a transport struct that wraps an individual Racket port?. Each transport is responsible for providing an open-input... and open-output... function. As you can see from the table below their is good coverage of the transport API, although at this time the two server functions listen and accept are not supported.
Thrift | Racket |
open | open-input-?-transport |
open-output-?-transport | |
close | |
read | |
write | |
flush | |
listen | not yet defined |
accept | not yet defined |
The following table lists the transports defined by Thrift and their corresponding Racket implementation (if any).
Feature | Coverage | Racket |
Sockets | minimal-required | not yet defined |
Buffered | minimal-required | |
Framed | minimal-required | |
Files | minimal-recommended | |
HTTP Client | minimal-recommended | not yet defined |
HTTP Server | other-recommended | not yet defined |
Pipes | other-recommended | not yet defined |
NamedPipes | other-recommended | not yet defined |
The memory buffer transport (module thrift/transport/memory) is primarily used for testing and allows reading/writing over byte buffers.
1.3 Protocol Layer
The Protocol interface described in the Thrift Concepts page is actually split into two separate components in the Racket implementation. These two are defined in the module thrift/protocol/common as the structs encoder and decoder. This reflects the Racket philosophy of having separate input and output ports as well as making it easier to implement just one half of the protocol interface.
The following table presents a sample of the mapping from the Thrift API on the left hand side to the Racket module form on the right. For the four methods on the thrift interface that deal with structured data: message, field, map, list, and set we define structs that are input to the write functions and returned from the read functions.
Thrift | Racket |
writeMessageBegin(name, type, seq) | (write-message-begin message-header?) |
name, type, seq = readMessageBegin() | read-message-begin -> message-header? |
writeMessageEnd() | write-message-end |
readMessageEnd() | read-message-end |
writeI16(i16) | (write-int16 type-int16?) |
i16 = readI16() | read-int16 -> type-int16? |
Additionally the thrift/protocol/decoding module provides decode-a-struct, decode-a-list, and decode-a-set.
The following table lists the protocols defined by Thrift and their corresponding Racket implementation (if any).
Feature | Coverage | Racket |
Binary | minimal-required | |
Multiplex | minimal-required | |
JSON | minimal-recommended | |
Compact | other-recommended | |
Debug | other-recommended |
1.4 Processor Layer
The key element of the processor layer is the definition of an interface used by the server layer to denote a component that reads from one and writes to another protocol. This interface is described in the Thrift documentation as follows.
interface TProcessor { |
bool process(TProtocol in, TProtocol out) throws TException |
} |
The thrift/processor/common module provides the following contract definition that describes a function in the same manner as the interface above.
(define protocol-processor/c (-> decoder? encoder? boolean?))
1.5 Server Layer
The following table lists the servers defined by Thrift, this is not currently the focus of this package and none are implemented.
Feature | Coverage | Racket |
SimpleServer | minimal-required | not yet defined |
Non-Blocking | other-recommended | not yet defined |
Threaded | other-recommended | not yet defined |
Thread Pool | other-recommended | not yet defined |