cable_room 0.6.2.beta9 → 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: 5a0b89cf59e8dc6fa9ebfed2efe728c0c2916bbac6d54738612944adec072762
4
- data.tar.gz: 55db8ebfde7f3574755f8348e90a4986c8943600c9231b1ce0af723f94863f33
3
+ metadata.gz: dd8691b68a1e9615764de3fb3a736a70d8c64f3ac5b78366e33e9fa996fa71b4
4
+ data.tar.gz: ab1d8f9027f2dc832fdc5e336f56d87c33231431813c7e579ba8399433e5a18c
5
5
  SHA512:
6
- metadata.gz: 60f838c24cc7b4bc43541c0cc9386f6a295824b0a44526a1fa0d018240966dc6c81665faed13edc76a7ae7fa4d0ab958dbe0c2486b85fc81f502e3fc819dafe2
7
- data.tar.gz: 61c0ea11ca13892247ac210fe32cc2c1d5ee157f1da7125f4a9fdde22bee7e9d70a6468e539a7e4503814feefbcbdd80b2e2075291b4b48fd9cd8183e89d6415
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
 
@@ -83,6 +91,8 @@ module CableRoom
83
91
  @has_left = false
84
92
  @has_established = false
85
93
  @streams_live = false
94
+ @reannounce_delay = nil
95
+ @reannounce_job = nil
86
96
 
87
97
  @cable_channel = cable_channel
88
98
  @room_class = room_class
@@ -132,6 +142,7 @@ module CableRoom
132
142
  @mutex.synchronize do
133
143
  return if left?
134
144
 
145
+ stop_reannouncing
135
146
  close_streamed_ports!
136
147
  @cable_channel._room_memberships.delete(self)
137
148
  port_transmit(room_class::ROOM_IN_CHANNEL, { type: 'port_disconnected' }, secure_context: true)
@@ -164,6 +175,7 @@ module CableRoom
164
175
  }
165
176
  msg[:extra] = ::ActiveJob::Arguments.serialize([@extra]) if @extra
166
177
  port_transmit(room_class::ROOM_IN_CHANNEL, msg, secure_context: true)
178
+ schedule_reannounce
167
179
  end
168
180
 
169
181
  protected
@@ -184,6 +196,45 @@ module CableRoom
184
196
  @last_transmit_at = monotonic_now unless type == :port_ping
185
197
  end
186
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
+
187
238
  def recently_transmitted?
188
239
  @last_transmit_at && (monotonic_now - @last_transmit_at) < RoomMember::PING_INTERVAL
189
240
  end
@@ -204,6 +255,7 @@ module CableRoom
204
255
  # A re-announced port (see ping!) is re-acknowledged; only the first one is a join.
205
256
  first_acknowledgement = !@has_established
206
257
  @has_established = true
258
+ stop_reannouncing
207
259
  @on_joined&.call(self) if first_acknowledgement
208
260
  when 'room_opened'
209
261
  # Only safe once our own streams are confirmed; otherwise the room may acknowledge on the
@@ -229,6 +281,7 @@ module CableRoom
229
281
 
230
282
  @token = SecureRandom.hex(16)
231
283
  @has_established = false
284
+ stop_reannouncing
232
285
  @cable_channel._room_memberships << self
233
286
 
234
287
  # Listen to public/broadcast channel
@@ -1,3 +1,3 @@
1
1
  module CableRoom
2
- VERSION = "0.6.2.beta9".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.beta9
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ethan Knapp