datagrout-conduit 0.8.1 → 0.8.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 +4 -4
- data/README.md +1 -1
- data/lib/datagrout_conduit/transport/ws.rb +32 -2
- data/lib/datagrout_conduit/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b5f3083e66b890a25b3fe77e4fd86e7e72ba3d86af8a530477ad93334de26f19
|
|
4
|
+
data.tar.gz: 16bb086f9c923bacad3fe8fc228eb5ea024a475a33bba51f320aad00fa032f56
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a38b2be0474f517414da7731565fac6a4327664f84b7b95f9e04d478f29183087ac4da84899fbba952bbba11244386735ecd564c1a422038c8baef3b45141d10
|
|
7
|
+
data.tar.gz: 82f0c8a811e8165f1a5c91dcc5c3f93121115cc49d9969774e6b0a2c65d63afb2cf34d646c1042039f52182db2bca2084982d75dee76c56c0ad612405132ec66
|
data/README.md
CHANGED
|
@@ -310,7 +310,7 @@ Supported topics:
|
|
|
310
310
|
| `flows.<flow_id>.*` | `flow.into` progress and completion |
|
|
311
311
|
| `governor.<server_uuid>` | Governor percept events (file change, schedule, webhook) |
|
|
312
312
|
|
|
313
|
-
**Reconnection**: after a disconnect, `send_request` and `subscribe` raise `DatagroutConduit::NotInitializedError`. Call `client.connect` again and re-subscribe — subscriptions do not survive reconnects in v0.4.
|
|
313
|
+
**Reconnection**: after a disconnect, `send_request` and `subscribe` raise `DatagroutConduit::NotInitializedError`. Call `client.connect` again and re-subscribe — subscriptions do not survive reconnects in v0.4. A connection ends when the server closes it, a read fails, or a keepalive ping goes unanswered for a whole interval; in-flight calls then fail and every subscription's `each` ends.
|
|
314
314
|
|
|
315
315
|
## Standard MCP Methods
|
|
316
316
|
|
|
@@ -442,6 +442,19 @@ module DatagroutConduit
|
|
|
442
442
|
subs.each_value { |list| list.each(&:_close) }
|
|
443
443
|
end
|
|
444
444
|
|
|
445
|
+
# The peer stopped answering pings: release every waiter as a close
|
|
446
|
+
# does, then close the socket so the read thread stops too.
|
|
447
|
+
def peer_gone
|
|
448
|
+
was_connected = @mutex.synchronize do
|
|
449
|
+
old = @connected
|
|
450
|
+
@connected = false
|
|
451
|
+
old
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
fail_all_pending(:ping_timeout) if was_connected
|
|
455
|
+
@io&.close rescue nil
|
|
456
|
+
end
|
|
457
|
+
|
|
445
458
|
def cleanup_socket
|
|
446
459
|
stop_ping_thread
|
|
447
460
|
@write_mutex.synchronize do
|
|
@@ -458,11 +471,17 @@ module DatagroutConduit
|
|
|
458
471
|
# Start the background ping thread. Sends one WS ping frame every
|
|
459
472
|
# @ping_interval seconds until the connection is torn down. No-op when
|
|
460
473
|
# @ping_interval is non-positive (used by tests to disable pinging).
|
|
474
|
+
#
|
|
475
|
+
# A ping still unanswered when the next is due closes the connection: a
|
|
476
|
+
# peer that vanished without a close frame (a dropped NAT mapping, a
|
|
477
|
+
# host that went away) is otherwise invisible until the OS gives up on
|
|
478
|
+
# the TCP connection.
|
|
461
479
|
def start_ping_thread
|
|
462
480
|
return if @ping_thread
|
|
463
481
|
return if @ping_interval <= 0
|
|
464
482
|
|
|
465
483
|
interval = @ping_interval
|
|
484
|
+
@awaiting_pong = false
|
|
466
485
|
@ping_thread = Thread.new do
|
|
467
486
|
loop do
|
|
468
487
|
sleep interval
|
|
@@ -471,15 +490,26 @@ module DatagroutConduit
|
|
|
471
490
|
driver = @driver
|
|
472
491
|
break unless driver
|
|
473
492
|
|
|
493
|
+
if @awaiting_pong
|
|
494
|
+
peer_gone
|
|
495
|
+
break
|
|
496
|
+
end
|
|
497
|
+
|
|
474
498
|
begin
|
|
475
499
|
# WebSocket::Driver#ping returns false if the connection is
|
|
476
|
-
# already closing; treat that as "stop the loop" too.
|
|
477
|
-
|
|
500
|
+
# already closing; treat that as "stop the loop" too. Its block
|
|
501
|
+
# runs when the matching pong arrives.
|
|
502
|
+
@awaiting_pong = true
|
|
503
|
+
@write_mutex.synchronize { driver.ping { @awaiting_pong = false } } || break
|
|
478
504
|
@pings_sent += 1
|
|
479
505
|
rescue StandardError
|
|
480
506
|
break
|
|
481
507
|
end
|
|
482
508
|
end
|
|
509
|
+
ensure
|
|
510
|
+
# A loop that ended on its own must not stop the next connect from
|
|
511
|
+
# starting a fresh one.
|
|
512
|
+
@ping_thread = nil if @ping_thread == Thread.current
|
|
483
513
|
end
|
|
484
514
|
@ping_thread.abort_on_exception = false
|
|
485
515
|
@ping_thread.name = "conduit-ws-ping"
|