Skip to content

Commit

Permalink
Merge pull request #27 from loopholelabs/staging
Browse files Browse the repository at this point in the history
v0.7.1
  • Loading branch information
ShivanshVij committed Dec 10, 2022
2 parents 0d1a0e0 + 72f92d4 commit 332d04e
Show file tree
Hide file tree
Showing 49 changed files with 4,088 additions and 480 deletions.
6 changes: 0 additions & 6 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,6 @@ and if required please add new test cases and list them below:
- [ ] Test A
- [ ] Test B

## Linting

Please make sure you've run the following and fixed any issues that arise:

- [ ] `trunk check` has been run

## Final Checklist:

- [ ] My code follows the style guidelines of this project
Expand Down
39 changes: 0 additions & 39 deletions .github/workflows/lint.yaml

This file was deleted.

3 changes: 0 additions & 3 deletions .trunk/.gitignore

This file was deleted.

1 change: 0 additions & 1 deletion .trunk/logs

This file was deleted.

1 change: 0 additions & 1 deletion .trunk/out

This file was deleted.

1 change: 0 additions & 1 deletion .trunk/plugins/trunk

This file was deleted.

15 changes: 0 additions & 15 deletions .trunk/trunk.yaml

This file was deleted.

14 changes: 11 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,20 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [v0.7.1] - 2022-12-10

### Changes

- Fixed a bug when generating fRPC with streams where sometimes stream messages would be received out of order.
- Removed the Trunk linter

## [v0.7.0] - 2022-09-28

### Features

- fRPC now uses the `VarInt` encoding format under the hood (added in [polyglot-go v0.5.0](https://github.com/loopholelabs/polyglot-go)) which should help reduce the number of bytes an RPC call is serialized to
- A new `CloseError` type has been added which, when returned by an RPC call, causes the connection to be closed after the message is written. This can be useful for authentication or connection management.
- Streaming is now available! The API matches gRPC's so it should be a drop-in replacement!
- A new `CloseError` type has been added which, when returned by an RPC call, causes the connection to be closed after the message is written. This can be useful for authentication or connection management.
- Streaming is now available! The API matches gRPC's so it should be a drop-in replacement!

### Changes

Expand All @@ -40,7 +47,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

> Changelogs for [v0.5.0] and before can be found at https://github.com/loopholelabs/frisbee-go
[unreleased]: https://github.com/loopholelabs/frpc-go/compare/v0.7.0...HEAD
[unreleased]: https://github.com/loopholelabs/frpc-go/compare/v0.7.1...HEAD
[v0.7.1]: https://github.com/loopholelabs/frpc-go/releases/tag/v0.7.1
[v0.7.0]: https://github.com/loopholelabs/frpc-go/releases/tag/v0.7.0
[v0.6.0]: https://github.com/loopholelabs/frpc-go/releases/tag/v0.6.0
[v0.5.1]: https://github.com/loopholelabs/frpc-go/releases/tag/v0.5.1
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,14 @@ same is true for selected other new features explicitly marked as

Usage instructions and documentation for fRPC is available at [https://frpc.io/](https://frpc.io/).

fRPC is still in very early \*_Alpha_. There may be bug in the library that will be fixed
fRPC is still in very early _Alpha_. There may be bugs in the library that will be fixed
as the library matures and usage of fRPC grows. One of the major benefits to fRPC is that reading the generated code
is extremely straight forward, making it easy to debug potential issues down the line.

### Unsupported Features

fRPC currently does not support the following features, though they are actively being worked on:

- Streaming Messages between the client and server
- `OneOf` Message Types

Example `Proto3` files can be found [here](/examples).
Expand Down
6 changes: 3 additions & 3 deletions dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ FROM golang as builder

ENV GOOS=linux GOARCH=amd64 CGO_ENABLED=0

RUN go install github.com/loopholelabs/frpc-go/protoc-gen-go-frpc@v0.5.1
RUN go install github.com/loopholelabs/frpc-go/protoc-gen-go-frpc@v0.7.1

# Note, the Docker images must be built for amd64. If the host machine architecture is not amd64
# you need to cross-compile the binary and move it into /go/bin.
Expand All @@ -12,8 +12,8 @@ FROM scratch

# Runtime dependencies
LABEL "build.buf.plugins.runtime_library_versions.0.name"="github.com/loopholelabs/frpc-go"
LABEL "build.buf.plugins.runtime_library_versions.0.version"="v0.5.1"
LABEL "build.buf.plugins.runtime_library_versions.0.version"="v0.7.1"

COPY --from=builder /go/bin /

ENTRYPOINT ["/protoc-gen-go-frpc"]
ENTRYPOINT ["/protoc-gen-go-frpc"]
Binary file added docs/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 49 additions & 0 deletions docs/getting-started/architecture.mdx
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.
70 changes: 70 additions & 0 deletions docs/getting-started/concepts.mdx
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).
49 changes: 49 additions & 0 deletions docs/getting-started/overview.mdx
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.
Loading

0 comments on commit 332d04e

Please sign in to comment.