cable_room 0.4.4 → 0.5.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
  SHA256:
3
- metadata.gz: 928184ed2b2f5a529bb24cccde6e0048f9c9f5a7ce2b60b62779bc8f06a998ca
4
- data.tar.gz: 440782d877fbdc28948fe8499de860bb0d99c4bcde01b1abb933a23f20a14074
3
+ metadata.gz: e7c2fd48ac93d24a9ae68aae23aee05c3373d60154f54b0c7900e8863559fa89
4
+ data.tar.gz: 48f564bb727ed8cfd5932d9a07d7ac6f24d969ce5622bf87f8ff5766f44b17e7
5
5
  SHA512:
6
- metadata.gz: 95047199ea82748e023d3ca246ba942cc4e5845613bd7f76f18c2700e027027f60277f904bc9f3cc5514f808ae7ca4d9305d051fdf40b00d6c280a5fc4e8aba0
7
- data.tar.gz: 5e4e966735dffddf5c074776ea44702dd52b6cd5559a5b814f7d87a03c3fb58e7acfb3b0b7401452b67e9444d7e67d29352ae726c8ab4ba35353e5390495685b
6
+ metadata.gz: b2bc85c458cf22927817827dd5d742f68060d0dee82b50338dfd27a9c78c5fe465afb8dc10e086c40c5e8171154542c9e6c1f39c9c72ab10b77199c85bba5cb0
7
+ data.tar.gz: e7f45e327bee8df3ffb82ae510a805900cce03ad710a6ab2b1986b29d51adbaf4b118aa21be299f4f495267777cf37f26e14e6a043528554d9ce4a46092c73e8
@@ -105,6 +105,8 @@ module CableRoom
105
105
  @mutex.synchronize do
106
106
  return if @current_state == :dead || @current_state == :shutting_down
107
107
 
108
+ logger.info "Initiating shutdown: #{reason}"
109
+
108
110
  # Stop streams immediately to prevent further messages from being added
109
111
  stop_all_streams
110
112
 
@@ -75,8 +75,6 @@ module CableRoom
75
75
  end
76
76
  end
77
77
 
78
- protected
79
-
80
78
  def each_room_channel(&blk)
81
79
  @room_channels.dup.each(&blk)
82
80
  end
@@ -14,9 +14,18 @@ module CableRoom
14
14
  runner do
15
15
  end
16
16
 
17
- initializer "cable_room.shutdown" do
18
- Rails.application.reloader.before_class_unload do
19
- CableRoom::ChannelTracker.instance.shutdown_rooms!
17
+ initializer "cable_room.hook_action_cable_restart" do
18
+ module ActionCableServerExtensions
19
+ def restart
20
+ CableRoom::ChannelTracker.instance.each_room_channel do |chan|
21
+ chan.unsubscribe_from_channel
22
+ end
23
+ super
24
+ end
25
+ end
26
+
27
+ ActiveSupport.on_load(:action_cable) do
28
+ ActionCable::Server::Base.prepend(ActionCableServerExtensions)
20
29
  end
21
30
  end
22
31
 
@@ -25,6 +25,8 @@ module CableRoom
25
25
 
26
26
  define_callbacks :port_connected, :port_disconnected
27
27
 
28
+ on_port_connected { reply({type: 'port_acknowledged' }) }
29
+
28
30
  set_callback(:receive_message, :around) do |_, blk|
29
31
  previous_mtok = @current_message_origin
30
32
  begin
@@ -52,7 +52,7 @@ module CableRoom
52
52
  false
53
53
  }
54
54
 
55
- reaper_checkers << cfg
55
+ self.reaper_checkers = reaper_checkers + [cfg]
56
56
  end
57
57
  end
58
58
 
@@ -53,58 +53,36 @@ module CableRoom
53
53
  room_class,
54
54
  room_key,
55
55
  create: false,
