cable_room 0.6.2.beta8 → 0.6.2

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: cf9bc187f61f47429b4f6d19591ae11f9ce5adc4f3e631a386543c5a4be3d31f
4
- data.tar.gz: 7ea623c7bce5023f7eef8e9f70c7fd723dd6d4c83ffdff6e0e636bcf4a0c2085
3
+ metadata.gz: dd8691b68a1e9615764de3fb3a736a70d8c64f3ac5b78366e33e9fa996fa71b4
4
+ data.tar.gz: ab1d8f9027f2dc832fdc5e336f56d87c33231431813c7e579ba8399433e5a18c
5
5
  SHA512:
6
- metadata.gz: 3ea7801344b227a3db243d32aa569427a2e721adb2c4e8894ff803834a6e60392a064cac0b9f2bf21257936109b472d99f994bb82eec3387aa490d1cf7260c1b
7
- data.tar.gz: b0d7b8b7b054d5a45290df64691e919a9ac8d951beb06df38edf799e3c81bb955ca5444b490293fb4d20d0a09759dc4b8122334d2d041ebf52e6bbd23486d8cf
6
+ metadata.gz: 151dad25868518619f54fe1fe33e70f737742acc58f7a7f3b56dc02088e30b4b0713e74e0ca17aaba86769a4fb57007b5a9f9e60d18b5b131a27af4d6cdc54e8
7
+ data.tar.gz: 85f6190c18f1273e5b13c20fa7a33979bb6618f8544f6a40241d632e7248779f8df5176eb9643493e1297ba4c9a9690f9d04f192909421160af53935ca771296
@@ -9,6 +9,14 @@ module CableRoom
9
9
  # ~30% of all room messages at 10 s with no skipping.
10
10
  PING_INTERVAL = 15.seconds
11
11
 
12
+ # A dropped announcement is invisible to the port. The room's inbound subscription is
13
+ # registered asynchronously — and the room may live in another process entirely — so a
14
+ # port_connected sent before the room is listening is discarded with no error. Re-announce on
15
+ # a doubling backoff from here until the room acknowledges, rather than waiting out a whole
16
+ # PING_INTERVAL. port_connected is idempotent on the room side (the port is merged,
17
+ # user_joined fires only once), so a redundant re-announcement costs one message.
18
+ REANNOUNCE_INITIAL_DELAY = 0.1.seconds
19
+
12
20
  included do
13
21
  periodically :ping_room_memberships, every: PING_INTERVAL
14
22
 
@@ -51,13 +59,11 @@ module CableRoom
51
59
 
52
60
  def transmit_subscription_confirmation(...)
53
61
  super
54
- # Rails invokes this from the pubsub adapter's subscribe success callback, which runs while
55
- # SubscriberMap holds its (non-reentrant) @sync mutex. Broadcasting from that stack raises
56
- # ThreadError: deadlock; recursive locking, and the adapter swallows it. Defer onto the event
57
- # loop so the announce still happens after every stream is confirmed live, but off the lock.
58
62
  memberships = _room_memberships.to_a
59
63
  memberships.each(&:streams_live!)
60
- connection.server.event_loop.post { memberships.each(&:transmit_port_connected) }
64
+ connection.worker_pool.async_exec(self, connection: connection) do
65
+ memberships.each(&:transmit_port_connected)
66
+ end
61
67
  end
62
68
  end
63
69
 
@@ -85,6 +91,8 @@ module CableRoom
85
91
  @has_left = false
86
92
  @has_established = false
87
93
  @streams_live = false
94
+ @reannounce_delay = nil
95
+ @reannounce_job = nil
88
96
 
89
97
  @cable_channel = cable_channel
90
98
  @room_class = room_class
@@ -134,6 +142,7 @@ module CableRoom
134
142
  @mutex.synchronize do
135
143
  return if left?
136
144
 
145
+ stop_reannouncing
137
146
  close_streamed_ports!
138
147
  @cable_channel._room_memberships.delete(self)
139
148
  port_transmit(room_class::ROOM_IN_CHANNEL, { type: 'port_disconnected' }, secure_context: true)
@@ -166,6 +175,7 @@ module CableRoom
166
175
  }
167
176
  msg[:extra] = ::ActiveJob::Arguments.serialize([@extra]) if @extra
168
177
  port_transmit(room_class::ROOM_IN_CHANNEL, msg, secure_context: true)
178
+ schedule_reannounce
169
179
  end
170
180
 
171
181
  protected
@@ -186,6 +196,45 @@ module CableRoom
186
196
  @last_transmit_at = monotonic_now unless type == :port_ping
187
197
  end
188
198
 
199
+ # Re-announce until the room acknowledges the port, doubling the wait each time. Handing off
200
+ # to ping! at PING_INTERVAL keeps a stuck membership from holding a timer open forever.
201
+ def schedule_reannounce
202
+ @mutex.synchronize do
203
+ cancel_reannounce
204
+ return if @has_established || @has_left
205
+ return if ChannelTracker.instance.shutdown?
206
+
207
+ next_delay = @reannounce_delay ? @reannounce_delay * 2 : RoomMember::REANNOUNCE_INITIAL_DELAY
208
+ return if next_delay > RoomMember::PING_INTERVAL
209
+
210
+ @reannounce_delay = next_delay
211
+
212
+ # async_exec runs the block with `instance_exec` against the channel, so hold onto the
213
+ # membership rather than relying on `self`.
214
+ membership = self
215
+ channel = @cable_channel
216
+ @reannounce_job = ChannelTracker.instance.scheduler.schedule_in(@reannounce_delay.to_f) do
217
+ channel.connection.worker_pool.async_exec(channel, connection: channel.connection) do
218
+ membership.transmit_port_connected unless membership.connected? || membership.left?
219
+ end
220
+ end
221
+ end
222
+ end
223
+
224
+ def cancel_reannounce
225
+ @mutex.synchronize do
226
+ @reannounce_job&.unschedule
227
+ @reannounce_job = nil
228
+ end
229
+ end
230
+
231
+ def stop_reannouncing
232
+ @mutex.synchronize do
233
+ cancel_reannounce
234
+ @reannounce_delay = nil
235
+ end
236
+ end
237
+
189
238
  def recently_transmitted?
190
239
  @last_transmit_at && (monotonic_now - @last_transmit_at) < RoomMember::PING_INTERVAL
191
240
  end
@@ -206,6 +255,7 @@ module CableRoom
206
255
  # A re-announced port (see ping!) is re-acknowledged; only the first one is a join.
207
256
  first_acknowledgement = !@has_established
208
257
  @has_established = true
258
+ stop_reannouncing
209
259
  @on_joined&.call(self) if first_acknowledgement
210
260
  when 'room_opened'
211
261
  # Only safe once our own streams are confirmed; otherwise the room may acknowledge on the
@@ -231,6 +281,7 @@ module CableRoom
231
281
 
232
282
  @token = SecureRandom.hex(16)
233
283
  @has_established = false
284
+ stop_reannouncing
234
285
  @cable_channel._room_memberships << self
235
286
 
236
287
  # Listen to public/broadcast channel
@@ -1,3 +1,3 @@
1
1
  module CableRoom
2
- VERSION = "0.6.2.beta8".freeze
2
+ VERSION = "0.6.2".freeze
3
3
  end
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.6.2.beta8
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ethan Knapp