Skip to content
This repository has been archived by the owner on Dec 28, 2024. It is now read-only.

Commit

Permalink
docs: new rpc docs
Browse files Browse the repository at this point in the history
  • Loading branch information
palkan committed Mar 6, 2024
1 parent 4f16b99 commit ec17f3e
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 77 deletions.
4 changes: 4 additions & 0 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ func (r *Runner) Run() error {

r.log.Info(fmt.Sprintf("Starting %s %s%s (pid: %d, open file limit: %s, gomaxprocs: %d)", r.name, version.Version(), mrubySupport, os.Getpid(), utils.OpenFileLimit(), numProcs))

if r.config.IsPublic() {
r.log.Warn("Server is running in the public mode")
}

appNode, err := r.runNode()

if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,7 @@ func NewConfig() Config {

return config
}

func (c Config) IsPublic() bool {
return c.SkipAuth && c.Streams.Public
}
2 changes: 1 addition & 1 deletion docs/broadcasting.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ $ curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer my-
broadcast_key = OpenSSL::HMAC.hexdigest("SHA256", "<APPLICATION SECRET>", "broadcast-cable")
```

When using AnyCable SDKs, you don't need to calculate it yourself. But if you want to publish broadcasts using a custom implementation, you can generate a broadcast key for your secret key as follows:
When using official AnyCable server libraries, you don't need to calculate it yourself (they all use the same inference mechanism). But if you want to publish broadcasts using a custom implementation, you can generate a broadcast key for your secret key as follows:

```sh
echo -n 'broadcast-cable' | openssl dgst -sha256 -hmac '<your secret>' | awk '{print $2}'
Expand Down
2 changes: 1 addition & 1 deletion docs/broker.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ You can use [AnyCable JS client](https://github.com/anycable/anycable-client) li

## Broadcasting messages

Broker is responsible for **registering broadcast messages**. Each message MUST be registered once; thus, we MUST use a broadcasting method which publishes messages to a single node in a cluster (see [Broadcast adapters](../ruby/broadcast_adapters.md)). Currently, `http` and `redisx` adapters are supported.
Broker is responsible for **registering broadcast messages**. Each message MUST be registered once; thus, we MUST use a broadcasting method which publishes messages to a single node in a cluster (see [broadasting](./broadcasting.md)). Currently, `http` and `redisx` adapters are supported.

**NOTE:** When legacy adapters are used, enabling a broker has no effect.

Expand Down
52 changes: 1 addition & 51 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Supports wildcards, e.g., `--allowed_origins=*.evilmartians.io,www.evilmartians.

**--broadcast_adapter** (`ANYCABLE_BROADCAST_ADAPTER`, default: `redis`)

[Broadcasting adapter](../ruby/broadcast_adapters.md) to use. Available options: `redis` (default), `redisx`, `nats`, and `http`.
[Broadcasting adapter](./broadcasting.md) to use. Available options: `redis` (default), `redisx`, `nats`, and `http`.

When HTTP adapter is used, AnyCable-Go accepts broadcasting requests on `:8090/_broadcast`.

Expand Down Expand Up @@ -190,17 +190,6 @@ For example, using the following URL, you can set the ping interval to 10 second
ws://localhost:8080/cable?pi=10&ptp=ms
```

## HTTP RPC

When using HTTP RPC, you can specify the following additional options:

- `http_rpc_secret`: a secret token used to authenticate RPC requests.
- `http_rpc_timeout`: timeout for RPC requests (default: 3s).

You MUST use `rpc_host` configuration option to provide the URL for HTTP RPC, e.g.: `https://my.web.app/anycable`.

Please, refer to the [RPC over](../ruby/http_rpc.md) documentation for more information about this communication mode.

## TLS

To secure your `anycable-go` server provide the paths to SSL certificate and private key:
Expand All @@ -217,45 +206,6 @@ If RPC server uses certificate issued by private CA, then you can pass either it

If RPC uses self-signed certificate, you can disable RPC server certificate verification by setting `--rpc_tls_verify` (`ANYCABLE_RPC_TLS_VERIFY`) to `false`, but this is insecure, use only in test/development.

## Concurrency settings

AnyCable-Go uses a single Go gRPC client\* to communicate with AnyCable RPC servers (see [the corresponding PR](https://github.com/anycable/anycable-go/pull/88)). We limit the number of concurrent RPC calls to avoid flooding servers (and getting `ResourceExhausted` exceptions in response).

\* A single _client_ doesn't necessary mean a single connection; a Go gRPC client could maintain multiple HTTP2 connections, for example, when using [DNS-based load balancing](../deployment/load_balancing).

We limit the number of concurrent RPC calls at the application level (to prevent RPC servers overload). By default, the concurrency limit is equal to **28**, which is intentionally less than the default RPC size (see [Ruby configuration](../ruby/configuration.md#concurrency-settings)): there is a tiny lag between the times when the response is received by the client and the corresponding worker is returned to the pool. Thus, whenever you update the concurrency settings, make sure that the AnyCable-Go value is _slightly less_ than the AnyCable-RPC one.

You can change this value via `--rpc_concurrency` (`ANYCABLE_RPC_CONCURRENCY`) parameter.

## Adaptive concurrency

<p class="pro-badge-header"></p>

AnyCable-Go Pro provides the **adaptive concurrency** feature. When it is enabled, AnyCable-Go automatically adjusts its RPC concurrency limit depending on the two factors: the number of `ResourceExhausted` errors (indicating that the current concurrency limit is greater than RPC servers capacity) and the number of pending RPC calls (indicating the current concurrency is too small to process incoming messages). The first factor (exhausted errors) has a priority (so if we have both a huge backlog and a large number of errors we decrease the concurrency limit).

You can enable the adaptive concurrency by specifying 0 as the `--rpc_concurrency` value:

```sh
$ anycable-go --rpc_concurrency=0

...

INFO 2023-02-23T15:26:13.649Z context=rpc RPC controller initialized: \
localhost:50051 (concurrency: auto (initial=25, min=5, max=100), enable_tls: false, proto_versions: v1)
```

You should see the `(concurrency: auto (...))` in the logs. You can also specify the upper and lower bounds for concurrency via the following parameters:

```sh
$ anycable-go \
--rpc_concurrency=0 \
--rpc_concurrency_initial=30 \
--rpc_concurrency_max=50 \
--rpc_concurrency_min=5
```

You can also monitor the current concurrency value via the `rpc_capacity_num` metrics.

## Disconnect settings

AnyCable-Go notifies an RPC server about disconnected clients asynchronously with a rate limit. We do that to allow other RPC calls to have higher priority (because _live_ clients are usually more important) and to avoid load spikes during mass disconnects (i.e., when a server restarts).
Expand Down
88 changes: 66 additions & 22 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,21 @@
# Getting Started with AnyCable-Go
# Getting Started with AnyCable

AnyCable-Go is a WebSocket server for AnyCable written in Golang.
AnyCable is a language-agnostic real-time server focused on performance and reliability written in Go.

## Installation
> The quickest way to get AnyCable is to use our managed (and free) solution: [plus.anycable.io](https://plus.anycable.io)
> The quickest way to get AnyCable for production is to use our hosted version: [plus.anycable.io](https://plus.anycable.io)
## Installation

The easiest way to install AnyCable-Go is to [download](https://github.com/anycable/anycable-go/releases) a pre-compiled binary.

MacOS users could install it with [Homebrew](https://brew.sh/)

```sh
brew install anycable-go

# or use --HEAD option for edge versions
brew install anycable-go --HEAD
```

Arch Linux users can install [anycable-go package from AUR](https://aur.archlinux.org/packages/anycable-go/).

Of course, you can install it from source too:

```sh
go get -u -f github.com/anycable/anycable-go/cmd/anycable-go
```

### Via NPM

For JavaScript projects, there is also an option to install AnyCable-Go via NPM:
Expand All @@ -38,28 +29,28 @@ yarn add --dev @anycable/anycable-go
npx anycable-go
```

**NOTE:** The version of the NPM package is the same as the version of the AnyCable-Go binary (which is downloaded automatically on the first run).
**NOTE:** The version of the NPM package is the same as the version of the AnyCable server binary (which is downloaded automatically on the first run).

## Usage

Run server:
After installation, you can run AnyCable as follows:

```sh
$ anycable-go

=> INFO time context=main Starting AnyCable v1.4.8 (pid: 12902, open files limit: 524288, gomaxprocs: 4)
2024-03-06 13:38:07.545 INF Starting AnyCable 1.5.0-4f16b99 (with mruby 1.2.0 (2015-11-17)) (pid: 8289, open file limit: 122880, gomaxprocs: 8) nodeid=hj2mXN
...
2024-03-06 13:38:56.490 INF RPC controller initialized: localhost:50051 (concurrency: 28, impl: grpc, enable_tls: false, proto_versions: v1) nodeid=FlCtwf context=rpc
```

By default, `anycable-go` tries to connect to a gRPC server listening at `localhost:50051` (the default host for the Ruby gem).
By default, AnyCable tries to connect to a gRPC server listening at `localhost:50051` (the default host for the Ruby gem).

You can change this setting by providing `--rpc_host` option or `ANYCABLE_RPC_HOST` env variable (read more about [configuration](./configuration.md)).
AnyCable is designed as a logic-less proxy for your real-time features relying on a backend server to authenticate connections, authorize subscriptions and process incoming messages. That's why our default configuration assumes having an RPC server to handle all this logic.

All other configuration parameters have the same default values as the corresponding parameters for the AnyCable RPC server, so you don't need to change them usually.
You can read more about AnyCable RPC in the [corresponding documentation](./rpc.md).

### Standalone mode (pub/sub only)

AnyCable is designed as a logic-less proxy for your real-time features relying on a backend server to authenticate connections, authorize subscriptions and process incoming messages. That's why our default configuration assumes having an RPC server to handle all this logic.

For pure pub/sub functionality, you can use AnyCable in a standalone mode, without any RPC servers. For that, you must configure the following features:

- [JWT authentication](./jwt_identification.md) or disable authentication completely (`--noauth`). **NOTE:** You can still add minimal protection via the `--allowed_origins` option (see [configuration](./configuration.md#primary-settings)).
Expand All @@ -68,16 +59,69 @@ For pure pub/sub functionality, you can use AnyCable in a standalone mode, witho

There is also a shortcut option `--public` to enable both `--noauth` and `--public_streams` options. **Use it with caution**.

You can also explicitly disable the RPC component by specifying the `--norpc` option.

Thus, to run AnyCable real-time server in an insecure standalone mode, use the following command:

```sh
$ anycable-go --public

2024-03-06 14:00:12.549 INF Starting AnyCable 1.5.0-4f16b99 (with mruby 1.2.0 (2015-11-17)) (pid: 17817, open file limit: 122880, gomaxprocs: 8) nodeid=wAhWDB
2024-03-06 14:00:12.549 WRN Server is running in the public mode nodeid=wAhWDB
...
```

To secure access to AnyCable server, specify either the `--jwt_secret` or `--streams_secret` option. There is also the `--secret` shortcut:

```sh
anycable-go --secret=VERY_SECRET_VALUE
anycable-go --secret=VERY_SECRET_VALUE --norpc
```

Read more about pub/sub mode in the [signed streams documentation](./signed_streams.md).

### Connecting to AnyCable

AnyCable uses the [Action Cable protocol][protocol] for client-server communication. We recommend using our official [JavaScript client library][anycable-client] for all JavaScript/TypeScript runtimes:

```js
import { createCable } from '@anycable/web'

const cable = createCable(CABLE_URL)

const subscription = cable.subscribeTo('ChatChannel', { roomId: '42' })

const _ = await subscription.perform('speak', { msg: 'Hello' })

subscription.on('message', msg => {
if (msg.type === 'typing') {
console.log(`User ${msg.name} is typing`)
} else {
console.log(`${msg.name}: ${msg.text}`)
}
})
```

**Note**: The snippet above assumes having a "ChatChannel" defined in your application (which is connected to AnyCable via RPC).

You can also use:

- Third-party Action Cable-compatible clients.

- EventSource (Server-Sent Events) connections ([more info](./sse.md)).

- Custom WebSocket clients following the [Action Cable protocol][protocol].

AnyCable Pro also supports:

- Apollo GraphQL WebSocket clients ([more info](./apollo.md))

- HTTP streaming (long-polling) ([more info](./long_polling.md))

- OCPP WebSocket clients ([more info](./ocpp.md))

### Broadcasting messages

Finally, to broadcast messages to connected clients via the name pub/sub streams, you can use one of the provided [broadcast adapters](./broadcasting.md).

[anycable-client]: https://github.com/anycable/anycable-client
[protocol]: ../misc/action_cable_protocol.md
2 changes: 1 addition & 1 deletion docs/pubsub.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Although, we do not plan to sunset legacy, distributed adapters in the nearest f

By default, pub/sub is disabled (since the default broadcast adapter is legacy, fan-out Redis). To enable the pub/sub layer, you must provide the name of the provider via the `--pubsub` option.

You also need to enable a compatible broadcasting adapter. See [Broadcast adapters](/ruby/broadcast_adapters.md).
You also need to enable a compatible broadcasting adapter. See [broadcasting](./broadcasting.md).

**NOTE**: It's safe to enable `--pubsub` even if you're still using legacy broadcasting adapters (they do not pass messages through the pub/sub layer).

Expand Down
2 changes: 1 addition & 1 deletion docs/reliable_streams.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ INFO 2023-07-04T02:00:24.386Z consumer=s2IbkM context=broadcast id=s2IbkM provid
...
```

See [Broadcast adapters](/ruby/broadcast_adapters.md) for more information.
See [broadcasting documentation](./broadcasting.md) for more information.

Finally, to re-transmit _registered_ messages within a cluster, you MUST also configure a pub/sub adapter (via the `--pubsub` option). The command will look as follows:

Expand Down
Loading

0 comments on commit ec17f3e

Please sign in to comment.