message_bus 3.3.3 → 3.3.7
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/.eslintrc.js +21 -0
- data/.github/workflows/ci.yml +71 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +3 -1
- data/CHANGELOG +36 -8
- data/DEV.md +7 -0
- data/Gemfile +0 -25
- data/LICENSE +1 -1
- data/README.md +34 -15
- data/Rakefile +13 -8
- data/assets/message-bus-ajax.js +4 -10
- data/assets/message-bus.js +69 -76
- data/bench/codecs/all_codecs.rb +39 -0
- data/bench/codecs/marshal.rb +11 -0
- data/bench/codecs/packed_string.rb +67 -0
- data/bench/codecs/string_hack.rb +47 -0
- data/bench/codecs_large_user_list.rb +29 -0
- data/bench/codecs_standard_message.rb +29 -0
- data/examples/bench/bench.lua +2 -2
- data/lib/message_bus/backends/base.rb +3 -5
- data/lib/message_bus/backends/memory.rb +0 -2
- data/lib/message_bus/backends/postgres.rb +7 -5
- data/lib/message_bus/backends/redis.rb +3 -5
- data/lib/message_bus/client.rb +3 -7
- data/lib/message_bus/codec/base.rb +18 -0
- data/lib/message_bus/codec/json.rb +15 -0
- data/lib/message_bus/codec/oj.rb +21 -0
- data/lib/message_bus/connection_manager.rb +1 -1
- data/lib/message_bus/distributed_cache.rb +2 -1
- data/lib/message_bus/http_client.rb +2 -2
- data/lib/message_bus/rack/diagnostics.rb +30 -8
- data/lib/message_bus/rack/middleware.rb +22 -16
- data/lib/message_bus/rack/thin_ext.rb +1 -1
- data/lib/message_bus/version.rb +1 -1
- data/lib/message_bus.rb +38 -23
- data/message_bus.gemspec +20 -5
- data/package-lock.json +3744 -0
- data/package.json +14 -4
- data/spec/assets/SpecHelper.js +6 -5
- data/spec/assets/message-bus.spec.js +9 -6
- data/spec/helpers.rb +17 -6
- data/spec/integration/http_client_spec.rb +1 -1
- data/spec/lib/message_bus/backend_spec.rb +12 -44
- data/spec/lib/message_bus/client_spec.rb +6 -6
- data/spec/lib/message_bus/distributed_cache_spec.rb +5 -7
- data/spec/lib/message_bus/multi_process_spec.rb +1 -1
- data/spec/lib/message_bus/rack/middleware_spec.rb +16 -5
- data/spec/lib/message_bus_spec.rb +18 -7
- data/spec/spec_helper.rb +8 -9
- data/spec/support/jasmine-browser.json +16 -0
- metadata +230 -13
- data/.travis.yml +0 -17
- data/lib/message_bus/em_ext.rb +0 -6
- data/spec/assets/support/jasmine.yml +0 -126
- data/spec/assets/support/jasmine_helper.rb +0 -11
- data/vendor/assets/javascripts/message-bus-ajax.js +0 -44
- data/vendor/assets/javascripts/message-bus.js +0 -556
@@ -2,8 +2,6 @@
|
|
2
2
|
|
3
3
|
require 'pg'
|
4
4
|
|
5
|
-
require "message_bus/backends/base"
|
6
|
-
|
7
5
|
module MessageBus
|
8
6
|
module Backends
|
9
7
|
# The Postgres backend stores published messages in a single Postgres table
|
@@ -46,6 +44,7 @@ module MessageBus
|
|
46
44
|
@listening_on = {}
|
47
45
|
@available = []
|
48
46
|
@allocated = {}
|
47
|
+
@subscribe_connection = nil
|
49
48
|
@mutex = Mutex.new
|
50
49
|
@pid = Process.pid
|
51
50
|
end
|
@@ -133,7 +132,7 @@ module MessageBus
|
|
133
132
|
listener = Listener.new
|
134
133
|
yield listener
|
135
134
|
|
136
|
-
conn = raw_pg_connection
|
135
|
+
conn = @subscribe_connection = raw_pg_connection
|
137
136
|
conn.exec "LISTEN #{channel}"
|
138
137
|
listener.do_sub.call
|
139
138
|
while listening_on?(channel, obj)
|
@@ -147,6 +146,9 @@ module MessageBus
|
|
147
146
|
|
148
147
|
conn.exec "UNLISTEN #{channel}"
|
149
148
|
nil
|
149
|
+
ensure
|
150
|
+
@subscribe_connection&.close
|
151
|
+
@subscribe_connection = nil
|
150
152
|
end
|
151
153
|
|
152
154
|
def unsubscribe
|
@@ -253,7 +255,7 @@ module MessageBus
|
|
253
255
|
@clear_every = config[:clear_every] || 1
|
254
256
|
end
|
255
257
|
|
256
|
-
# Reconnects to Postgres; used after a process fork, typically
|
258
|
+
# Reconnects to Postgres; used after a process fork, typically triggered by a forking webserver
|
257
259
|
# @see Base#after_fork
|
258
260
|
def after_fork
|
259
261
|
client.reconnect
|
@@ -279,7 +281,7 @@ module MessageBus
|
|
279
281
|
msg = MessageBus::Message.new backlog_id, backlog_id, channel, data
|
280
282
|
payload = msg.encode
|
281
283
|
c.publish postgresql_channel_name, payload
|
282
|
-
if backlog_id % clear_every == 0
|
284
|
+
if backlog_id && backlog_id % clear_every == 0
|
283
285
|
max_backlog_size = (opts && opts[:max_backlog_size]) || self.max_backlog_size
|
284
286
|
max_backlog_age = (opts && opts[:max_backlog_age]) || self.max_backlog_age
|
285
287
|
c.clear_global_backlog(backlog_id, @max_global_backlog_size)
|
@@ -3,8 +3,6 @@
|
|
3
3
|
require 'redis'
|
4
4
|
require 'digest'
|
5
5
|
|
6
|
-
require "message_bus/backends/base"
|
7
|
-
|
8
6
|
module MessageBus
|
9
7
|
module Backends
|
10
8
|
# The Redis backend stores published messages in Redis sorted sets (using
|
@@ -64,7 +62,7 @@ module MessageBus
|
|
64
62
|
@max_backlog_age = 604800
|
65
63
|
end
|
66
64
|
|
67
|
-
# Reconnects to Redis; used after a process fork, typically
|
65
|
+
# Reconnects to Redis; used after a process fork, typically triggered by a forking webserver
|
68
66
|
# @see Base#after_fork
|
69
67
|
def after_fork
|
70
68
|
pub_redis.disconnect!
|
@@ -104,8 +102,8 @@ module MessageBus
|
|
104
102
|
|
105
103
|
local global_id = redis.call("INCR", global_id_key)
|
106
104
|
local backlog_id = redis.call("INCR", backlog_id_key)
|
107
|
-
local payload =
|
108
|
-
local global_backlog_message =
|
105
|
+
local payload = table.concat({ global_id, backlog_id, start_payload }, "|")
|
106
|
+
local global_backlog_message = table.concat({ backlog_id, channel }, "|")
|
109
107
|
|
110
108
|
redis.call("ZADD", backlog_key, backlog_id, payload)
|
111
109
|
redis.call("EXPIRE", backlog_key, max_backlog_age)
|
data/lib/message_bus/client.rb
CHANGED
@@ -220,7 +220,7 @@ class MessageBus::Client
|
|
220
220
|
|
221
221
|
private
|
222
222
|
|
223
|
-
# heavily optimised to avoid all
|
223
|
+
# heavily optimised to avoid all unneeded allocations
|
224
224
|
NEWLINE = "\r\n".freeze
|
225
225
|
COLON_SPACE = ": ".freeze
|
226
226
|
HTTP_11 = "HTTP/1.1 200 OK\r\n".freeze
|
@@ -261,7 +261,7 @@ class MessageBus::Client
|
|
261
261
|
@wrote_headers = true
|
262
262
|
end
|
263
263
|
|
264
|
-
# chunked encoding may be "re-chunked" by proxies, so add a
|
264
|
+
# chunked encoding may be "re-chunked" by proxies, so add a separator
|
265
265
|
postfix = NEWLINE + "|" + NEWLINE
|
266
266
|
data = data.gsub(postfix, NEWLINE + "||" + NEWLINE)
|
267
267
|
chunk_length = data.bytesize + postfix.bytesize
|
@@ -275,11 +275,7 @@ class MessageBus::Client
|
|
275
275
|
@async_response << postfix
|
276
276
|
@async_response << NEWLINE
|
277
277
|
else
|
278
|
-
@io.write(chunk_length.to_s(16))
|
279
|
-
@io.write(NEWLINE)
|
280
|
-
@io.write(data)
|
281
|
-
@io.write(postfix)
|
282
|
-
@io.write(NEWLINE)
|
278
|
+
@io.write(chunk_length.to_s(16) << NEWLINE << data << postfix << NEWLINE)
|
283
279
|
end
|
284
280
|
end
|
285
281
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MessageBus
|
4
|
+
module Codec
|
5
|
+
class Base
|
6
|
+
def encode(hash)
|
7
|
+
raise ConcreteClassMustImplementError
|
8
|
+
end
|
9
|
+
|
10
|
+
def decode(payload)
|
11
|
+
raise ConcreteClassMustImplementError
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
autoload :Json, File.expand_path("json", __dir__)
|
16
|
+
autoload :Oj, File.expand_path("oj", __dir__)
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'oj' unless defined? ::Oj
|
4
|
+
|
5
|
+
module MessageBus
|
6
|
+
module Codec
|
7
|
+
class Oj < Base
|
8
|
+
def initialize(options = { mode: :compat })
|
9
|
+
@options = options
|
10
|
+
end
|
11
|
+
|
12
|
+
def encode(hash)
|
13
|
+
::Oj.dump(hash, @options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def decode(payload)
|
17
|
+
::Oj.load(payload, @options)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -45,7 +45,8 @@ module MessageBus
|
|
45
45
|
hash = current.hash(message.site_id || DEFAULT_SITE_ID)
|
46
46
|
|
47
47
|
case payload["op"]
|
48
|
-
|
48
|
+
# TODO: consider custom marshal support with a restricted set
|
49
|
+
when "set" then hash[payload["key"]] = payload["marshalled"] ? Marshal.load(Base64.decode64(payload["value"])) : payload["value"] # rubocop:disable Security/MarshalLoad
|
49
50
|
when "delete" then hash.delete(payload["key"])
|
50
51
|
when "clear" then hash.clear
|
51
52
|
end
|
@@ -146,8 +146,8 @@ module MessageBus
|
|
146
146
|
#
|
147
147
|
# A last_message_id may be provided.
|
148
148
|
# * -1 will subscribe to all new messages
|
149
|
-
# * -2 will
|
150
|
-
# * -3 will
|
149
|
+
# * -2 will receive last message + all new messages
|
150
|
+
# * -3 will receive last 2 message + all new messages
|
151
151
|
#
|
152
152
|
# @example Subscribing to a channel with `last_message_id`
|
153
153
|
# client.subscribe("/test", last_message_id: -2) do |payload|
|
@@ -13,6 +13,15 @@ class MessageBus::Rack::Diagnostics
|
|
13
13
|
@bus = config[:message_bus] || MessageBus
|
14
14
|
end
|
15
15
|
|
16
|
+
JS_ASSETS = %w{
|
17
|
+
jquery-1.8.2.js
|
18
|
+
react.js
|
19
|
+
react-dom.js
|
20
|
+
babel.min.js
|
21
|
+
message-bus.js
|
22
|
+
application.jsx
|
23
|
+
}
|
24
|
+
|
16
25
|
# Process an HTTP request from a subscriber client
|
17
26
|
# @param [Rack::Request::Env] env the request environment
|
18
27
|
def call(env)
|
@@ -39,9 +48,9 @@ class MessageBus::Rack::Diagnostics
|
|
39
48
|
end
|
40
49
|
|
41
50
|
asset = route.split('/assets/')[1]
|
42
|
-
|
51
|
+
|
52
|
+
if asset && JS_ASSETS.include?(asset)
|
43
53
|
content = asset_contents(asset)
|
44
|
-
split = asset.split('.')
|
45
54
|
return [200, { 'Content-Type' => 'application/javascript;charset=UTF-8' }, [content]]
|
46
55
|
end
|
47
56
|
|
@@ -75,6 +84,23 @@ class MessageBus::Rack::Diagnostics
|
|
75
84
|
File.expand_path("../../../../assets/#{asset}", __FILE__)
|
76
85
|
end
|
77
86
|
|
87
|
+
def script_tags
|
88
|
+
tags = []
|
89
|
+
|
90
|
+
JS_ASSETS.each do |asset|
|
91
|
+
type =
|
92
|
+
if asset.end_with?('.js')
|
93
|
+
'text/javascript'
|
94
|
+
elsif asset.end_with?('.jsx')
|
95
|
+
'text/jsx'
|
96
|
+
end
|
97
|
+
|
98
|
+
tags << js_asset(asset, type)
|
99
|
+
end
|
100
|
+
|
101
|
+
tags.join("\n")
|
102
|
+
end
|
103
|
+
|
78
104
|
def index
|
79
105
|
html = <<~HTML
|
80
106
|
<!DOCTYPE html>
|
@@ -83,12 +109,8 @@ class MessageBus::Rack::Diagnostics
|
|
83
109
|
</head>
|
84
110
|
<body>
|
85
111
|
<div id="app"></div>
|
86
|
-
|
87
|
-
#{
|
88
|
-
#{js_asset "react-dom.js"}
|
89
|
-
#{js_asset "babel.min.js"}
|
90
|
-
#{js_asset "message-bus.js"}
|
91
|
-
#{js_asset "application.jsx", "text/jsx"}
|
112
|
+
|
113
|
+
#{script_tags}
|
92
114
|
</body>
|
93
115
|
</html>
|
94
116
|
HTML
|
@@ -66,6 +66,12 @@ class MessageBus::Rack::Middleware
|
|
66
66
|
private
|
67
67
|
|
68
68
|
def handle_request(env)
|
69
|
+
# Prevent simple polling from clobbering the session
|
70
|
+
# See: https://github.com/discourse/message_bus/issues/257
|
71
|
+
if (rack_session_options = env[Rack::RACK_SESSION_OPTIONS])
|
72
|
+
rack_session_options[:skip] = true
|
73
|
+
end
|
74
|
+
|
69
75
|
# special debug/test route
|
70
76
|
if @bus.allow_broadcast? && env['PATH_INFO'] == @broadcast_route
|
71
77
|
parsed = Rack::Request.new(env)
|
@@ -81,6 +87,22 @@ class MessageBus::Rack::Middleware
|
|
81
87
|
client_id = env['PATH_INFO'][@base_route_length..-1].split("/")[0]
|
82
88
|
return [404, {}, ["not found"]] unless client_id
|
83
89
|
|
90
|
+
headers = {}
|
91
|
+
headers["Cache-Control"] = "must-revalidate, private, max-age=0"
|
92
|
+
headers["Content-Type"] = "application/json; charset=utf-8"
|
93
|
+
headers["Pragma"] = "no-cache"
|
94
|
+
headers["Expires"] = "0"
|
95
|
+
|
96
|
+
if @bus.extra_response_headers_lookup
|
97
|
+
@bus.extra_response_headers_lookup.call(env).each do |k, v|
|
98
|
+
headers[k] = v
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
if env["REQUEST_METHOD"] == "OPTIONS"
|
103
|
+
return [200, headers, ["OK"]]
|
104
|
+
end
|
105
|
+
|
84
106
|
user_id = @bus.user_id_lookup.call(env) if @bus.user_id_lookup
|
85
107
|
group_ids = @bus.group_ids_lookup.call(env) if @bus.group_ids_lookup
|
86
108
|
site_id = @bus.site_id_lookup.call(env) if @bus.site_id_lookup
|
@@ -111,22 +133,6 @@ class MessageBus::Rack::Middleware
|
|
111
133
|
end
|
112
134
|
end
|
113
135
|
|
114
|
-
headers = {}
|
115
|
-
headers["Cache-Control"] = "must-revalidate, private, max-age=0"
|
116
|
-
headers["Content-Type"] = "application/json; charset=utf-8"
|
117
|
-
headers["Pragma"] = "no-cache"
|
118
|
-
headers["Expires"] = "0"
|
119
|
-
|
120
|
-
if @bus.extra_response_headers_lookup
|
121
|
-
@bus.extra_response_headers_lookup.call(env).each do |k, v|
|
122
|
-
headers[k] = v
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
if env["REQUEST_METHOD"] == "OPTIONS"
|
127
|
-
return [200, headers, ["OK"]]
|
128
|
-
end
|
129
|
-
|
130
136
|
long_polling = @bus.long_polling_enabled? &&
|
131
137
|
env['QUERY_STRING'] !~ /dlp=t/ &&
|
132
138
|
@connection_manager.client_count < @bus.max_active_clients
|
data/lib/message_bus/version.rb
CHANGED
data/lib/message_bus.rb
CHANGED
@@ -2,18 +2,22 @@
|
|
2
2
|
|
3
3
|
require "monitor"
|
4
4
|
require "set"
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
5
|
+
|
6
|
+
require_relative "message_bus/version"
|
7
|
+
require_relative "message_bus/message"
|
8
|
+
require_relative "message_bus/client"
|
9
|
+
require_relative "message_bus/connection_manager"
|
10
|
+
require_relative "message_bus/diagnostics"
|
11
|
+
require_relative "message_bus/rack/middleware"
|
12
|
+
require_relative "message_bus/rack/diagnostics"
|
13
|
+
require_relative "message_bus/timer_thread"
|
14
|
+
require_relative "message_bus/codec/base"
|
15
|
+
require_relative "message_bus/backends"
|
16
|
+
require_relative "message_bus/backends/base"
|
13
17
|
|
14
18
|
# we still need to take care of the logger
|
15
|
-
if defined?(::Rails)
|
16
|
-
|
19
|
+
if defined?(::Rails::Engine)
|
20
|
+
require_relative 'message_bus/rails/railtie'
|
17
21
|
end
|
18
22
|
|
19
23
|
# @see MessageBus::Implementation
|
@@ -96,14 +100,14 @@ module MessageBus::Implementation
|
|
96
100
|
configure(long_polling_enabled: val)
|
97
101
|
end
|
98
102
|
|
99
|
-
# @param [Integer] val The number of
|
103
|
+
# @param [Integer] val The number of simultaneous clients we can service;
|
100
104
|
# will revert to polling if we are out of slots
|
101
105
|
# @return [void]
|
102
106
|
def max_active_clients=(val)
|
103
107
|
configure(max_active_clients: val)
|
104
108
|
end
|
105
109
|
|
106
|
-
# @return [Integer] The number of
|
110
|
+
# @return [Integer] The number of simultaneous clients we can service;
|
107
111
|
# will revert to polling if we are out of slots. Defaults to 1000 if not
|
108
112
|
# explicitly set.
|
109
113
|
def max_active_clients
|
@@ -271,13 +275,24 @@ module MessageBus::Implementation
|
|
271
275
|
# set, defaults to false unless we're in Rails test or development mode.
|
272
276
|
def allow_broadcast?
|
273
277
|
@config[:allow_broadcast] ||=
|
274
|
-
if defined? ::Rails
|
278
|
+
if defined? ::Rails.env
|
275
279
|
::Rails.env.test? || ::Rails.env.development?
|
276
280
|
else
|
277
281
|
false
|
278
282
|
end
|
279
283
|
end
|
280
284
|
|
285
|
+
# @param [MessageBus::Codec::Base] codec used to encode and decode Message payloads
|
286
|
+
# @return [void]
|
287
|
+
def transport_codec=(codec)
|
288
|
+
configure(transport_codec: codec)
|
289
|
+
end
|
290
|
+
|
291
|
+
# @return [MessageBus::Codec::Base] codec used to encode and decode Message payloads
|
292
|
+
def transport_codec
|
293
|
+
@config[:transport_codec] ||= MessageBus::Codec::Json.new
|
294
|
+
end
|
295
|
+
|
281
296
|
# @param [MessageBus::Backend::Base] pub_sub a configured backend
|
282
297
|
# @return [void]
|
283
298
|
def reliable_pub_sub=(pub_sub)
|
@@ -323,7 +338,7 @@ module MessageBus::Implementation
|
|
323
338
|
# @option opts [Array<String,Integer>] :group_ids (`nil`) the group IDs to which the message should be available. If nil, available to all.
|
324
339
|
# @option opts [String] :site_id (`nil`) the site ID to scope the message to; used for hosting multiple
|
325
340
|
# applications or instances of an application against a single message_bus
|
326
|
-
# @option opts [nil,Integer] :max_backlog_age the longest amount of time a message may live in a backlog before
|
341
|
+
# @option opts [nil,Integer] :max_backlog_age the longest amount of time a message may live in a backlog before being removed, in seconds
|
327
342
|
# @option opts [nil,Integer] :max_backlog_size the largest permitted size (number of messages) for the channel backlog; beyond this capacity, old messages will be dropped
|
328
343
|
#
|
329
344
|
# @return [Integer] the channel-specific ID the message was given
|
@@ -358,18 +373,18 @@ module MessageBus::Implementation
|
|
358
373
|
raise ::MessageBus::InvalidMessageTarget
|
359
374
|
end
|
360
375
|
|
361
|
-
encoded_data =
|
362
|
-
data
|
363
|
-
user_ids
|
364
|
-
group_ids
|
365
|
-
client_ids
|
366
|
-
)
|
376
|
+
encoded_data = transport_codec.encode({
|
377
|
+
"data" => data,
|
378
|
+
"user_ids" => user_ids,
|
379
|
+
"group_ids" => group_ids,
|
380
|
+
"client_ids" => client_ids
|
381
|
+
})
|
367
382
|
|
368
383
|
channel_opts = {}
|
369
384
|
|
370
385
|
if opts
|
371
386
|
if ((age = opts[:max_backlog_age]) || (size = opts[:max_backlog_size]))
|
372
|
-
channel_opts[:max_backlog_size] = size
|
387
|
+
channel_opts[:max_backlog_size] = size
|
373
388
|
channel_opts[:max_backlog_age] = age
|
374
389
|
end
|
375
390
|
|
@@ -512,7 +527,7 @@ module MessageBus::Implementation
|
|
512
527
|
end
|
513
528
|
|
514
529
|
# Stops listening for publications and stops executing scheduled tasks.
|
515
|
-
# Mostly used in tests to
|
530
|
+
# Mostly used in tests to destroy entire bus.
|
516
531
|
# @return [void]
|
517
532
|
def destroy
|
518
533
|
return if @destroyed
|
@@ -626,7 +641,7 @@ module MessageBus::Implementation
|
|
626
641
|
channel, site_id = decode_channel_name(msg.channel)
|
627
642
|
msg.channel = channel
|
628
643
|
msg.site_id = site_id
|
629
|
-
parsed =
|
644
|
+
parsed = transport_codec.decode(msg.data)
|
630
645
|
msg.data = parsed["data"]
|
631
646
|
msg.user_ids = parsed["user_ids"]
|
632
647
|
msg.group_ids = parsed["group_ids"]
|
data/message_bus.gemspec
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
# -*- encoding: utf-8 -*-
|
3
2
|
|
4
3
|
require File.expand_path('../lib/message_bus/version', __FILE__)
|
5
4
|
|
@@ -8,17 +7,33 @@ Gem::Specification.new do |gem|
|
|
8
7
|
gem.email = ["sam.saffron@gmail.com"]
|
9
8
|
gem.description = %q{A message bus for rack}
|
10
9
|
gem.summary = %q{}
|
11
|
-
gem.homepage = "https://github.com/
|
10
|
+
gem.homepage = "https://github.com/discourse/message_bus"
|
12
11
|
gem.license = "MIT"
|
13
|
-
gem.files = `git ls-files`.split($\)
|
14
|
-
["vendor/assets/javascripts/message-bus.js", "vendor/assets/javascripts/message-bus-ajax.js"]
|
12
|
+
gem.files = `git ls-files`.split($\)
|
15
13
|
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
16
14
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
17
15
|
gem.name = "message_bus"
|
18
16
|
gem.require_paths = ["lib"]
|
19
17
|
gem.version = MessageBus::VERSION
|
20
|
-
gem.required_ruby_version = ">= 2.
|
18
|
+
gem.required_ruby_version = ">= 2.6.0"
|
19
|
+
|
21
20
|
gem.add_runtime_dependency 'rack', '>= 1.1.3'
|
21
|
+
|
22
22
|
gem.add_development_dependency 'redis'
|
23
23
|
gem.add_development_dependency 'pg'
|
24
|
+
gem.add_development_dependency 'concurrent-ruby' # for distributed-cache
|
25
|
+
gem.add_development_dependency 'minitest'
|
26
|
+
gem.add_development_dependency 'minitest-hooks'
|
27
|
+
gem.add_development_dependency 'minitest-global_expectations'
|
28
|
+
gem.add_development_dependency 'rake'
|
29
|
+
gem.add_development_dependency 'http_parser.rb'
|
30
|
+
gem.add_development_dependency 'thin'
|
31
|
+
gem.add_development_dependency 'rack-test'
|
32
|
+
gem.add_development_dependency 'puma'
|
33
|
+
gem.add_development_dependency 'm'
|
34
|
+
gem.add_development_dependency 'byebug'
|
35
|
+
gem.add_development_dependency 'oj'
|
36
|
+
gem.add_development_dependency 'yard'
|
37
|
+
gem.add_development_dependency 'rubocop-discourse'
|
38
|
+
gem.add_development_dependency 'rubocop-rspec'
|
24
39
|
end
|