56
- on_closed: nil,
57
- on_opened: nil,
56
+ on_room_opened: nil, # Not guaranteed (Only given if the Room Opens while we are trying to connect to it)
57
+ on_joined: nil,
58
58
  on_message: nil,
59
+ on_room_closed: nil, # Not guaranteed (Only given if the Room Closes while we are connected to it)
60
+ on_left: nil,
59
61
  tags: [],
60
62
  extra: nil,
61
63
  &preconfigure
62
64
  )
63
- @token = SecureRandom.hex(16)
65
+ @mutex = Monitor.new
66
+
64
67
  @has_left = false
68
+ @has_established = false
65
69
 
66
70
  @cable_channel = cable_channel
67
71
  @room_class = room_class
68
72
  @room_key = room_key
69
73
  @allow_create = create
70
74
 
71
- @on_opened = on_opened
72
- @on_closed = on_closed
75
+ @on_room_opened = on_room_opened
76
+ @on_joined = on_joined
73
77
  @on_message = on_message
78
+ @on_room_closed = on_room_closed
79
+ @on_left = on_left
80
+ @preconfigure = preconfigure
74
81
 
75
82
  @tags = Array(tags).map(&:to_sym)
76
83
  @extra = extra
77
84
 
78
- @cable_channel._room_memberships << self
79
-
80
- # Listen to public/broadcast channel
81
- stream_port(room_class::ROOM_OUT_CHANNEL) do |message|
82
- handle_received_message(message)
83
- end
84
-
85
- # Listen to private channel
86
- stream_port(@token) do |message|
87
- handle_received_message(message)
88
- end
89
-
90
- # Listen to user-specific channel
91
- if extra && extra[:as]
92
- stream_port(extra[:as]) do |message|
93
- handle_received_message(message)
94
- end
95
- end
96
-
97
- @tags.each do |tag|
98
- stream_port(tag) do |message|
99
- handle_received_message(message)
100
- end
101
- end
102
-
103
- preconfigure&.call(self)
104
-
105
- transmit_port_connected
106
-
107
- maybe_provision_room
85
+ initiate_connection
108
86
  end
109
87
 
110
88
  delegate :logger, to: :@cable_channel
@@ -113,25 +91,41 @@ module CableRoom
113
91
  port_transmit(room_class::ROOM_IN_CHANNEL, data)
114
92
  end
115
93
 
94
+ def connected?
95
+ !left? && @has_established
96
+ end
97
+
116
98
  def left?
117
- @has_left
99
+ @mutex.synchronize { @has_left }
118
100
  end
119
101
 
120
102
  def ping!
121
103
  return if left?
122
-
123
104
  port_transmit(room_class::ROOM_IN_CHANNEL, { type: 'port_ping' }, secure_context: true)
124
- maybe_provision_room
105
+ @mutex.synchronize do
106
+ maybe_provision_room
107
+ end
125
108
  end
126
109
 
127
110
  def leave!
128
- return if left?
111
+ @mutex.synchronize do
112
+ return if left?
129
113
 
130
- close_streamed_ports!
131
- @cable_channel._room_memberships.delete(self)
132
- port_transmit(room_class::ROOM_IN_CHANNEL, { type: 'port_disconnected' }, secure_context: true)
133
- @has_left = true
134
- @on_closed&.call(self)
114
+ close_streamed_ports!
115
+ @cable_channel._room_memberships.delete(self)
116
+ port_transmit(room_class::ROOM_IN_CHANNEL, { type: 'port_disconnected' }, secure_context: true)
117
+ @has_left = true
118
+ end
119
+ @on_left&.call(self)
120
+ end
121
+
122
+ def rejoin!
123
+ @mutex.synchronize do
124
+ return unless left?
125
+
126
+ @has_left = false
127
+ initiate_connection
128
+ end
135
129
  end
136
130
 
137
131
  def key; @room_key; end
@@ -160,12 +154,15 @@ module CableRoom
160
154
  return leave! if message == "KILL"
161
155
 
162
156
  case message['type']
