-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #27 from loopholelabs/staging
v0.7.1
- Loading branch information
Showing
49 changed files
with
4,088 additions
and
480 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
--- | ||
title: Architecture | ||
--- | ||
|
||
The architecture of fRPC is based on the standard Server/Client model that a lot of other RPC frameworks are follow. | ||
The idea is that the `Client` makes a connection with the `Server`, and then sends a structured | ||
request. Based on the request type, the `Server` runs a handler that then returns a response or an error. | ||
The `Server` then forwards that response object (or the error) back to the `Client`. | ||
|
||
From the perspective of the `Client`, they have simply called a function and received a response. The fact | ||
that the request is serialized and transmitted to the `Server` is hidden for simplicity. | ||
|
||
To dig into how the underlying architecture of both the `Server` and `Client` work, it is first | ||
important to understand that the underlying [Frisbee](https://github.com/loopholelabs/frisbee-go) protocol does not have any notion of a request | ||
or response. When Frisbee sends a `Packet` of data, it does not wait for a response. This makes | ||
the protocol suitable for a number of use cases (like real-time streaming), but also means that Request/Reply semantics | ||
need to be implemented in the application logic - in this case, the code that fRPC generates. | ||
|
||
# Server Architecture | ||
|
||
The generated fRPC `Server` is based on the RPC `Services` that are defined in the `proto3` | ||
file that is passed to the `protoc` compiler. Developers are responsible for implementing the generated | ||
`Service` interfaces and passing that into the `Server` constructor. | ||
|
||
The `Server` then takes that implementation and creates a `handler table` that maps the request type to the | ||
accompanying function in the provided `Service` implementation. | ||
|
||
When it receives a request, it looks up the request type in the `handler table` and calls the accompanying | ||
function with the deserialized Request object. The function then returns a Response object that | ||
is serialized and sent back to the `Client`. | ||
|
||
# Client Architecture | ||
|
||
The generated fRPC `Client` is also based on the RPC `Services` that are defined in the | ||
`proto3` file that is passed to the `protoc` compiler. Based on the RPC Calls defined in those services, | ||
fRPC generates a number of `Client` helper functions - one for each possible RPC Call. | ||
|
||
As mentioned before, Frisbee does not have any notion of a request or response - this means that we must implement | ||
the ability to wait for a response from the `Server` in the application logic. We need to also be able to map | ||
those incoming responses to the correct ongoing request. | ||
|
||
To achieve this, fRPC Clients make use of an `in-flight` requests table that maps a request ID to a channel | ||
that can be listened to for a response. When an RPC function is called, it generates a request ID, serializes the request | ||
object and sends it to the `Server`. When a response object is received from the `Server`, it is | ||
deserialized and request ID is looked up in the `in-flight` requests table. | ||
|
||
The response is then pushed into the channel associated with the request ID, where it is read by the RPC function | ||
that made the request in the first place. This response unblocks the RPC caller and the response object (or an error) | ||
is returned. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
--- | ||
title: Concepts | ||
--- | ||
|
||
fRPC is, at its core, a code generator - one which uses the Frisbee messaging framework as its underlying transport mechanism. It hooks into | ||
the `protoc` compiler and generates an RPC framework that matches the `proto3` spec provided to it. | ||
|
||
Frisbee was designed to allow developers to define their own messaging protocols, while having a library that would handle | ||
all the lower level implementation for them. | ||
|
||
<Tooltip tip="Request/Reply systems where the request is sent to a remote service which then replies back to the caller">RPC Frameworks</Tooltip> | ||
are implementations of the Request/Reply pattern, and so fRPC generates the necessary | ||
Frisbee code to handle that messaging pattern. | ||
|
||
There are three main components to fRPC: | ||
|
||
- The Message Types | ||
- The Client | ||
- The Server | ||
|
||
# Message Types | ||
|
||
One of the challenges with any messaging system is that the messages must be serialized and deserialized into formats that | ||
can be transmitted over the wire. With a code generator like fRPC, that means we need to take your `proto3` | ||
message definitions and generate the accompanying `structs` in Go. We then need to create consistent, performant, | ||
and safe serialization and deserialization functions for those structs. | ||
|
||
To do this, fRPC makes use of the [Polyglot](https://github.com/loopholelabs/polyglot-go) library, which is a high-performance | ||
serialization framework that recycles byte buffers and can serialize and deserialize data with almost no allocations. | ||
This makes serialization and deserialization extremely fast, while also allowing us to minimize the accompanying memory allocations. | ||
|
||
[polyglot-go](https://github.com/loopholelabs/polyglot-go) library type comes with a number of | ||
`encode` and `decode` methods for various types, that fRPC chains together to create the | ||
serialization and deserialization functions for your `proto3` message definitions. | ||
|
||
We're also actively working on a [polyglot-rs](https://github.com/loopholelabs/polyglot-rs) library, which is a Rust | ||
implementation of `Polyglot`, as well as [polyglot-ts](https://github.com/loopholelabs/polyglot-ts) which is a | ||
TypeScript (and Javascript) implementation of `Polyglot`. | ||
|
||
# The Client | ||
|
||
The fRPC Client is a simple wrapper around the `frisbee.Client` type, and contains generated helper | ||
functions for creating and sending requests to an fRPC Server and then returning the accompanying response. | ||
|
||
It's also possible to deviate from those helper functions and access the underlying `frisbee.Client` directly. | ||
This allows you to do things like turn Frisbee off (and thus retrieve the underlying TCP connection). | ||
|
||
# The Server | ||
|
||
The fRPC Server is a simple wrapper around the `frisbee.Server` type, and contains generated helper | ||
functions for handling incoming requests and returning the accompanying response based on the handlers you've passed in | ||
to the constructor. | ||
|
||
Similar to the Client, it's also possible to deviate from those helper functions and access the underlying | ||
`frisbee.Server` directly. This allows you to do things like turn Frisbee off (and thus retrieve the | ||
underlying TCP connection), or write your own middleware functions for incoming or outgoing packets. | ||
|
||
# Accessing Frisbee Directly | ||
|
||
As we've mentioned before, it's possible to access the underlying [Frisbee](https://github.com/loopholelabs/frisbee-go) primitives from both the | ||
client and the server. This is why fRPC is more flexible than other RPC frameworks, and why it's possible to | ||
do things like send a few RPC requests using fRPC and then reuse that underlying TCP connection for something like an | ||
HTTP proxy. | ||
|
||
fRPC generates a `frisbee.HandlerTable` that allows Frisbee to route incoming packets to the correct | ||
handler functions. It's possible to override this table using the `frisbee.Server.SetHandlerTable()` | ||
method (which is exposed in the generated `frpc.Server` type). | ||
|
||
To learn more about how [Frisbee](https://github.com/loopholelabs/frisbee-go) works and how you can leverage it from within the generated fRPC | ||
code, check out the [frisbee-go Github Repository](https://github.com/loopholelabs/frisbee-go). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
--- | ||
title: Overview | ||
--- | ||
|
||
**fRPC** (or **Frisbee RPC**), is an <Tooltip tip="Remote Procedure Call">RPC</Tooltip> Framework (similar to [gRPC](https://grpc.io) or | ||
[Apache Thrift](https://thrift.apache.org/)) that's designed from the ground up to be lightweight, extensible, and extremely performant. | ||
|
||
We built <Tooltip tip="Frisbee RPC">fRPC</Tooltip> because we loved the idea of defining our message types in a standardized | ||
[proto3](https://developers.google.com/protocol-buffers/docs/proto3) format and having the [protobuf](https://github.com/protocolbuffers/protobuf) compiler generate all the necessary | ||
glue code for us, but we didn't like the [overhead](https://github.com/boguslaw-wojcik/encoding-benchmarks) of encoding and decoding | ||
messages in the <Tooltip tip="Data format used to serialize structured data">Protobuf</Tooltip> format, and wanted a wire protocol that was lighter and faster | ||
than <Tooltip tip="Wire format used for gRPC">HTTP\/2</Tooltip>. | ||
|
||
<Tooltip tip="Frisbee RPC">fRPC</Tooltip> offers a few major improvements over existing | ||
RPC frameworks like gRPC: | ||
|
||
- **Speed** - On average fRPC outperforms other RPC frameworks [by 2-4x in an apples-to-apples comparison](/performance/grpc-benchmarks), and is easily able to handle more than **2 million RPCs/second** on a single server | ||
- **Flexibility** - Not only does fRPC allow developers to deviate from the standard request/reply messaging pattern and implement custom patterns alongside their existing RPCs, but developers also have the ability to turn fRPC off and retrieve the underlying TCP connections so they can be reused for something else | ||
- **Familiarity** - Using fRPC feels very familiar to anyone who's used gRPC before, which means that developers can take advantage of the speed and extensibility that fRPC provides without a steep learning curve | ||
|
||
fRPC works by making use of protobuf plugins, and allows developers to use their existing proto3 files to generate a full | ||
RPC Framework that uses Frisbee under the hood. Our goal is to make fRPC a **drop-in | ||
replacement for gRPC** thanks to its generated interfaces matching gRPC's, however we don't support all of the features that | ||
gRPC does yet, most notable being Streaming and OneOf message types. | ||
|
||
# fRPC vs Frisbee | ||
|
||
It's important to note the distinction between fRPC and Frisbee. fRPC uses proto3 files to generate client and server | ||
implementations that use the Frisbee framework under the hood. This is why fRPC is so performant compared to other RPC | ||
frameworks - the Frisbee messaging framework and wire protocol are lightweight and extremely optimized. | ||
|
||
At its core, **Frisbee** is best described as a `bring-your-own-protocol` messaging framework. Our goal was | ||
to make it possible for developers to define their **own** messaging patterns and protocols, and have the actual | ||
lower-level implementations done for them by the library. | ||
|
||
<Note> | ||
A simple way to understand this is to think of fRPC as a Request/Reply | ||
protocol, and Frisbee as the low-level implementation of that protocol. With | ||
Frisbee you can implement any protocol or pattern you'd like, but since | ||
Request/Reply is so common fRPC allows you to implement that specific pattern | ||
very quickly and easily. | ||
</Note> | ||
|
||
# Getting started with fRPC | ||
|
||
Over the next few pages we'll walk you through the process of getting started with <Tooltip tip="Frisbee RPC">fRPC</Tooltip>, | ||
from defining your message types in a <Tooltip tip="Syntax used to describe protocol buffers">proto3</Tooltip> file, to writing your first server and client. | ||
|
||
We'll also introduce the core concepts around Frisbee as well as how you can use the Framework to build your own custom messaging protocols. |
Oops, something went wrong.