anycable 0.5.2 → 0.6.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE.md +25 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +31 -0
- data/.rubocop.yml +22 -22
- data/.travis.yml +1 -2
- data/CHANGELOG.md +92 -0
- data/README.md +10 -58
- data/anycable.gemspec +10 -7
- data/benchmarks/.gitignore +1 -0
- data/benchmarks/2018-10-27.md +181 -0
- data/benchmarks/assets/2018-10-27-action-cable-rss.png +0 -0
- data/benchmarks/assets/2018-10-27-action-cable-rtt.png +0 -0
- data/benchmarks/assets/2018-10-27-anycable-rss.png +0 -0
- data/benchmarks/assets/2018-10-27-anycable-rtt.png +0 -0
- data/benchmarks/assets/2018-10-27-async-rss.png +0 -0
- data/benchmarks/assets/2018-10-27-async-rtt.png +0 -0
- data/benchmarks/assets/2018-10-27-falcon-cable-rss.png +0 -0
- data/benchmarks/assets/2018-10-27-falcon-cable-rtt.png +0 -0
- data/benchmarks/assets/2018-10-27-iodine-cable-rss.png +0 -0
- data/benchmarks/assets/2018-10-27-iodine-cable-rtt.png +0 -0
- data/benchmarks/assets/2018-10-27-plezi-rss.png +0 -0
- data/benchmarks/assets/2018-10-27-plezi-rtt.png +0 -0
- data/benchmarks/bench.png +0 -0
- data/benchmarks/benchmark.yml +12 -10
- data/benchmarks/hosts +2 -2
- data/benchmarks/rtt_plot.py +74 -0
- data/benchmarks/rtt_plot_test.py +16 -0
- data/benchmarks/servers.yml +25 -3
- data/bin/anycable +13 -0
- data/etc/bug_report_template.rb +1 -1
- data/lib/anycable.rb +53 -16
- data/lib/anycable/broadcast_adapters.rb +33 -0
- data/lib/anycable/broadcast_adapters/redis.rb +42 -0
- data/lib/anycable/cli.rb +323 -0
- data/lib/anycable/config.rb +91 -17
- data/lib/anycable/exceptions_handling.rb +31 -0
- data/lib/anycable/handler/capture_exceptions.rb +39 -0
- data/lib/anycable/health_server.rb +53 -31
- data/lib/anycable/middleware.rb +19 -0
- data/lib/anycable/middleware_chain.rb +58 -0
- data/lib/anycable/rpc/rpc_pb.rb +1 -1
- data/lib/anycable/rpc/rpc_services_pb.rb +1 -1
- data/lib/anycable/rpc_handler.rb +28 -26
- data/lib/anycable/server.rb +114 -39
- data/lib/anycable/socket.rb +1 -1
- data/lib/anycable/version.rb +2 -2
- metadata +45 -26
- data/lib/anycable/handler/exceptions_handling.rb +0 -43
- data/lib/anycable/pubsub.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f38ac8ce1378f75f5e1b4379c51254a346a2576fdb8326e6e2efb5d1820e857f
|
4
|
+
data.tar.gz: 0fa60623686123be319a92c8548b82ae4c3bf9ddadade0234cb3d69118599cd3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18014f2f1193f3e4f2984e4800b14097e131f9b93e413cada4f29805295c1b8153f75d9e7b00b843feb7e66c34c1ffa3e6c24d5494f3c0e516dc693ed39acb94
|
7
|
+
data.tar.gz: c27a42de1a8b6539a4906e75afe3cea4ac4a5e39c1a006ed06ba106f0b0f99d51b7052a93e54cbfe8ab72114f7b43f34f692214009038a82f7839e614e960b15
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<!--
|
2
|
+
First of all, thanks for your report/suggestion/whatever!
|
3
|
+
|
4
|
+
This template is for bug reports. If you are reporting a bug, please continue on. If you are here for another reason,
|
5
|
+
feel free to skip the rest of this template.
|
6
|
+
-->
|
7
|
+
|
8
|
+
### Tell us about your environment
|
9
|
+
|
10
|
+
**Ruby version:**
|
11
|
+
|
12
|
+
**`anycable` gem version:**
|
13
|
+
|
14
|
+
**`grpc` gem version:**
|
15
|
+
|
16
|
+
### What did you do?
|
17
|
+
|
18
|
+
### What did you expect to happen?
|
19
|
+
|
20
|
+
### What actually happened?
|
21
|
+
|
22
|
+
<!--
|
23
|
+
Please, provide reproduction script (using this template (https://github.com/anycable/anycable/blob/master/etc/bug_report_template.rb)
|
24
|
+
when submitting bugs if possible.
|
25
|
+
-->
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<!--
|
2
|
+
First of all, thanks for contributing!
|
3
|
+
|
4
|
+
If it's a typo fix or minor documentation update feel free to skip the rest of this template!
|
5
|
+
-->
|
6
|
+
|
7
|
+
<!--
|
8
|
+
If it's a bug fix, then link it to the issue, for example:
|
9
|
+
|
10
|
+
Fixes #xxx
|
11
|
+
-->
|
12
|
+
|
13
|
+
|
14
|
+
<!--
|
15
|
+
Otherwise, describe the changes:
|
16
|
+
|
17
|
+
### What is the purpose of this pull request?
|
18
|
+
|
19
|
+
### What changes did you make? (overview)
|
20
|
+
|
21
|
+
### Is there anything you'd like reviewers to focus on?
|
22
|
+
|
23
|
+
-->
|
24
|
+
|
25
|
+
<!--
|
26
|
+
Please ensure your PR is ready:
|
27
|
+
|
28
|
+
- Include tests for this change
|
29
|
+
- Add Changelog entry
|
30
|
+
- Update documentation for this change (if appropriate)
|
31
|
+
-->
|
data/.rubocop.yml
CHANGED
@@ -6,11 +6,9 @@ AllCops:
|
|
6
6
|
- 'spec/**/*.rb'
|
7
7
|
Exclude:
|
8
8
|
- 'bin/**/*'
|
9
|
-
- 'spec/dummy/**/*'
|
10
9
|
- 'tmp/**/*'
|
11
|
-
- 'bench/**/*'
|
12
|
-
- 'vendor/**/*'
|
13
10
|
- 'lib/anycable/rpc/**/*'
|
11
|
+
- 'vendor/**/*'
|
14
12
|
- 'gemfiles/**/*'
|
15
13
|
- 'Gemfile'
|
16
14
|
- 'Rakefile'
|
@@ -19,16 +17,7 @@ AllCops:
|
|
19
17
|
StyleGuideCopsOnly: false
|
20
18
|
TargetRubyVersion: 2.4
|
21
19
|
|
22
|
-
|
23
|
-
Enabled: false
|
24
|
-
|
25
|
-
Naming/UncommunicativeMethodParamName:
|
26
|
-
Enabled: false
|
27
|
-
|
28
|
-
Style/PercentLiteralDelimiters:
|
29
|
-
Enabled: false
|
30
|
-
|
31
|
-
Style/TrivialAccessors:
|
20
|
+
Rails:
|
32
21
|
Enabled: false
|
33
22
|
|
34
23
|
Style/Documentation:
|
@@ -36,7 +25,7 @@ Style/Documentation:
|
|
36
25
|
- 'spec/**/*.rb'
|
37
26
|
|
38
27
|
Style/StringLiterals:
|
39
|
-
|
28
|
+
EnforcedStyle: double_quotes
|
40
29
|
|
41
30
|
Layout/SpaceInsideStringInterpolation:
|
42
31
|
EnforcedStyle: no_space
|
@@ -45,11 +34,13 @@ Style/BlockDelimiters:
|
|
45
34
|
Exclude:
|
46
35
|
- 'spec/**/*.rb'
|
47
36
|
|
48
|
-
|
49
|
-
|
37
|
+
Style/ClassAndModuleChildren:
|
38
|
+
Exclude:
|
39
|
+
- 'spec/**/*.rb'
|
50
40
|
|
51
|
-
|
52
|
-
|
41
|
+
Style/ParallelAssignment:
|
42
|
+
Exclude:
|
43
|
+
- 'spec/**/*.rb'
|
53
44
|
|
54
45
|
Metrics/MethodLength:
|
55
46
|
Exclude:
|
@@ -60,12 +51,21 @@ Metrics/LineLength:
|
|
60
51
|
Exclude:
|
61
52
|
- 'spec/**/*.rb'
|
62
53
|
|
54
|
+
Metrics/AbcSize:
|
55
|
+
Exclude:
|
56
|
+
- 'spec/**/*.rb'
|
57
|
+
|
63
58
|
Metrics/BlockLength:
|
64
59
|
Exclude:
|
65
60
|
- 'spec/**/*.rb'
|
66
61
|
|
67
|
-
|
68
|
-
|
62
|
+
Metrics/CyclomaticComplexity:
|
63
|
+
Exclude:
|
64
|
+
- 'spec/**/*.rb'
|
65
|
+
|
66
|
+
Metrics/PerceivedComplexity:
|
67
|
+
Exclude:
|
68
|
+
- 'spec/**/*.rb'
|
69
69
|
|
70
|
-
|
71
|
-
Enabled: false
|
70
|
+
Lint/HandleExceptions:
|
71
|
+
Enabled: false
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,98 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.6.0-dev
|
6
|
+
|
7
|
+
### Features
|
8
|
+
|
9
|
+
#### Broadcast adapters
|
10
|
+
|
11
|
+
AnyCable allows you to use custom broadcasting adapters (Redis is used by default):
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
# Specify by name (tries to load `AnyCable::BroadcastAdapters::MyAdapter` from
|
15
|
+
# "anycable/broadcast_adapters/my_adapter")
|
16
|
+
AnyCable.broadcast_adapter = :my_adapter, { option: "value" }
|
17
|
+
# or provide an instance (should respond_to #broadcast)
|
18
|
+
AnyCable.broadcast_adapter = MyAdapter.new
|
19
|
+
```
|
20
|
+
|
21
|
+
**Breaking:** to use Redis adapter you must ensure that it is present in your Gemfile; AnyCable gem doesn't have `redis` as a dependency anymore.
|
22
|
+
|
23
|
+
#### CLI
|
24
|
+
|
25
|
+
AnyCable now ships with a CLI–`anycable`.
|
26
|
+
|
27
|
+
Use it to run a gRPC server:
|
28
|
+
|
29
|
+
```sh
|
30
|
+
# run anycable and load app from app.rb
|
31
|
+
bundle exec anycable -r app.rb
|
32
|
+
# or
|
33
|
+
bundle exec anycable --require app.rb
|
34
|
+
```
|
35
|
+
|
36
|
+
All configuration options are also supported as CLI options (see `anycable -h` for more information).
|
37
|
+
|
38
|
+
The only required options is the application file to load (`-r/--require`).
|
39
|
+
|
40
|
+
You can omit it if you want to load an app form `./config/environment.rb` (e.g. with Rails) or `./config/anycable.rb`.
|
41
|
+
|
42
|
+
AnyCable CLI also allows you to run a separate command (process) from within a RPC server:
|
43
|
+
|
44
|
+
```sh
|
45
|
+
$ bundle exec anycable --server-command "anycable-go -p 3334"
|
46
|
+
```
|
47
|
+
|
48
|
+
#### Configuration
|
49
|
+
|
50
|
+
- Default server host is changed from `localhost:50051` to `0.0.0.0:50051`
|
51
|
+
- Expose gRPC server parameters via `rpc_*` config params:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
AnyCable.configure do |config|
|
55
|
+
config.rpc_pool_size = 120
|
56
|
+
config.rpc_max_waiting_requests = 10
|
57
|
+
# etc
|
58
|
+
end
|
59
|
+
```
|
60
|
+
- `REDIS_URL` env is used by default if present (and no `ANYCABLE_REDIS_URL` specified)
|
61
|
+
- Make HTTP health check url configurable
|
62
|
+
- Add ability to pass Redis Sentinel config as array of string.
|
63
|
+
|
64
|
+
Now it's possible to pass Sentinel configuration via env vars:
|
65
|
+
|
66
|
+
```sh
|
67
|
+
ANYCABLE_REDIS_SENTINELS=127.0.0.1:26380,127.0.0.1:26381 bundle exec anycable
|
68
|
+
```
|
69
|
+
|
70
|
+
#### Other
|
71
|
+
|
72
|
+
- Added middlewares support
|
73
|
+
|
74
|
+
See [docs](https://docs.anycable.io/#/./middlewares).
|
75
|
+
|
76
|
+
- Added gRPC health checker.
|
77
|
+
|
78
|
+
See [docs](https://docs.anycable.io/#/./health_checking).
|
79
|
+
|
80
|
+
### API changes
|
81
|
+
|
82
|
+
**NOTE**: the old API is still working but deprecated (you'll see a notice).
|
83
|
+
|
84
|
+
- Use `AnyCable` instead of `Anycable`
|
85
|
+
|
86
|
+
- New API for registering error handlers:
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
AnyCable.capture_exception do |ex|
|
90
|
+
Honeybadger.notify(ex)
|
91
|
+
end
|
92
|
+
```
|
93
|
+
|
94
|
+
- `AnyCable::Server.start` is deprecated
|
95
|
+
|
96
|
+
|
5
97
|
## 0.5.2 (2018-09-06)
|
6
98
|
|
7
99
|
- [#48](https://github.com/anycable/anycable/pull/48) Add HTTP health server ([@DarthSim][])
|
data/README.md
CHANGED
@@ -1,40 +1,27 @@
|
|
1
|
-
[![GitPitch](https://gitpitch.com/assets/badge.svg)](https://gitpitch.com/anycable/anycable/master?grs=github) [![Gem Version](https://badge.fury.io/rb/anycable.svg)](https://rubygems.org/gems/anycable) [![Build Status](https://travis-ci.org/anycable/anycable.svg?branch=master)](https://travis-ci.org/anycable/anycable)
|
1
|
+
[![GitPitch](https://gitpitch.com/assets/badge.svg)](https://gitpitch.com/anycable/anycable/master?grs=github) [![Gem Version](https://badge.fury.io/rb/anycable.svg)](https://rubygems.org/gems/anycable) [![Build Status](https://travis-ci.org/anycable/anycable.svg?branch=master)](https://travis-ci.org/anycable/anycable)
|
2
2
|
[![Gitter](https://img.shields.io/badge/gitter-join%20chat%20%E2%86%92-brightgreen.svg)](https://gitter.im/anycable/Lobby)
|
3
|
+
[![Documentation](https://img.shields.io/badge/docs-link-brightgreen.svg)](https://docs.anycable.io)
|
3
4
|
|
4
|
-
#
|
5
|
+
# AnyCable
|
6
|
+
|
7
|
+
<img align="right" height="150" width="129"
|
8
|
+
title="AnyCable logo" src="https://docs.anycable.io/assets/images/logo.svg">
|
5
9
|
|
6
10
|
AnyCable allows you to use any WebSocket server (written in any language) as a replacement for your Ruby server (such as Faye, ActionCable, etc).
|
7
11
|
|
8
12
|
AnyCable uses ActionCable protocol, so you can use ActionCable [JavaScript client](https://www.npmjs.com/package/actioncable) without any monkey-patching.
|
9
13
|
|
10
|
-
**NOTE**: Since version 0.4.0 this repository contains only core functionality and cannot be used separately as is.
|
11
|
-
Rails plug-n-play integration has been extracted to [anycable-rails](https://github.com/anycable/anycable-rails) gem.
|
12
|
-
|
13
14
|
<a href="https://evilmartians.com/">
|
14
15
|
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
|
15
16
|
|
16
17
|
## Requirements
|
17
18
|
|
18
|
-
- Ruby >= 2.
|
19
|
+
- Ruby >= 2.4
|
19
20
|
- Redis (for brodcasting, [discuss other options](https://github.com/anycable/anycable/issues/2) with us!)
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
For MacOS there is also [the same problem](https://github.com/google/protobuf/issues/4098) with `google-protobuf` that can be solved
|
24
|
-
the following way:
|
25
|
-
|
26
|
-
```ruby
|
27
|
-
# Gemfile
|
28
|
-
git 'https://github.com/google/protobuf' do
|
29
|
-
gem 'google-protobuf'
|
30
|
-
end
|
31
|
-
```
|
32
|
-
|
33
|
-
## How It Works?
|
34
|
-
|
35
|
-
![](https://s3.amazonaws.com/anycable/Scheme.png)
|
22
|
+
## Usage
|
36
23
|
|
37
|
-
|
24
|
+
Check out our 📑 [Documentation](https://docs.anycable.io).
|
38
25
|
|
39
26
|
## Links
|
40
27
|
|
@@ -54,46 +41,11 @@ Read our [Wiki](https://github.com/anycable/anycable/wiki) for more.
|
|
54
41
|
|
55
42
|
- RailsClub Moscow 2016 [slides](https://speakerdeck.com/palkan/railsclub-moscow-2016-anycable) and [video](https://www.youtube.com/watch?v=-k7GQKuBevY&list=PLiWUIs1hSNeOXZhotgDX7Y7qBsr24cu7o&index=4) (RU)
|
56
43
|
|
57
|
-
|
58
44
|
## Compatible WebSocket servers
|
59
45
|
|
60
|
-
- [
|
46
|
+
- [AnyCable Go](https://github.com/anycable/anycable-go)
|
61
47
|
- [ErlyCable](https://github.com/anycable/erlycable)
|
62
48
|
|
63
|
-
## Configuration
|
64
|
-
|
65
|
-
Anycable uses [anyway_config](https://github.com/palkan/anyway_config), thus it is also possible to set configuration variables through `secrets.yml` or environment vars.
|
66
|
-
|
67
|
-
### Example with redis sentinel
|
68
|
-
|
69
|
-
```yaml
|
70
|
-
rpc_host: "localhost:50123"
|
71
|
-
redis_url: "redis://redis-1-1:6379/2"
|
72
|
-
redis_sentinels:
|
73
|
-
- { host: 'redis-1-1', port: 26379 }
|
74
|
-
- { host: 'redis-1-2', port: 26379 }
|
75
|
-
- { host: 'redis-1-3', port: 26379 }
|
76
|
-
```
|
77
|
-
|
78
|
-
## ActionCable Compatibility
|
79
|
-
|
80
|
-
This is the compatibility list for the AnyCable gem, not for AnyCable servers (which may not support some of the features yet).
|
81
|
-
|
82
|
-
Feature | Status
|
83
|
-
-------------------------|--------
|
84
|
-
Connection Identifiers | +
|
85
|
-
Connection Request (cookies, params) | +
|
86
|
-
Disconnect Handling | +
|
87
|
-
Subscribe to channels | +
|
88
|
-
Parameterized subscriptions | +
|
89
|
-
Unsubscribe from channels | +
|
90
|
-
[Subscription Instance Variables](http://edgeapi.rubyonrails.org/classes/ActionCable/Channel/Streams.html) | -
|
91
|
-
Performing Channel Actions | +
|
92
|
-
Streaming | +
|
93
|
-
[Custom stream callbacks](http://edgeapi.rubyonrails.org/classes/ActionCable/Channel/Streams.html) | -
|
94
|
-
Broadcasting | +
|
95
|
-
Custom pubsub adapter | Only redis
|
96
|
-
|
97
49
|
## Build
|
98
50
|
|
99
51
|
- Install required GRPC gems:
|
data/anycable.gemspec
CHANGED
@@ -6,27 +6,30 @@ require 'anycable/version'
|
|
6
6
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
8
|
spec.name = "anycable"
|
9
|
-
spec.version =
|
9
|
+
spec.version = AnyCable::VERSION
|
10
10
|
spec.authors = ["palkan"]
|
11
11
|
spec.email = ["dementiev.vm@gmail.com"]
|
12
12
|
|
13
|
-
spec.summary = "
|
14
|
-
spec.description = "
|
13
|
+
spec.summary = "AnyCable is a polyglot replacement for ActionCable-compatible servers"
|
14
|
+
spec.description = "AnyCable is a polyglot replacement for ActionCable-compatible servers"
|
15
15
|
spec.homepage = "http://github.com/anycable/anycable"
|
16
16
|
spec.license = "MIT"
|
17
17
|
|
18
|
+
spec.executables = ["anycable"]
|
18
19
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
19
20
|
spec.require_paths = ["lib"]
|
20
21
|
|
21
|
-
spec.
|
22
|
-
spec.add_dependency "grpc", "~> 1.6"
|
23
|
-
spec.add_dependency "redis", ">= 3.2"
|
22
|
+
spec.required_ruby_version = '>= 2.4.0'
|
24
23
|
|
24
|
+
spec.add_dependency "anyway_config", "~> 1.4.1"
|
25
|
+
spec.add_dependency "grpc", "~> 1.15"
|
26
|
+
|
27
|
+
spec.add_development_dependency "redis", ">= 4.0"
|
25
28
|
spec.add_development_dependency "bundler", "~> 1"
|
26
29
|
spec.add_development_dependency "rake", ">= 10.0"
|
27
30
|
spec.add_development_dependency "rack", "~> 2.0"
|
28
31
|
spec.add_development_dependency "rspec", ">= 3.5"
|
29
|
-
spec.add_development_dependency "rubocop", "~> 0.
|
32
|
+
spec.add_development_dependency "rubocop", "~> 0.60.0"
|
30
33
|
spec.add_development_dependency "simplecov", ">= 0.3.8"
|
31
34
|
spec.add_development_dependency "pry-byebug"
|
32
35
|
end
|
data/benchmarks/.gitignore
CHANGED
@@ -0,0 +1,181 @@
|
|
1
|
+
# WebSocket Shootout Benchmark (2018-10-27)
|
2
|
+
|
3
|
+
Code: https://github.com/palkan/websocket-shootout
|
4
|
+
|
5
|
+
Client/Server instances: c3.2xlarge (8 vCPU, 15 GiB RAM).
|
6
|
+
|
7
|
+
Ruby: 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin16]
|
8
|
+
Rails: 5.2.0 / 6.0.0.aplha (this [PR](https://github.com/rails/rails/pull/33295))
|
9
|
+
|
10
|
+
The benchmark measures broadcasting RTT for 10k clients and the memory usage.
|
11
|
+
|
12
|
+
Memory usage charts were captured with [psrecord](https://github.com/astrofrog/psrecord):
|
13
|
+
|
14
|
+
```sh
|
15
|
+
psrecord <pid> --include-children --plot plot.png
|
16
|
+
```
|
17
|
+
|
18
|
+
## Action Cable + Puma (8 workers)
|
19
|
+
|
20
|
+
Server: `WEB_CONCURRENCY=8 bundle exec rails s -p 3334 -e production`
|
21
|
+
|
22
|
+
```
|
23
|
+
$ bin/websocket-bench broadcast --concurrent 8 --sample-size 100 --step-size 1000 --payload-padding 200 --total-steps 10 --origin http://0.0.0.0 ws://172.31.21.207:3334/cable --server-type=actioncable
|
24
|
+
|
25
|
+
clients: 1000 95per-rtt: 2470ms min-rtt: 1ms median-rtt: 518ms max-rtt: 2893ms
|
26
|
+
clients: 2000 95per-rtt: 3066ms min-rtt: 1ms median-rtt: 1045ms max-rtt: 3878ms
|
27
|
+
clients: 3000 95per-rtt: 3785ms min-rtt: 1ms median-rtt: 2071ms max-rtt: 4211ms
|
28
|
+
clients: 4000 95per-rtt: 5141ms min-rtt: 1ms median-rtt: 2363ms max-rtt: 6042ms
|
29
|
+
clients: 5000 95per-rtt: 9477ms min-rtt: 1ms median-rtt: 3283ms max-rtt: 10000ms
|
30
|
+
clients: 6000 95per-rtt: 7038ms min-rtt: 1ms median-rtt: 3898ms max-rtt: 8684ms
|
31
|
+
clients: 7000 95per-rtt: 8517ms min-rtt: 2ms median-rtt: 4108ms max-rtt: 8436ms
|
32
|
+
clients: 8000 95per-rtt: 9105ms min-rtt: 2ms median-rtt: 5387ms max-rtt: 9166ms
|
33
|
+
clients: 9000 95per-rtt: 10064ms min-rtt: 1ms median-rtt: 5335ms max-rtt: 10108ms
|
34
|
+
clients: 10000 95per-rtt: 15766ms min-rtt: 2ms median-rtt: 5921ms max-rtt: 17907ms
|
35
|
+
```
|
36
|
+
|
37
|
+
![](assets/2018-10-27-action-cable-rtt.png)
|
38
|
+
|
39
|
+
![](assets/2018-10-27-action-cable-rss.png)
|
40
|
+
|
41
|
+
## Action Cable + Iodine (8 workers & 16 threads)
|
42
|
+
|
43
|
+
Server: `bundle exec iodine -p 3334 -w 8 -t 16`
|
44
|
+
|
45
|
+
```
|
46
|
+
$ bin/websocket-bench broadcast --concurrent 8 --sample-size 100 --step-size 1000 --payload-padding 200 --total-steps 10 --origin http://0.0.0.0 ws://172.31.21.207:3334/cable --server-type=actioncable
|
47
|
+
|
48
|
+
clients: 1000 95per-rtt: 2354ms min-rtt: 1ms median-rtt: 798ms max-rtt: 2944ms
|
49
|
+
clients: 2000 95per-rtt: 3199ms min-rtt: 2ms median-rtt: 2068ms max-rtt: 3603ms
|
50
|
+
clients: 3000 95per-rtt: 4808ms min-rtt: 2ms median-rtt: 3226ms max-rtt: 6016ms
|
51
|
+
clients: 4000 95per-rtt: 6628ms min-rtt: 1ms median-rtt: 4511ms max-rtt: 7520ms
|
52
|
+
clients: 5000 95per-rtt: 7761ms min-rtt: 1ms median-rtt: 5592ms max-rtt: 8828ms
|
53
|
+
clients: 6000 95per-rtt: 17042ms min-rtt: 1ms median-rtt: 4557ms max-rtt: 18245ms
|
54
|
+
clients: 7000 95per-rtt: 12331ms min-rtt: 1ms median-rtt: 8355ms max-rtt: 13525ms
|
55
|
+
clients: 8000 95per-rtt: 16785ms min-rtt: 2ms median-rtt: 6217ms max-rtt: 17609ms
|
56
|
+
clients: 9000 95per-rtt: 18438ms min-rtt: 1ms median-rtt: 1111ms max-rtt: 18848ms
|
57
|
+
clients: 10000 95per-rtt: 19034ms min-rtt: 1ms median-rtt: 11235ms max-rtt: 24343ms
|
58
|
+
```
|
59
|
+
|
60
|
+
![](assets/2018-10-27-iodine-cable-rtt.png)
|
61
|
+
|
62
|
+
![](assets/2018-10-27-iodine-cable-rss.png)
|
63
|
+
|
64
|
+
|
65
|
+
## Action Cable + Falcon (8 workers)
|
66
|
+
|
67
|
+
Server: `RAILS_ENV=production bundle exec falcon serve -b http://0.0.0.0:3334`
|
68
|
+
|
69
|
+
```
|
70
|
+
$ bin/websocket-bench broadcast --concurrent 8 --sample-size 100 --step-size 1000 --payload-padding 200 --total-steps 10 --origin http://0.0.0.0 ws://172.31.21.207:3334/cable --server-type=actioncable
|
71
|
+
|
72
|
+
|
73
|
+
clients: 1000 95per-rtt: 1957ms min-rtt: 1ms median-rtt: 766ms max-rtt: 2077ms
|
74
|
+
clients: 2000 95per-rtt: 5225ms min-rtt: 1ms median-rtt: 624ms max-rtt: 5969ms
|
75
|
+
clients: 3000 95per-rtt: 6358ms min-rtt: 2ms median-rtt: 1205ms max-rtt: 7116ms
|
76
|
+
clients: 4000 95per-rtt: 8878ms min-rtt: 1ms median-rtt: 1152ms max-rtt: 10167ms
|
77
|
+
clients: 5000 95per-rtt: 8829ms min-rtt: 1ms median-rtt: 2368ms max-rtt: 9792ms
|
78
|
+
clients: 6000 95per-rtt: 10831ms min-rtt: 1ms median-rtt: 2892ms max-rtt: 12766ms
|
79
|
+
clients: 7000 95per-rtt: 12760ms min-rtt: 1ms median-rtt: 5229ms max-rtt: 14713ms
|
80
|
+
clients: 8000 95per-rtt: 15512ms min-rtt: 1ms median-rtt: 4843ms max-rtt: 16353ms
|
81
|
+
clients: 9000 95per-rtt: 20176ms min-rtt: 1ms median-rtt: 4919ms max-rtt: 22529ms
|
82
|
+
clients: 10000 95per-rtt: 19865ms min-rtt: 1ms median-rtt: 4733ms max-rtt: 20686ms
|
83
|
+
```
|
84
|
+
|
85
|
+
![](assets/2018-10-27-falcon-cable-rtt.png)
|
86
|
+
|
87
|
+
![](assets/2018-10-27-falcon-cable-rss.png)
|
88
|
+
|
89
|
+
**NOTE**: for some reason `psrecord` reports negative RSS usage when Falcon starts (almost every run).
|
90
|
+
|
91
|
+
## Action Cable + AnyCable-Go 0.6.0.alpha
|
92
|
+
|
93
|
+
**NOTE**: this benchmark has twice more steps (i.e. 20k instead of 10k).
|
94
|
+
|
95
|
+
Server: `ANYCABLE_GO_BIN="anycable-go-0.6.0-alpha" ANYCABLE_PORT="3334" bundle exec bin/anycable`
|
96
|
+
|
97
|
+
```
|
98
|
+
$ bin/websocket-bench broadcast --concurrent 8 --sample-size 100 --step-size 1000 --payload-padding 200 --total-steps 10 --origin http://0.0.0.0 ws://172.31.21.207:3334/cable --server-type=actioncable
|
99
|
+
|
100
|
+
clients: 1000 95per-rtt: 200ms min-rtt: 4ms median-rtt: 30ms max-rtt: 261ms
|
101
|
+
clients: 2000 95per-rtt: 284ms min-rtt: 2ms median-rtt: 51ms max-rtt: 380ms
|
102
|
+
clients: 3000 95per-rtt: 490ms min-rtt: 5ms median-rtt: 80ms max-rtt: 651ms
|
103
|
+
clients: 4000 95per-rtt: 601ms min-rtt: 3ms median-rtt: 63ms max-rtt: 2114ms
|
104
|
+
clients: 5000 95per-rtt: 678ms min-rtt: 11ms median-rtt: 123ms max-rtt: 2946ms
|
105
|
+
clients: 6000 95per-rtt: 933ms min-rtt: 12ms median-rtt: 146ms max-rtt: 1815ms
|
106
|
+
clients: 7000 95per-rtt: 1034ms min-rtt: 17ms median-rtt: 163ms max-rtt: 4282ms
|
107
|
+
clients: 8000 95per-rtt: 866ms min-rtt: 5ms median-rtt: 205ms max-rtt: 1631ms
|
108
|
+
clients: 9000 95per-rtt: 1297ms min-rtt: 8ms median-rtt: 230ms max-rtt: 2380ms
|
109
|
+
clients: 10000 95per-rtt: 1075ms min-rtt: 4ms median-rtt: 363ms max-rtt: 2718ms
|
110
|
+
clients: 11000 95per-rtt: 1382ms min-rtt: 2ms median-rtt: 263ms max-rtt: 4310ms
|
111
|
+
clients: 12000 95per-rtt: 1448ms min-rtt: 4ms median-rtt: 205ms max-rtt: 1686ms
|
112
|
+
clients: 13000 95per-rtt: 1503ms min-rtt: 11ms median-rtt: 322ms max-rtt: 1879ms
|
113
|
+
clients: 14000 95per-rtt: 2662ms min-rtt: 4ms median-rtt: 318ms max-rtt: 5604ms
|
114
|
+
clients: 15000 95per-rtt: 2113ms min-rtt: 7ms median-rtt: 353ms max-rtt: 2484ms
|
115
|
+
clients: 16000 95per-rtt: 2930ms min-rtt: 3ms median-rtt: 383ms max-rtt: 4021ms
|
116
|
+
clients: 17000 95per-rtt: 3349ms min-rtt: 2ms median-rtt: 386ms max-rtt: 5844ms
|
117
|
+
clients: 18000 95per-rtt: 2797ms min-rtt: 4ms median-rtt: 361ms max-rtt: 6973ms
|
118
|
+
clients: 19000 95per-rtt: 3534ms min-rtt: 6ms median-rtt: 448ms max-rtt: 5482ms
|
119
|
+
clients: 20000 95per-rtt: 2892ms min-rtt: 3ms median-rtt: 399ms max-rtt: 4639ms
|
120
|
+
```
|
121
|
+
|
122
|
+
![](assets/2018-10-27-anycable-rtt.png)
|
123
|
+
|
124
|
+
![](assets/2018-10-27-anycable-rss.png)
|
125
|
+
|
126
|
+
**NOTE:** RSS were captured only for `anycable-go`
|
127
|
+
|
128
|
+
## Falcon + `async-websocket` (4 workers)
|
129
|
+
|
130
|
+
```
|
131
|
+
$ bin/websocket-bench broadcast --concurrent 8 --sample-size 100 --step-size 1000 --payload-padding 200 --total-steps 10 ws://172.31.21.207:3334/cable
|
132
|
+
|
133
|
+
clients: 1000 95per-rtt: 964ms min-rtt: 5ms median-rtt: 542ms max-rtt: 971ms
|
134
|
+
clients: 2000 95per-rtt: 4912ms min-rtt: 1ms median-rtt: 2796ms max-rtt: 5247ms
|
135
|
+
clients: 3000 95per-rtt: 3263ms min-rtt: 6ms median-rtt: 891ms max-rtt: 4166ms
|
136
|
+
clients: 4000 95per-rtt: 1778ms min-rtt: 1ms median-rtt: 490ms max-rtt: 2115ms
|
137
|
+
clients: 5000 95per-rtt: 2294ms min-rtt: 5ms median-rtt: 513ms max-rtt: 2807ms
|
138
|
+
clients: 6000 95per-rtt: 2802ms min-rtt: 9ms median-rtt: 426ms max-rtt: 3263ms
|
139
|
+
clients: 7000 95per-rtt: 4196ms min-rtt: 7ms median-rtt: 485ms max-rtt: 5377ms
|
140
|
+
clients: 8000 95per-rtt: 4741ms min-rtt: 4ms median-rtt: 772ms max-rtt: 5005ms
|
141
|
+
clients: 9000 95per-rtt: 6207ms min-rtt: 2ms median-rtt: 972ms max-rtt: 7296ms
|
142
|
+
clients: 10000 95per-rtt: 5468ms min-rtt: 35ms median-rtt: 887ms max-rtt: 6420ms
|
143
|
+
```
|
144
|
+
|
145
|
+
![](assets/2018-10-27-async-rtt.png)
|
146
|
+
|
147
|
+
![](assets/2018-10-27-async-rss.png)
|
148
|
+
|
149
|
+
|
150
|
+
## Iodine + Plezi (4 workers & 16 threads)
|
151
|
+
|
152
|
+
**NOTE**: this benchmark has twice more steps (i.e. 20k instead of 10k).
|
153
|
+
|
154
|
+
```
|
155
|
+
$ bin/websocket-bench broadcast --concurrent 8 --sample-size 100 --step-size 1000 --payload-padding 200 --total-steps 10 ws://172.31.21.207:3334/cable
|
156
|
+
|
157
|
+
clients: 1000 95per-rtt: 119ms min-rtt: 0ms median-rtt: 19ms max-rtt: 348ms
|
158
|
+
clients: 2000 95per-rtt: 321ms min-rtt: 1ms median-rtt: 45ms max-rtt: 634ms
|
159
|
+
clients: 3000 95per-rtt: 392ms min-rtt: 0ms median-rtt: 66ms max-rtt: 1543ms
|
160
|
+
clients: 4000 95per-rtt: 424ms min-rtt: 1ms median-rtt: 128ms max-rtt: 617ms
|
161
|
+
clients: 5000 95per-rtt: 747ms min-rtt: 1ms median-rtt: 126ms max-rtt: 1252ms
|
162
|
+
clients: 6000 95per-rtt: 659ms min-rtt: 0ms median-rtt: 153ms max-rtt: 1621ms
|
163
|
+
clients: 7000 95per-rtt: 839ms min-rtt: 0ms median-rtt: 205ms max-rtt: 1041ms
|
164
|
+
clients: 8000 95per-rtt: 995ms min-rtt: 1ms median-rtt: 221ms max-rtt: 1534ms
|
165
|
+
clients: 9000 95per-rtt: 1072ms min-rtt: 0ms median-rtt: 234ms max-rtt: 5679ms
|
166
|
+
clients: 10000 95per-rtt: 1030ms min-rtt: 0ms median-rtt: 298ms max-rtt: 3998ms
|
167
|
+
clients: 11000 95per-rtt: 1052ms min-rtt: 1ms median-rtt: 302ms max-rtt: 5539ms
|
168
|
+
clients: 12000 95per-rtt: 1017ms min-rtt: 0ms median-rtt: 332ms max-rtt: 5342ms
|
169
|
+
clients: 13000 95per-rtt: 1528ms min-rtt: 1ms median-rtt: 391ms max-rtt: 2488ms
|
170
|
+
clients: 14000 95per-rtt: 1411ms min-rtt: 1ms median-rtt: 418ms max-rtt: 1810ms
|
171
|
+
clients: 15000 95per-rtt: 1674ms min-rtt: 1ms median-rtt: 428ms max-rtt: 2154ms
|
172
|
+
clients: 16000 95per-rtt: 1436ms min-rtt: 1ms median-rtt: 463ms max-rtt: 7788ms
|
173
|
+
clients: 17000 95per-rtt: 1816ms min-rtt: 0ms median-rtt: 449ms max-rtt: 7299ms
|
174
|
+
clients: 18000 95per-rtt: 2025ms min-rtt: 1ms median-rtt: 492ms max-rtt: 4009ms
|
175
|
+
clients: 19000 95per-rtt: 1740ms min-rtt: 2ms median-rtt: 522ms max-rtt: 3834ms
|
176
|
+
clients: 20000 95per-rtt: 2017ms min-rtt: 2ms median-rtt: 591ms max-rtt: 3579ms
|
177
|
+
```
|
178
|
+
|
179
|
+
![](assets/2018-10-27-plezi-rtt.png)
|
180
|
+
|
181
|
+
![](assets/2018-10-27-plezi-rss.png)
|