157
+ when 'port_acknowledged'
158
+ @has_established = true
159
+ @on_joined&.call(self)
163
160
  when 'room_opened'
164
161
  transmit_port_connected
165
- @on_opened&.call(self)
162
+ @on_room_opened&.call(self)
166
163
  when 'room_closed'
167
- @on_closed&.call(self)
168
- maybe_provision_room
164
+ leave!
165
+ @on_room_closed&.call(self)
169
166
  else
170
167
  logger.warn "Unknown room message type: #{message['type'].inspect}" unless @on_message
171
168
  end
@@ -175,6 +172,45 @@ module CableRoom
175
172
 
176
173
  private
177
174
 
175
+ def initiate_connection
176
+ @mutex.synchronize do
177
+ return if left?
178
+
179
+ @token = SecureRandom.hex(16)
180
+ @has_established = false
181
+ @cable_channel._room_memberships << self
182
+
183
+ # Listen to public/broadcast channel
184
+ stream_port(room_class::ROOM_OUT_CHANNEL) do |message|
185
+ handle_received_message(message)
186
+ end
187
+
188
+ # Listen to private channel
189
+ stream_port(@token) do |message|
190
+ handle_received_message(message)
191
+ end
192
+
193
+ # Listen to user-specific channel
194
+ if @extra && @extra[:as]
195
+ stream_port(@extra[:as]) do |message|
196
+ handle_received_message(message)
197
+ end
198
+ end
199
+
200
+ @tags.each do |tag|
201
+ stream_port(tag) do |message|
202
+ handle_received_message(message)
203
+ end
204
+ end
205
+
206
+ @preconfigure&.call(self)
207
+
208
+ transmit_port_connected
209
+
210
+ maybe_provision_room
211
+ end
212
+ end
213
+
178
214
  def transmit_port_connected
179
215
  msg = {
180
216
  type: 'port_connected',
@@ -0,0 +1,35 @@
1
+ module CableRoom
2
+ module RoomProxyChannel
3
+ extend ActiveSupport::Concern
4
+ include CableRoom::RoomMember
5
+
6
+ class_methods do
7
+ def subscribe_to_room(&blk)
8
+ define_method(:subscribe_to_room, &blk)
9
+ end
10
+ end
11
+
12
+ def subscribed
13
+ @room_membership = subscribe_to_room
14
+ end
15
+
16
+ def receive(data)
17
+ @room_membership << data if @room_membership&.connected?
18
+ end
19
+
20
+ def unsubscribed
21
+ @room_membership&.leave!
22
+ end
23
+
24
+ protected
25
+
26
+ def subscribe_to_room
27
+ raise NotImplementedError
28
+ end
29
+
30
+ def join_room(*args, **kwargs, &blk)
31
+ kwargs[:forward] = true
32
+ super
33
+ end
34
+ end
35
+ end
@@ -1,3 +1,3 @@
1
1
  module CableRoom
2
- VERSION = "0.4.4".freeze
2
+ VERSION = "0.5.0".freeze
3
3
  end
data/lib/cable_room.rb CHANGED
@@ -13,6 +13,7 @@ require_relative 'cable_room/channel_base'
13
13
  require_relative 'cable_room/channel_tracker'
14
14
  require_relative 'cable_room/ports'
15
15
  require_relative 'cable_room/room_member'
16
+ require_relative 'cable_room/room_proxy_channel'
16
17
  require_relative 'cable_room/room/'
17
18
  require_relative 'cable_room/version'
18
19
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cable_room
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ethan Knapp
@@ -126,6 +126,7 @@ files:
126
126
  - lib/cable_room/room/threading.rb
127
127
  - lib/cable_room/room/user_management.rb
128
128
  - lib/cable_room/room_member.rb
129
+ - lib/cable_room/room_proxy_channel.rb
129
130
  - lib/cable_room/version.rb
130
131
  - spec/cable_room/room_member_spec.rb
131
132
  - spec/internal/config/cable.yml