faye-redis-ng 1.0.12 → 1.0.13
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/CHANGELOG.md +57 -1
- data/lib/faye/redis/subscription_manager.rb +29 -0
- data/lib/faye/redis/version.rb +1 -1
- data/lib/faye/redis.rb +2 -0
- 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: 1b5fc029a910d92539d5500a92a851a1b3db0857a5769e6aa9338b8155126cfd
|
|
4
|
+
data.tar.gz: cbf1c670cfe442f7511466f278280db0f8543eee8adcddd9dc0e5ba9a0527667
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ae3fb5749855e269fae14583b830bb3d6c55dda8cd90dd28f0bc2fcd4a91c1ca34b89db0a3ac8d7db9343a337653524f84f8b9d7680c089c14e4d42d172ae5f6
|
|
7
|
+
data.tar.gz: 4355fe52a0d572f61640bc1bef644563f1df61d0e37549e8d35d76a64b58eafb0a255570f973453cda769f5e3a47b01715995fcb111eaa10bcf9a5292077e369
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,45 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.0.13] - 2025-11-01
|
|
11
|
+
|
|
12
|
+
### Added - Ping-Based Subscription TTL Refresh
|
|
13
|
+
- **Subscription TTLs now refresh on every ping**: Keeps subscriptions alive as long as client is connected
|
|
14
|
+
- **New behavior**: Each client ping (every ~25s) now refreshes all subscription-related TTLs
|
|
15
|
+
- **Implementation**:
|
|
16
|
+
- Added `SubscriptionManager#refresh_client_subscriptions_ttl` method
|
|
17
|
+
- Modified `Redis#ping` to call subscription TTL refresh
|
|
18
|
+
- Uses pipelined Redis commands for efficient batch TTL updates
|
|
19
|
+
- **Impact**:
|
|
20
|
+
- ✅ Active clients: Subscriptions never expire while connected
|
|
21
|
+
- ✅ Inactive clients: Subscriptions expire 1 hour after last ping (as expected)
|
|
22
|
+
- ✅ Long-lived connections: Chat rooms, dashboards work indefinitely
|
|
23
|
+
- ✅ Prevents silent subscription expiration for active clients
|
|
24
|
+
- **Before**: Subscriptions expired after 1 hour even for active clients
|
|
25
|
+
- **After**: Subscriptions only expire 1 hour after client disconnects
|
|
26
|
+
- **Performance**: Minimal impact - uses single pipelined Redis call per ping
|
|
27
|
+
|
|
28
|
+
### Design Decision - Message Queue TTL Not Refreshed
|
|
29
|
+
- **Message queue TTL remains fixed at 1 hour**: Does not refresh on ping
|
|
30
|
+
- **Rationale**:
|
|
31
|
+
- Active clients: Messages are immediately delivered, queue is usually empty
|
|
32
|
+
- Empty queues that expire are automatically recreated when needed
|
|
33
|
+
- Inactive clients: 1-hour TTL provides sufficient buffer for reconnection
|
|
34
|
+
- Memory efficiency: Prevents permanent empty queue keys for long-lived connections
|
|
35
|
+
- **Trade-offs**:
|
|
36
|
+
- ✅ Better memory efficiency: Empty queues expire after 1 hour
|
|
37
|
+
- ✅ No functional impact: Messages still delivered normally to active clients
|
|
38
|
+
- ✅ Automatic cleanup: Long-term disconnected clients don't accumulate messages indefinitely
|
|
39
|
+
- **Behavior**:
|
|
40
|
+
- Active client: Queue may expire, but recreates automatically on next message
|
|
41
|
+
- Disconnected < 1 hour: All messages preserved for reconnection
|
|
42
|
+
- Disconnected > 1 hour: Messages cleared to prevent unbounded growth
|
|
43
|
+
|
|
44
|
+
### Notes
|
|
45
|
+
- Ping-based refresh ensures long-lived connections (chat, real-time dashboards) work correctly
|
|
46
|
+
- Message queue strategy balances reliability with memory efficiency
|
|
47
|
+
- The 1-hour TTL provides ample buffer (60 GC cycles) for cleanup after disconnect
|
|
48
|
+
|
|
10
49
|
## [1.0.12] - 2025-11-01
|
|
11
50
|
|
|
12
51
|
### Changed - Aligned Subscription TTL with Message TTL
|
|
@@ -32,11 +71,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
32
71
|
- `{namespace}:patterns` (SET)
|
|
33
72
|
- **Backward compatibility**: Users can still override with custom `subscription_ttl` option
|
|
34
73
|
|
|
74
|
+
### Added - Ping-Based Subscription TTL Refresh
|
|
75
|
+
- **Subscription TTLs now refresh on every ping**: Keeps subscriptions alive as long as client is connected
|
|
76
|
+
- **New behavior**: Each client ping (every ~25s) now refreshes all subscription-related TTLs
|
|
77
|
+
- **Implementation**:
|
|
78
|
+
- Added `SubscriptionManager#refresh_client_subscriptions_ttl` method
|
|
79
|
+
- Modified `Redis#ping` to call subscription TTL refresh
|
|
80
|
+
- Uses pipelined Redis commands for efficient batch TTL updates
|
|
81
|
+
- **Impact**:
|
|
82
|
+
- ✅ Active clients: Subscriptions never expire while connected
|
|
83
|
+
- ✅ Inactive clients: Subscriptions expire 1 hour after last ping (as expected)
|
|
84
|
+
- ✅ Long-lived connections: Chat rooms, dashboards work indefinitely
|
|
85
|
+
- ✅ Prevents silent subscription expiration for active clients
|
|
86
|
+
- **Before**: Subscriptions expired after 1 hour even for active clients
|
|
87
|
+
- **After**: Subscriptions only expire 1 hour after client disconnects
|
|
88
|
+
- **Performance**: Minimal impact - uses single pipelined Redis call per ping
|
|
89
|
+
|
|
35
90
|
### Notes
|
|
36
91
|
- This change ensures subscriptions don't expire before their associated messages
|
|
37
|
-
- The 1-hour TTL provides ample buffer (60 GC cycles) for cleanup
|
|
92
|
+
- The 1-hour TTL provides ample buffer (60 GC cycles) for cleanup after disconnect
|
|
38
93
|
- TTL-safe implementation (v1.0.10) ensures active subscriptions maintain their original TTL
|
|
39
94
|
- Conservative approach: prioritizes message delivery over aggressive memory optimization
|
|
95
|
+
- Ping-based refresh ensures long-lived connections (chat, real-time dashboards) work correctly
|
|
40
96
|
|
|
41
97
|
## [1.0.11] - 2025-10-31
|
|
42
98
|
|
|
@@ -118,6 +118,35 @@ module Faye
|
|
|
118
118
|
EventMachine.next_tick { callback.call(false) } if callback
|
|
119
119
|
end
|
|
120
120
|
|
|
121
|
+
# Refresh TTL for all subscription keys related to a client
|
|
122
|
+
# Called during ping to keep subscriptions alive as long as client is connected
|
|
123
|
+
def refresh_client_subscriptions_ttl(client_id)
|
|
124
|
+
subscription_ttl = @options[:subscription_ttl] || 3600
|
|
125
|
+
|
|
126
|
+
@connection.with_redis do |redis|
|
|
127
|
+
# Get all channels this client is subscribed to
|
|
128
|
+
channels = redis.smembers(client_subscriptions_key(client_id))
|
|
129
|
+
return if channels.empty?
|
|
130
|
+
|
|
131
|
+
# Use pipeline to refresh all TTLs efficiently
|
|
132
|
+
redis.pipelined do |pipeline|
|
|
133
|
+
# Refresh client's subscriptions set
|
|
134
|
+
pipeline.expire(client_subscriptions_key(client_id), subscription_ttl)
|
|
135
|
+
|
|
136
|
+
# Refresh each subscription metadata and channel subscriber set
|
|
137
|
+
channels.each do |channel|
|
|
138
|
+
pipeline.expire(subscription_key(client_id, channel), subscription_ttl)
|
|
139
|
+
pipeline.expire(channel_subscribers_key(channel), subscription_ttl)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Refresh patterns set if it exists
|
|
143
|
+
pipeline.expire(patterns_key, subscription_ttl)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
rescue => e
|
|
147
|
+
log_error("Failed to refresh subscription TTL for client #{client_id}: #{e.message}")
|
|
148
|
+
end
|
|
149
|
+
|
|
121
150
|
# Get all channels a client is subscribed to
|
|
122
151
|
def get_client_subscriptions(client_id, &callback)
|
|
123
152
|
channels = @connection.with_redis do |redis|
|
data/lib/faye/redis/version.rb
CHANGED
data/lib/faye/redis.rb
CHANGED
|
@@ -88,8 +88,10 @@ module Faye
|
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
# Ping a client to keep it alive
|
|
91
|
+
# Also refreshes subscription TTLs to keep them alive while client is connected
|
|
91
92
|
def ping(client_id)
|
|
92
93
|
@client_registry.ping(client_id)
|
|
94
|
+
@subscription_manager.refresh_client_subscriptions_ttl(client_id)
|
|
93
95
|
end
|
|
94
96
|
|
|
95
97
|
# Subscribe a client to a channel
|