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.
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
@@ -0,0 +1,5 @@
1
+ require 'redis'
2
+ require 'connection_pool'
3
+ require 'eventmachine'
4
+
5
+ require_relative 'faye/redis'
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: []