cable_room 0.6.2 → 0.7.0.beta1
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 +122 -0
- data/README.md +1190 -0
- data/cable_room.gemspec +5 -2
- data/exe/cable_room +8 -0
- data/lib/cable_room/broadcaster.rb +116 -0
- data/lib/cable_room/bus.rb +372 -0
- data/lib/cable_room/cli.rb +237 -0
- data/lib/cable_room/config.rb +112 -0
- data/lib/cable_room/host/bus_inbound.rb +36 -0
- data/lib/cable_room/host/runner.rb +571 -0
- data/lib/cable_room/host/supervisor.rb +275 -0
- data/lib/cable_room/host/worker_pool.rb +37 -0
- data/lib/cable_room/host.rb +477 -0
- data/lib/cable_room/membership_store.rb +105 -0
- data/lib/cable_room/migration.rb +586 -0
- data/lib/cable_room/periodic_timer.rb +18 -0
- data/lib/cable_room/placement.rb +258 -0
- data/lib/cable_room/ports.rb +19 -11
- data/lib/cable_room/railtie.rb +3 -12
- data/lib/cable_room/room/base.rb +45 -39
- data/lib/cable_room/room/host_adapter.rb +52 -0
- data/lib/cable_room/room/lifecycle.rb +26 -9
- data/lib/cable_room/room/port_management.rb +57 -0
- data/lib/cable_room/room/reaping.rb +34 -1
- data/lib/cable_room/room/snapshotting.rb +78 -0
- data/lib/cable_room/room/threading.rb +2 -2
- data/lib/cable_room/room/user_management.rb +27 -0
- data/lib/cable_room/room.rb +5 -2
- data/lib/cable_room/room_member.rb +260 -84
- data/lib/cable_room/room_proxy_channel.rb +13 -2
- data/lib/cable_room/snapshot.rb +136 -0
- data/lib/cable_room/version.rb +1 -1
- data/lib/cable_room.rb +57 -2
- metadata +25 -9
- data/lib/cable_room/channel_base.rb +0 -262
- data/lib/cable_room/channel_tracker.rb +0 -130
- data/lib/cable_room/room/channel_adapter.rb +0 -18
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
module CableRoom
|
|
2
|
-
class ChannelTracker
|
|
3
|
-
def self.instance
|
|
4
|
-
@instance ||= new
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
BEAT_INTERVAL = 5.seconds
|
|
8
|
-
|
|
9
|
-
delegate :logger, :pubsub, :event_loop, :config, to: :cable_server
|
|
10
|
-
|
|
11
|
-
attr_reader :room_channels, :scheduler
|
|
12
|
-
|
|
13
|
-
def initialize
|
|
14
|
-
@room_channels = Set.new
|
|
15
|
-
@monitor = Monitor.new
|
|
16
|
-
|
|
17
|
-
@scheduler = Rufus::Scheduler.new
|
|
18
|
-
|
|
19
|
-
at_exit do
|
|
20
|
-
logger.info "Shutting down CableRoom"
|
|
21
|
-
shutdown!
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
scheduler.every(BEAT_INTERVAL) do
|
|
25
|
-
each_room_channel do |chan|
|
|
26
|
-
chan.beat
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def worker_pool
|
|
32
|
-
# TODO Pin Rooms to a specific thread so that they never have to worry about thread safety?
|
|
33
|
-
@worker_pool || @monitor.synchronize { @worker_pool ||= ThreadPool.new(max_size: config.worker_pool_size) }
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def track_room_channel(chan)
|
|
37
|
-
raise "Cannot add Room after shutdown" if @shutdown
|
|
38
|
-
@room_channels << chan
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def untrack_room_channel(chan)
|
|
42
|
-
@room_channels.delete(chan)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def shutdown?
|
|
46
|
-
@shutdown
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def shutdown!
|
|
50
|
-
@monitor.synchronize do
|
|
51
|
-
@shutdown = true
|
|
52
|
-
|
|
53
|
-
scheduler.shutdown
|
|
54
|
-
|
|
55
|
-
shutdown_rooms!
|
|
56
|
-
|
|
57
|
-
worker_pool.executor.shutdown
|
|
58
|
-
worker_pool.executor.wait_for_termination(5)
|
|
59
|
-
worker_pool.executor.kill
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def shutdown_rooms!
|
|
64
|
-
@monitor.synchronize do
|
|
65
|
-
each_room_channel do |chan|
|
|
66
|
-
chan.initiate_shutdown("Server shutting down")
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
count = 0
|
|
71
|
-
loop do
|
|
72
|
-
break if @room_channels.empty? || count >= 15
|
|
73
|
-
sleep 1
|
|
74
|
-
count += 1
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def each_room_channel(&blk)
|
|
79
|
-
@room_channels.dup.each(&blk)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
private
|
|
83
|
-
|
|
84
|
-
def cable_server
|
|
85
|
-
ActionCable.server
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
class ThreadPool < ActionCable::Server::Worker
|
|
89
|
-
set_callback :work, :around do |_, blk|
|
|
90
|
-
pconn = ActionCable::Server::Worker.connection
|
|
91
|
-
ActionCable::Server::Worker.connection = connection
|
|
92
|
-
blk.call
|
|
93
|
-
ensure
|
|
94
|
-
ActionCable::Server::Worker.connection = pconn
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
# ActionCable's Worker#invoke reduces every exception to a log line and a no-argument
|
|
98
|
-
# `handle_exception` call, which discards the error itself. Rooms run all of their work
|
|
99
|
-
# through here, so report it properly instead.
|
|
100
|
-
def invoke(receiver, method, *args, connection:, &block)
|
|
101
|
-
work(connection) do
|
|
102
|
-
receiver.send method, *args, &block
|
|
103
|
-
rescue Exception => e
|
|
104
|
-
if connection.respond_to?(:report_work_error)
|
|
105
|
-
connection.report_work_error(e)
|
|
106
|
-
else
|
|
107
|
-
logger.error "There was an exception - #{e.class}(#{e.message})"
|
|
108
|
-
logger.error Array(e.backtrace).join("\n")
|
|
109
|
-
CableRoom.report_error(e, connection: connection)
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def async_invoke(receiver, method, *args, connection: receiver, &block)
|
|
115
|
-
# Instead of posting directly to the global pool, post to a dedicated queue for the room/"connection".
|
|
116
|
-
# This makes each rooms so that they can be processed by at-most-one thread at a time, while still
|
|
117
|
-
# allowing multiple rooms to be processed by the same thread-pool.
|
|
118
|
-
|
|
119
|
-
# TODO Implement more of a round-robin approach so that no room can starve out others?
|
|
120
|
-
|
|
121
|
-
# "connection" here really references the Channel, since "Connections" in this context don't really exist
|
|
122
|
-
|
|
123
|
-
connection._post_wrapped_work(async: false) do
|
|
124
|
-
invoke(receiver, method, *args, connection: connection, &block)
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
end
|
|
130
|
-
end
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
module CableRoom
|
|
2
|
-
module Room
|
|
3
|
-
module ChannelAdapter
|
|
4
|
-
extend ActiveSupport::Concern
|
|
5
|
-
|
|
6
|
-
Channel = CableRoom::ChannelBase
|
|
7
|
-
|
|
8
|
-
class_methods do
|
|
9
|
-
def inherited(subclass)
|
|
10
|
-
# Descend from *this* class's Channel, so periodic timers and other channel-level
|
|
11
|
-
# configuration survive multiple levels of subclassing
|
|
12
|
-
subclass.const_set(:Channel, Class.new(self::Channel))
|
|
13
|
-
super
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|