anycable 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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