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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 925d630d73669095c73fb2c1cfe55a9e87eb3f96
4
- data.tar.gz: 0314e4c2a10909275c91e5cc813eaa9fb8b98999
3
+ metadata.gz: 2589605d172fda191b1733259d1205e474754285
4
+ data.tar.gz: 444266a714ada061f08f699ffafd61f08edd6e59
5
5
  SHA512:
6
- metadata.gz: 0d31377f132589da64214429fdeac9e3332ec66294869631d5a3d2ab33ed58dd496dc094734c23c07457eea2884ce21b5cb33542866e455394e4df516c76f0f9
7
- data.tar.gz: c13beb8e1f441b420b859523aa8545ee8997a63e4ec6b21095dc8d469cc8a4934e512c854e943d031d5d96b91b5c048c1833261c184f8745a3d46db63f43c420
6
+ metadata.gz: cdcdca3db177557e4d144d0af7b8d8a643ad2dfe1c3728e7be95aaa84494e21f38e7bda57d61c3f617f62b1e7302be2c19a0b07b4e5795fb213b898bd8279280
7
+ data.tar.gz: 669cdc0c8b3d83114a1a0f5acf2e7a1686e70ba2a739a1acdcbdc01cdcbc5122e56eab907f26aefe49cf227a631a047f17a8d817c75acfa429d6654f9b9e00c8
data/.travis.yml CHANGED
@@ -1,11 +1,6 @@
1
1
  language: ruby
2
2
  cache: bundler
3
3
 
4
- rvm: 2.3.3
5
-
6
4
  matrix:
7
5
  include:
8
- - gemfile: gemfiles/rails5.gemfile
9
- - gemfile: gemfiles/railsmaster.gemfile
10
- allow_failures:
11
- - gemfile: gemfiles/railsmaster.gemfile
6
+ - rvm: 2.3.3
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
@@ -1,4 +1,4 @@
1
- Copyright 2016 palkan
1
+ Copyright 2017 palkan
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
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 built-in Ruby ActionCable server.
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
- With AnyCable you can use channels, client-side JS, broadcasting - (almost) all that you can do with ActionCable.
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
- You can even use ActionCable in development and not be afraid of compatibility issues.
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
- - Rails ~> 5.0;
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 "rails", "~> 5"
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 "rspec-rails", ">= 3.4"
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
@@ -1,8 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "bundler/setup"
4
- require "rails"
5
- require "anycable/server"
4
+ require "anycable"
6
5
 
7
6
  require "pry"
8
7
  Pry.start
@@ -6,7 +6,8 @@ module Anycable
6
6
  class Config < Anyway::Config
7
7
  config_name :anycable
8
8
 
9
- attr_config rpc_host: "localhost:50051",
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
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  require "redis"
3
+ require "json"
3
4
 
4
5
  module Anycable
5
6
  # PubSub for broadcasting
@@ -17,9 +17,7 @@ module Anycable
17
17
  self.service_name = 'anycable.RPC'
18
18
 
19
19
  rpc :Connect, ConnectionRequest, ConnectionResponse
20
- rpc :Subscribe, CommandMessage, CommandResponse
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
 
@@ -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 = ApplicationCable::Connection.new(
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.identifiers_hash.to_json,
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 = ApplicationCable::Connection.new(
41
- env:
42
- path_env(request.path).merge(
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 subscribe(message, _unused_call)
57
- logger.debug("RPC Subscribe: #{message}")
58
-
59
- run_command(message) do |connection, channel|
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
- def unsubscribe(message, _unused_call)
80
- logger.debug("RPC Unsubscribe: #{message}")
51
+ private
52
+
53
+ def run_command(message)
54
+ connection = factory.create(
55
+ identifiers: message.connection_identifiers
56
+ )
81
57
 
82
- run_command(message) do |connection, channel|
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::SUCCESS,
87
- disconnect: false,
88
- stop_streams: true
64
+ status: Anycable::Status::ERROR
89
65
  )
90
66
  end
91
67
  end
92
68
 
93
- def perform(message, _unused_call)
94
- logger.debug("RPC Perform: #{message}")
95
-
96
- run_command(message) do |connection, channel|
97
- channel.perform_action(ActiveSupport::JSON.decode(message.data))
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
- private
88
+ def handle_unsubscribe(_mgs, connection, channel)
89
+ channel.handle_unsubscribe
109
90
 
110
- def run_command(message)
111
- connection = ApplicationCable::Connection.new(
112
- identifiers_json: message.connection_identifiers
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
- channel = connection.channel_for(message.identifier)
116
-
117
- if channel.present?
118
- yield connection, channel
119
- else
120
- Anycable::CommandResponse.new(
121
- status: Anycable::Status::ERROR
122
- )
123
- end
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 path_env(path)
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
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  require 'grpc'
3
- require 'anycable'
4
3
  require 'anycable/rpc_handler'
5
4
 
6
5
  # Set GRPC logger
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Anycable
3
- VERSION = "0.3.0"
3
+ VERSION = "0.4.0"
4
4
  end
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/actioncable/server"
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
- def self.logger=(logger)
15
- @logger = logger
16
- end
16
+ class << self
17
+ def logger=(logger)
18
+ @logger = logger
19
+ end
17
20
 
18
- def self.logger
19
- @logger ||= Anycable.config.debug ? Logger.new(STDOUT) : Logger.new('/dev/null')
20
- end
21
+ def logger
22
+ @logger ||= Anycable.config.debug ? Logger.new(STDOUT) : Logger.new('/dev/null')
23
+ end
21
24
 
22
- def self.config
23
- @config ||= Config.new
24
- end
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
- def self.configure
27
- yield(config) if block_given?
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 Subscribe (CommandMessage) returns (CommandResponse) {}
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.3.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: 2016-12-28 00:00:00.000000000 Z
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.4.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.4.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: rspec-rails
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.4'
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.4'
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:
@@ -1,6 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem 'rails', '~> 5.0.0'
4
- gem 'rspec-rails', '~> 3.5.0'
5
-
6
- gemspec path: '..'
@@ -1,6 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem 'rails', github: 'rails/rails'
4
- gem 'rspec-rails', '~> 3.5.0'
5
-
6
- gemspec path: '..'
@@ -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
- require "action_cable"
3
- require "anycable/pubsub"
4
-
5
- module ActionCable
6
- module Server
7
- # Override pubsub for ActionCable
8
- class Base
9
- def pubsub
10
- @any_pubsub ||= Anycable::PubSub.new
11
- end
12
- end
13
- end
14
- 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,7 +0,0 @@
1
- Description:
2
- Generates Anycable executable
3
-
4
- Examples:
5
- rails generate anycable
6
-
7
- This will generate Anycable executable
@@ -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,8 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
- require ::File.expand_path('../../config/environment', __FILE__)
4
- require 'anycable/server'
5
-
6
- Rails.application.eager_load!
7
-
8
- Anycable::Server.start
@@ -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