anycable 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +1 -6
- data/CHANGELOG.md +10 -0
- data/MIT-LICENSE +1 -1
- data/README.md +6 -64
- data/anycable.gemspec +3 -3
- data/bin/console +1 -2
- data/lib/anycable/config.rb +2 -1
- data/lib/anycable/pubsub.rb +1 -0
- data/lib/anycable/rpc/rpc_services.rb +1 -3
- data/lib/anycable/rpc_handler.rb +53 -64
- data/lib/anycable/server.rb +0 -1
- data/lib/anycable/version.rb +1 -1
- data/lib/anycable.rb +25 -12
- data/protos/rpc.proto +1 -3
- metadata +21 -31
- data/gemfiles/rails5.gemfile +0 -6
- data/gemfiles/railsmaster.gemfile +0 -6
- data/lib/anycable/actioncable/channel.rb +0 -43
- data/lib/anycable/actioncable/connection.rb +0 -95
- data/lib/anycable/actioncable/server.rb +0 -14
- data/lib/anycable/refinements/subscriptions.rb +0 -14
- data/lib/generators/anycable/USAGE +0 -7
- data/lib/generators/anycable/anycable_generator.rb +0 -11
- data/lib/generators/anycable/templates/script +0 -8
- data/lib/tasks/anycable_tasks.rake +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2589605d172fda191b1733259d1205e474754285
|
4
|
+
data.tar.gz: 444266a714ada061f08f699ffafd61f08edd6e59
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cdcdca3db177557e4d144d0af7b8d8a643ad2dfe1c3728e7be95aaa84494e21f38e7bda57d61c3f617f62b1e7302be2c19a0b07b4e5795fb213b898bd8279280
|
7
|
+
data.tar.gz: 669cdc0c8b3d83114a1a0f5acf2e7a1686e70ba2a739a1acdcbdc01cdcbc5122e56eab907f26aefe49cf227a631a047f17a8d817c75acfa429d6654f9b9e00c8
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
+
## 0.4.0
|
4
|
+
|
5
|
+
- Refactor RPC API. ([@palkan][])
|
6
|
+
|
7
|
+
Replace `Subscribe`, `Unsubscribe` and `Perform` methods with `Command` method.
|
8
|
+
|
9
|
+
- Extract Rails functionality to separate gem. ([@palkan][])
|
10
|
+
|
11
|
+
All Rails specifics now live here https://github.com/anycable/anycable-rails.
|
12
|
+
|
3
13
|
## 0.3.0 (2016-12-28)
|
4
14
|
|
5
15
|
- Handle `Disconnect` requests. ([@palkan][])
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -3,25 +3,20 @@
|
|
3
3
|
|
4
4
|
# Anycable
|
5
5
|
|
6
|
-
AnyCable allows you to use any WebSocket server (written in any language) as a replacement for
|
6
|
+
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
7
|
|
8
|
-
|
8
|
+
AnyCable uses ActionCable protocol, so you can use ActionCable [JavaScript client](https://www.npmjs.com/package/actioncable) without any monkey-patching.
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
[Example Application](https://github.com/anycable/anycable_demo)
|
13
|
-
|
14
|
-
**NOTE**: MacOS users, please, beware of [Sierra-related bug](
|
15
|
-
https://github.com/grpc/grpc/issues/8403).
|
10
|
+
**NOTE**: Since version 0.4.0 this repository contains only core functionality and connot be used separately as is.
|
11
|
+
Rails plug-n-play integration has been extracted to [anycable-rails](https://github.com/anycable/anycable-rails) gem.
|
16
12
|
|
17
13
|
<a href="https://evilmartians.com/">
|
18
14
|
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
|
19
15
|
|
20
16
|
## Requirements
|
21
17
|
|
22
|
-
- Ruby ~> 2.3;
|
23
|
-
-
|
24
|
-
- Redis
|
18
|
+
- Ruby ~> 2.3, < 2.4 (follow [this issue](https://github.com/grpc/grpc/issues/9296) for Ruby 2.4 support);
|
19
|
+
- Redis (for brodcasting, [discuss other options](https://github.com/anycable/anycable/issues/2) with us!)
|
25
20
|
|
26
21
|
## How It Works?
|
27
22
|
|
@@ -39,62 +34,10 @@ https://github.com/grpc/grpc/issues/8403).
|
|
39
34
|
- [Anycable Go](https://github.com/anycable/anycable-go)
|
40
35
|
- [ErlyCable](https://github.com/anycable/erlycable)
|
41
36
|
|
42
|
-
|
43
|
-
## Installation
|
44
|
-
|
45
|
-
Add Anycable to your application's Gemfile:
|
46
|
-
|
47
|
-
```ruby
|
48
|
-
gem 'anycable', group: :production
|
49
|
-
```
|
50
|
-
|
51
|
-
And then run:
|
52
|
-
|
53
|
-
```shell
|
54
|
-
rails generate anycable
|
55
|
-
```
|
56
|
-
|
57
|
-
to create executable.
|
58
|
-
|
59
|
-
You can use _built-in_ ActionCable for test and development.
|
60
|
-
|
61
37
|
## Configuration
|
62
38
|
|
63
|
-
Add `config/anycable.yml`if you want to override defaults (see below):
|
64
|
-
|
65
|
-
```yml
|
66
|
-
production:
|
67
|
-
# gRPC server host
|
68
|
-
rpc_host: "localhost:50051"
|
69
|
-
# Redis URL (for broadcasting)
|
70
|
-
redis_url: "redis://localhost:6379/2"
|
71
|
-
# Redis channel name
|
72
|
-
redis_channel: "anycable"
|
73
|
-
|
74
|
-
```
|
75
|
-
|
76
39
|
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.
|
77
40
|
|
78
|
-
## Usage
|
79
|
-
|
80
|
-
Run Anycable RPC server:
|
81
|
-
|
82
|
-
```ruby
|
83
|
-
./bin/anycable
|
84
|
-
```
|
85
|
-
|
86
|
-
and also run AnyCable-compatible WebSocket server, e.g. [anycable-go](https://github.com/anycable/anycable-go):
|
87
|
-
|
88
|
-
```sh
|
89
|
-
anycable-go -addr='localhost:3334'
|
90
|
-
```
|
91
|
-
|
92
|
-
Don't forget to set cable url in your `config/environments/production.rb`:
|
93
|
-
|
94
|
-
```ruby
|
95
|
-
config.action_cable.url = "ws://localhost:3334/cable"
|
96
|
-
```
|
97
|
-
|
98
41
|
## ActionCable Compatibility
|
99
42
|
|
100
43
|
This is the compatibility list for the AnyCable gem, not for AnyCable servers (which may not support some of the features yet).
|
@@ -113,7 +56,6 @@ Streaming | +
|
|
113
56
|
[Custom stream callbacks](http://edgeapi.rubyonrails.org/classes/ActionCable/Channel/Streams.html) | -
|
114
57
|
Broadcasting | +
|
115
58
|
|
116
|
-
|
117
59
|
## Contributing
|
118
60
|
|
119
61
|
Bug reports and pull requests are welcome on GitHub at https://github.com/anycable/anycable.
|
data/anycable.gemspec
CHANGED
@@ -17,14 +17,14 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
spec.add_dependency "
|
21
|
-
spec.add_dependency "anyway_config", "~>0.4.0"
|
20
|
+
spec.add_dependency "anyway_config", "~>0.5.0"
|
22
21
|
spec.add_dependency "grpc", "~> 1.0"
|
23
22
|
spec.add_dependency "redis", "~> 3.0"
|
24
23
|
|
25
24
|
spec.add_development_dependency "bundler", "~> 1"
|
26
25
|
spec.add_development_dependency "rake", "~> 10.0"
|
27
|
-
spec.add_development_dependency "
|
26
|
+
spec.add_development_dependency "rack", "~> 2.0"
|
27
|
+
spec.add_development_dependency "rspec", ">= 3.5"
|
28
28
|
spec.add_development_dependency "simplecov", ">= 0.3.8"
|
29
29
|
spec.add_development_dependency "pry-byebug"
|
30
30
|
end
|
data/bin/console
CHANGED
data/lib/anycable/config.rb
CHANGED
@@ -6,7 +6,8 @@ module Anycable
|
|
6
6
|
class Config < Anyway::Config
|
7
7
|
config_name :anycable
|
8
8
|
|
9
|
-
attr_config
|
9
|
+
attr_config :connection_factory,
|
10
|
+
rpc_host: "localhost:50051",
|
10
11
|
redis_url: "redis://localhost:6379/5",
|
11
12
|
redis_channel: "anycable",
|
12
13
|
debug: false
|
data/lib/anycable/pubsub.rb
CHANGED
@@ -17,9 +17,7 @@ module Anycable
|
|
17
17
|
self.service_name = 'anycable.RPC'
|
18
18
|
|
19
19
|
rpc :Connect, ConnectionRequest, ConnectionResponse
|
20
|
-
rpc :
|
21
|
-
rpc :Unsubscribe, CommandMessage, CommandResponse
|
22
|
-
rpc :Perform, CommandMessage, CommandResponse
|
20
|
+
rpc :Command, CommandMessage, CommandResponse
|
23
21
|
rpc :Disconnect, DisconnectRequest, DisconnectResponse
|
24
22
|
end
|
25
23
|
|
data/lib/anycable/rpc_handler.rb
CHANGED
@@ -1,11 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require 'anycable/actioncable/connection'
|
3
|
-
require 'anycable/actioncable/channel'
|
4
2
|
require 'anycable/rpc/rpc'
|
5
3
|
require 'anycable/rpc/rpc_services'
|
6
4
|
|
7
5
|
# rubocop:disable Metrics/ClassLength
|
8
|
-
# rubocop:disable Metrics/AbcSize
|
9
6
|
# rubocop:disable Metrics/MethodLength
|
10
7
|
module Anycable
|
11
8
|
# RPC service handler
|
@@ -14,12 +11,7 @@ module Anycable
|
|
14
11
|
def connect(request, _unused_call)
|
15
12
|
logger.debug("RPC Connect: #{request}")
|
16
13
|
|
17
|
-
connection =
|
18
|
-
env:
|
19
|
-
path_env(request.path).merge(
|
20
|
-
'HTTP_COOKIE' => request.headers['Cookie']
|
21
|
-
)
|
22
|
-
)
|
14
|
+
connection = factory.create(env: rack_env(request))
|
23
15
|
|
24
16
|
connection.handle_open
|
25
17
|
|
@@ -28,7 +20,7 @@ module Anycable
|
|
28
20
|
else
|
29
21
|
Anycable::ConnectionResponse.new(
|
30
22
|
status: Anycable::Status::SUCCESS,
|
31
|
-
identifiers: connection.
|
23
|
+
identifiers: connection.identifiers_json,
|
32
24
|
transmissions: connection.transmissions
|
33
25
|
)
|
34
26
|
end
|
@@ -37,12 +29,9 @@ module Anycable
|
|
37
29
|
def disconnect(request, _unused_call)
|
38
30
|
logger.debug("RPC Disonnect: #{request}")
|
39
31
|
|
40
|
-
connection =
|
41
|
-
env:
|
42
|
-
|
43
|
-
'HTTP_COOKIE' => request.headers['Cookie']
|
44
|
-
),
|
45
|
-
identifiers_json: request.identifiers,
|
32
|
+
connection = factory.create(
|
33
|
+
env: rack_env(request),
|
34
|
+
identifiers: request.identifiers,
|
46
35
|
subscriptions: request.subscriptions
|
47
36
|
)
|
48
37
|
|
@@ -53,48 +42,39 @@ module Anycable
|
|
53
42
|
end
|
54
43
|
end
|
55
44
|
|
56
|
-
def
|
57
|
-
logger.debug("RPC
|
58
|
-
|
59
|
-
run_command(message)
|
60
|
-
channel.do_subscribe
|
61
|
-
if channel.subscription_rejected?
|
62
|
-
Anycable::CommandResponse.new(
|
63
|
-
status: Anycable::Status::ERROR,
|
64
|
-
disconnect: connection.closed?,
|
65
|
-
transmissions: connection.transmissions
|
66
|
-
)
|
67
|
-
else
|
68
|
-
Anycable::CommandResponse.new(
|
69
|
-
status: Anycable::Status::SUCCESS,
|
70
|
-
disconnect: connection.closed?,
|
71
|
-
stop_streams: channel.stop_streams?,
|
72
|
-
streams: channel.streams,
|
73
|
-
transmissions: connection.transmissions
|
74
|
-
)
|
75
|
-
end
|
76
|
-
end
|
45
|
+
def command(message, _unused_call)
|
46
|
+
logger.debug("RPC Command: #{message}")
|
47
|
+
|
48
|
+
run_command(message)
|
77
49
|
end
|
78
50
|
|
79
|
-
|
80
|
-
|
51
|
+
private
|
52
|
+
|
53
|
+
def run_command(message)
|
54
|
+
connection = factory.create(
|
55
|
+
identifiers: message.connection_identifiers
|
56
|
+
)
|
81
57
|
|
82
|
-
|
83
|
-
connection.subscriptions.remove_subscription(channel)
|
58
|
+
channel = connection.channel_for(message.identifier)
|
84
59
|
|
60
|
+
if !channel.nil?
|
61
|
+
send("handle_#{message.command}", message, connection, channel)
|
62
|
+
else
|
85
63
|
Anycable::CommandResponse.new(
|
86
|
-
status: Anycable::Status::
|
87
|
-
disconnect: false,
|
88
|
-
stop_streams: true
|
64
|
+
status: Anycable::Status::ERROR
|
89
65
|
)
|
90
66
|
end
|
91
67
|
end
|
92
68
|
|
93
|
-
def
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
69
|
+
def handle_subscribe(_msg, connection, channel)
|
70
|
+
channel.handle_subscribe
|
71
|
+
if channel.subscription_rejected?
|
72
|
+
Anycable::CommandResponse.new(
|
73
|
+
status: Anycable::Status::ERROR,
|
74
|
+
disconnect: connection.closed?,
|
75
|
+
transmissions: connection.transmissions
|
76
|
+
)
|
77
|
+
else
|
98
78
|
Anycable::CommandResponse.new(
|
99
79
|
status: Anycable::Status::SUCCESS,
|
100
80
|
disconnect: connection.closed?,
|
@@ -105,33 +85,38 @@ module Anycable
|
|
105
85
|
end
|
106
86
|
end
|
107
87
|
|
108
|
-
|
88
|
+
def handle_unsubscribe(_mgs, connection, channel)
|
89
|
+
channel.handle_unsubscribe
|
109
90
|
|
110
|
-
|
111
|
-
|
112
|
-
|
91
|
+
Anycable::CommandResponse.new(
|
92
|
+
status: Anycable::Status::SUCCESS,
|
93
|
+
disconnect: connection.closed?,
|
94
|
+
stop_streams: true,
|
95
|
+
transmissions: connection.transmissions
|
113
96
|
)
|
97
|
+
end
|
114
98
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
99
|
+
def handle_message(msg, connection, channel)
|
100
|
+
channel.handle_action(msg.data)
|
101
|
+
Anycable::CommandResponse.new(
|
102
|
+
status: Anycable::Status::SUCCESS,
|
103
|
+
disconnect: connection.closed?,
|
104
|
+
stop_streams: channel.stop_streams?,
|
105
|
+
streams: channel.streams,
|
106
|
+
transmissions: connection.transmissions
|
107
|
+
)
|
124
108
|
end
|
125
109
|
|
126
110
|
# Build env from path
|
127
|
-
def
|
128
|
-
uri = URI.parse(path)
|
111
|
+
def rack_env(request)
|
112
|
+
uri = URI.parse(request.path)
|
129
113
|
{
|
130
114
|
'QUERY_STRING' => uri.query,
|
131
115
|
'SCRIPT_NAME' => '',
|
132
116
|
'PATH_INFO' => uri.path,
|
133
117
|
'SERVER_PORT' => uri.port.to_s,
|
134
118
|
'HTTP_HOST' => uri.host,
|
119
|
+
'HTTP_COOKIE' => request.headers['Cookie'],
|
135
120
|
# Hack to avoid Missing rack.input error
|
136
121
|
'rack.request.form_input' => '',
|
137
122
|
'rack.input' => '',
|
@@ -142,5 +127,9 @@ module Anycable
|
|
142
127
|
def logger
|
143
128
|
Anycable.logger
|
144
129
|
end
|
130
|
+
|
131
|
+
def factory
|
132
|
+
Anycable.config.connection_factory
|
133
|
+
end
|
145
134
|
end
|
146
135
|
end
|
data/lib/anycable/server.rb
CHANGED
data/lib/anycable/version.rb
CHANGED
data/lib/anycable.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "anycable/version"
|
3
3
|
require "anycable/config"
|
4
|
-
require "anycable/
|
4
|
+
require "anycable/server"
|
5
|
+
require "anycable/pubsub"
|
6
|
+
require "logger"
|
5
7
|
|
6
8
|
# Anycable allows to use any websocket service (written in any language) as a replacement
|
7
9
|
# for ActionCable server.
|
@@ -11,19 +13,30 @@ require "anycable/actioncable/server"
|
|
11
13
|
#
|
12
14
|
# Broadcasting messages to WS is done through Redis Pub/Sub.
|
13
15
|
module Anycable
|
14
|
-
|
15
|
-
|
16
|
-
|
16
|
+
class << self
|
17
|
+
def logger=(logger)
|
18
|
+
@logger = logger
|
19
|
+
end
|
17
20
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
+
def logger
|
22
|
+
@logger ||= Anycable.config.debug ? Logger.new(STDOUT) : Logger.new('/dev/null')
|
23
|
+
end
|
21
24
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
+
def config
|
26
|
+
@config ||= Config.new
|
27
|
+
end
|
28
|
+
|
29
|
+
def configure
|
30
|
+
yield(config) if block_given?
|
31
|
+
end
|
32
|
+
|
33
|
+
def pubsub
|
34
|
+
@pubsub ||= PubSub.new
|
35
|
+
end
|
25
36
|
|
26
|
-
|
27
|
-
|
37
|
+
# Broadcast message to the channel
|
38
|
+
def broadcast(channel, payload)
|
39
|
+
pubsub.broadcast(channel, payload)
|
40
|
+
end
|
28
41
|
end
|
29
42
|
end
|
data/protos/rpc.proto
CHANGED
@@ -4,9 +4,7 @@ package anycable;
|
|
4
4
|
|
5
5
|
service RPC {
|
6
6
|
rpc Connect (ConnectionRequest) returns (ConnectionResponse) {}
|
7
|
-
rpc
|
8
|
-
rpc Unsubscribe (CommandMessage) returns (CommandResponse) {}
|
9
|
-
rpc Perform (CommandMessage) returns (CommandResponse) {}
|
7
|
+
rpc Command (CommandMessage) returns (CommandResponse) {}
|
10
8
|
rpc Disconnect (DisconnectRequest) returns (DisconnectResponse) {}
|
11
9
|
}
|
12
10
|
|
metadata
CHANGED
@@ -1,43 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: anycable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- palkan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-01-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: rails
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '5'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '5'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: anyway_config
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
31
17
|
- - "~>"
|
32
18
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
19
|
+
version: 0.5.0
|
34
20
|
type: :runtime
|
35
21
|
prerelease: false
|
36
22
|
version_requirements: !ruby/object:Gem::Requirement
|
37
23
|
requirements:
|
38
24
|
- - "~>"
|
39
25
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
26
|
+
version: 0.5.0
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: grpc
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,19 +81,33 @@ dependencies:
|
|
95
81
|
- !ruby/object:Gem::Version
|
96
82
|
version: '10.0'
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
84
|
+
name: rack
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '2.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '3.
|
103
|
+
version: '3.5'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '3.
|
110
|
+
version: '3.5'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: simplecov
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -168,24 +168,14 @@ files:
|
|
168
168
|
- bin/console
|
169
169
|
- bin/setup
|
170
170
|
- circle.yml
|
171
|
-
- gemfiles/rails5.gemfile
|
172
|
-
- gemfiles/railsmaster.gemfile
|
173
171
|
- lib/anycable.rb
|
174
|
-
- lib/anycable/actioncable/channel.rb
|
175
|
-
- lib/anycable/actioncable/connection.rb
|
176
|
-
- lib/anycable/actioncable/server.rb
|
177
172
|
- lib/anycable/config.rb
|
178
173
|
- lib/anycable/pubsub.rb
|
179
|
-
- lib/anycable/refinements/subscriptions.rb
|
180
174
|
- lib/anycable/rpc/rpc.rb
|
181
175
|
- lib/anycable/rpc/rpc_services.rb
|
182
176
|
- lib/anycable/rpc_handler.rb
|
183
177
|
- lib/anycable/server.rb
|
184
178
|
- lib/anycable/version.rb
|
185
|
-
- lib/generators/anycable/USAGE
|
186
|
-
- lib/generators/anycable/anycable_generator.rb
|
187
|
-
- lib/generators/anycable/templates/script
|
188
|
-
- lib/tasks/anycable_tasks.rake
|
189
179
|
- protos/rpc.proto
|
190
180
|
homepage: http://github.com/anycable/anycable
|
191
181
|
licenses:
|
data/gemfiles/rails5.gemfile
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require "action_cable"
|
3
|
-
|
4
|
-
module ActionCable
|
5
|
-
module Channel
|
6
|
-
class Base # :nodoc:
|
7
|
-
alias do_subscribe subscribe_to_channel
|
8
|
-
|
9
|
-
public :do_subscribe, :subscription_rejected?
|
10
|
-
|
11
|
-
def subscribe_to_channel
|
12
|
-
# noop
|
13
|
-
end
|
14
|
-
|
15
|
-
attr_reader :stop_streams
|
16
|
-
|
17
|
-
def stream_from(broadcasting, callback = nil, coder: nil)
|
18
|
-
raise ArgumentError('Unsupported') if callback.present? || coder.present? || block_given?
|
19
|
-
streams << broadcasting
|
20
|
-
end
|
21
|
-
|
22
|
-
def stop_all_streams
|
23
|
-
@stop_streams = true
|
24
|
-
end
|
25
|
-
|
26
|
-
def streams
|
27
|
-
@streams ||= []
|
28
|
-
end
|
29
|
-
|
30
|
-
def stop_streams?
|
31
|
-
stop_streams == true
|
32
|
-
end
|
33
|
-
|
34
|
-
def delegate_connection_identifiers
|
35
|
-
connection.identifiers.each do |identifier|
|
36
|
-
define_singleton_method(identifier) do
|
37
|
-
connection.fetch_identifier(identifier)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,95 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require "action_cable"
|
3
|
-
require "anycable/refinements/subscriptions"
|
4
|
-
|
5
|
-
module ActionCable
|
6
|
-
module Connection
|
7
|
-
class Base # :nodoc:
|
8
|
-
using Anycable::Refinements::Subscriptions
|
9
|
-
|
10
|
-
attr_reader :transmissions
|
11
|
-
|
12
|
-
class << self
|
13
|
-
def identified_by(*identifiers)
|
14
|
-
super
|
15
|
-
Array(identifiers).each do |identifier|
|
16
|
-
define_method(identifier) do
|
17
|
-
instance_variable_get(:"@#{identifier}") || fetch_identifier(identifier)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def initialize(env: {}, identifiers_json: '{}', subscriptions: [])
|
24
|
-
@ids = ActiveSupport::JSON.decode(identifiers_json)
|
25
|
-
|
26
|
-
@cached_ids = {}
|
27
|
-
@env = env
|
28
|
-
@coder = ActiveSupport::JSON
|
29
|
-
@closed = false
|
30
|
-
@transmissions = []
|
31
|
-
@subscriptions = ActionCable::Connection::Subscriptions.new(self)
|
32
|
-
|
33
|
-
# Initialize channels if any
|
34
|
-
subscriptions.each { |id| @subscriptions.fetch(id) }
|
35
|
-
end
|
36
|
-
|
37
|
-
# Create a channel instance from identifier for the connection
|
38
|
-
def channel_for(identifier)
|
39
|
-
subscriptions.fetch(identifier)
|
40
|
-
end
|
41
|
-
|
42
|
-
def handle_open
|
43
|
-
connect if respond_to?(:connect)
|
44
|
-
send_welcome_message
|
45
|
-
rescue ActionCable::Connection::Authorization::UnauthorizedError
|
46
|
-
close
|
47
|
-
end
|
48
|
-
|
49
|
-
def handle_close
|
50
|
-
subscriptions.unsubscribe_from_all
|
51
|
-
disconnect if respond_to?(:disconnect)
|
52
|
-
end
|
53
|
-
|
54
|
-
def close
|
55
|
-
@closed = true
|
56
|
-
end
|
57
|
-
|
58
|
-
def closed?
|
59
|
-
@closed
|
60
|
-
end
|
61
|
-
|
62
|
-
def transmit(cable_message)
|
63
|
-
transmissions << encode(cable_message)
|
64
|
-
end
|
65
|
-
|
66
|
-
def dispose
|
67
|
-
@closed = false
|
68
|
-
transmissions.clear
|
69
|
-
end
|
70
|
-
|
71
|
-
# Generate identifiers info.
|
72
|
-
# Converts GlobalID compatible vars to corresponding global IDs params.
|
73
|
-
def identifiers_hash
|
74
|
-
identifiers.each_with_object({}) do |id, acc|
|
75
|
-
obj = instance_variable_get("@#{id}")
|
76
|
-
next unless obj
|
77
|
-
acc[id] = obj.try(:to_gid_param) || obj
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
# Fetch identifier and deserialize if neccessary
|
82
|
-
def fetch_identifier(name)
|
83
|
-
@cached_ids[name] ||= @cached_ids.fetch(name) do
|
84
|
-
val = @ids[name.to_s]
|
85
|
-
next val unless val.is_a?(String)
|
86
|
-
GlobalID::Locator.locate(val) || val
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def logger
|
91
|
-
::Rails.logger
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module Anycable
|
3
|
-
module Refinements
|
4
|
-
module Subscriptions # :nodoc:
|
5
|
-
refine ActionCable::Connection::Subscriptions do
|
6
|
-
# Find or add a subscription to the list
|
7
|
-
def fetch(identifier)
|
8
|
-
add("identifier" => identifier) unless subscriptions[identifier]
|
9
|
-
subscriptions[identifier]
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
@@ -1,11 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require "rails/generators/base"
|
3
|
-
|
4
|
-
class AnycableGenerator < Rails::Generators::Base # :nodoc:
|
5
|
-
source_root File.expand_path('../templates', __FILE__)
|
6
|
-
|
7
|
-
def create_executable_file
|
8
|
-
template "script", "bin/anycable"
|
9
|
-
chmod "bin/anycable", 0o755
|
10
|
-
end
|
11
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
namespace :anycable do
|
3
|
-
desc "Make test gRPC call"
|
4
|
-
task check: :environment do
|
5
|
-
require 'grpc'
|
6
|
-
require 'anycable/rpc/rpc_services'
|
7
|
-
|
8
|
-
Anycable.logger = Logger.new(STDOUT)
|
9
|
-
stub = Anycable::RPC::Stub.new(Anycable.config.rpc_host, :this_channel_is_insecure)
|
10
|
-
stub.connect(
|
11
|
-
Anycable::ConnectionRequest.new(
|
12
|
-
path: 'http://example.com',
|
13
|
-
headers: { 'Cookie' => 'test=1;' }
|
14
|
-
)
|
15
|
-
)
|
16
|
-
end
|
17
|
-
end
|