faye-redis-ng 1.0.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 +7 -0
- data/CHANGELOG.md +41 -0
- data/LICENSE +21 -0
- data/README.md +271 -0
- data/lib/faye/redis/client_registry.rb +155 -0
- data/lib/faye/redis/connection.rb +107 -0
- data/lib/faye/redis/logger.rb +39 -0
- data/lib/faye/redis/message_queue.rb +207 -0
- data/lib/faye/redis/pubsub_coordinator.rb +207 -0
- data/lib/faye/redis/subscription_manager.rb +189 -0
- data/lib/faye/redis/version.rb +5 -0
- data/lib/faye/redis.rb +154 -0
- data/lib/faye-redis-ng.rb +5 -0
- metadata +128 -0
data/lib/faye/redis.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require_relative 'redis/version'
|
3
|
+
require_relative 'redis/logger'
|
4
|
+
require_relative 'redis/connection'
|
5
|
+
require_relative 'redis/client_registry'
|
6
|
+
require_relative 'redis/subscription_manager'
|
7
|
+
require_relative 'redis/message_queue'
|
8
|
+
require_relative 'redis/pubsub_coordinator'
|
9
|
+
|
10
|
+
module Faye
|
11
|
+
class Redis
|
12
|
+
# Default configuration options
|
13
|
+
DEFAULT_OPTIONS = {
|
14
|
+
host: 'localhost',
|
15
|
+
port: 6379,
|
16
|
+
database: 0,
|
17
|
+
password: nil,
|
18
|
+
pool_size: 5,
|
19
|
+
pool_timeout: 5,
|
20
|
+
connect_timeout: 1,
|
21
|
+
read_timeout: 1,
|
22
|
+
write_timeout: 1,
|
23
|
+
max_retries: 3,
|
24
|
+
retry_delay: 1,
|
25
|
+
client_timeout: 60,
|
26
|
+
message_ttl: 3600,
|
27
|
+
namespace: 'faye'
|
28
|
+
}.freeze
|
29
|
+
|
30
|
+
attr_reader :server, :options, :connection, :client_registry,
|
31
|
+
:subscription_manager, :message_queue, :pubsub_coordinator
|
32
|
+
|
33
|
+
# Factory method to create a new Redis engine instance
|
34
|
+
def self.create(server, options)
|
35
|
+
new(server, options)
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize(server, options = {})
|
39
|
+
@server = server
|
40
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
41
|
+
@logger = Logger.new('Faye::Redis', @options)
|
42
|
+
|
43
|
+
# Initialize components
|
44
|
+
@connection = Connection.new(@options)
|
45
|
+
@client_registry = ClientRegistry.new(@connection, @options)
|
46
|
+
@subscription_manager = SubscriptionManager.new(@connection, @options)
|
47
|
+
@message_queue = MessageQueue.new(@connection, @options)
|
48
|
+
@pubsub_coordinator = PubSubCoordinator.new(@connection, @options)
|
49
|
+
|
50
|
+
# Set up message routing
|
51
|
+
setup_message_routing
|
52
|
+
end
|
53
|
+
|
54
|
+
# Create a new client
|
55
|
+
def create_client(&callback)
|
56
|
+
client_id = generate_client_id
|
57
|
+
@client_registry.create(client_id) do |success|
|
58
|
+
if success
|
59
|
+
callback.call(client_id)
|
60
|
+
else
|
61
|
+
callback.call(nil)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Destroy a client
|
67
|
+
def destroy_client(client_id, &callback)
|
68
|
+
@subscription_manager.unsubscribe_all(client_id) do
|
69
|
+
@client_registry.destroy(client_id, &callback)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Check if a client exists
|
74
|
+
def client_exists(client_id, &callback)
|
75
|
+
@client_registry.exists?(client_id, &callback)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Ping a client to keep it alive
|
79
|
+
def ping(client_id)
|
80
|
+
@client_registry.ping(client_id)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Subscribe a client to a channel
|
84
|
+
def subscribe(client_id, channel, &callback)
|
85
|
+
@subscription_manager.subscribe(client_id, channel, &callback)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Unsubscribe a client from a channel
|
89
|
+
def unsubscribe(client_id, channel, &callback)
|
90
|
+
@subscription_manager.unsubscribe(client_id, channel, &callback)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Publish a message to channels
|
94
|
+
def publish(message, channels, &callback)
|
95
|
+
channels = [channels] unless channels.is_a?(Array)
|
96
|
+
success = true
|
97
|
+
|
98
|
+
begin
|
99
|
+
channels.each do |channel|
|
100
|
+
# Store message in queues for subscribed clients
|
101
|
+
@subscription_manager.get_subscribers(channel) do |client_ids|
|
102
|
+
client_ids.each do |client_id|
|
103
|
+
@message_queue.enqueue(client_id, message) do |enqueued|
|
104
|
+
success &&= enqueued
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Publish to Redis pub/sub for cross-server routing
|
110
|
+
@pubsub_coordinator.publish(channel, message) do |published|
|
111
|
+
success &&= published
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
EventMachine.next_tick { callback.call(success) } if callback
|
116
|
+
rescue => e
|
117
|
+
log_error("Failed to publish message to channels #{channels}: #{e.message}")
|
118
|
+
EventMachine.next_tick { callback.call(false) } if callback
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Empty a client's message queue
|
123
|
+
def empty_queue(client_id)
|
124
|
+
@message_queue.dequeue_all(client_id)
|
125
|
+
end
|
126
|
+
|
127
|
+
# Disconnect the engine
|
128
|
+
def disconnect
|
129
|
+
@pubsub_coordinator.disconnect
|
130
|
+
@connection.disconnect
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
def generate_client_id
|
136
|
+
SecureRandom.uuid
|
137
|
+
end
|
138
|
+
|
139
|
+
def setup_message_routing
|
140
|
+
# Subscribe to message events from other servers
|
141
|
+
@pubsub_coordinator.on_message do |channel, message|
|
142
|
+
@subscription_manager.get_subscribers(channel) do |client_ids|
|
143
|
+
client_ids.each do |client_id|
|
144
|
+
@message_queue.enqueue(client_id, message)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def log_error(message)
|
151
|
+
@logger.error(message)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
metadata
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: faye-redis-ng
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Zac
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-10-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: redis
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: connection_pool
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.5'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.5'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: eventmachine
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.0.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.0.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.12'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.12'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '13.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '13.0'
|
83
|
+
description: A Redis-based backend engine for Faye messaging server, allowing distribution
|
84
|
+
across multiple web servers
|
85
|
+
email: 579103+7a6163@users.noreply.github.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- CHANGELOG.md
|
91
|
+
- LICENSE
|
92
|
+
- README.md
|
93
|
+
- lib/faye-redis-ng.rb
|
94
|
+
- lib/faye/redis.rb
|
95
|
+
- lib/faye/redis/client_registry.rb
|
96
|
+
- lib/faye/redis/connection.rb
|
97
|
+
- lib/faye/redis/logger.rb
|
98
|
+
- lib/faye/redis/message_queue.rb
|
99
|
+
- lib/faye/redis/pubsub_coordinator.rb
|
100
|
+
- lib/faye/redis/subscription_manager.rb
|
101
|
+
- lib/faye/redis/version.rb
|
102
|
+
homepage: https://github.com/7a6163/faye-redis-ng
|
103
|
+
licenses:
|
104
|
+
- MIT
|
105
|
+
metadata:
|
106
|
+
homepage_uri: https://github.com/7a6163/faye-redis-ng
|
107
|
+
source_code_uri: https://github.com/7a6163/faye-redis-ng
|
108
|
+
changelog_uri: https://github.com/7a6163/faye-redis-ng/blob/main/CHANGELOG.md
|
109
|
+
post_install_message:
|
110
|
+
rdoc_options: []
|
111
|
+
require_paths:
|
112
|
+
- lib
|
113
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 2.7.0
|
118
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
requirements: []
|
124
|
+
rubygems_version: 3.5.22
|
125
|
+
signing_key:
|
126
|
+
specification_version: 4
|
127
|
+
summary: Redis backend for Faye
|
128
|
+
test_files: []
|