Use asynchronous ActiveJob for message delivery

Calling out to a 3rd party web service like Slack or Mattermost blocks
the request for the current Redmine user. Depending on network latency,
this can result in very slow response on any action that is notified via
`redmine_messenger`.

Instead the backend call should make use of Rails builtin asynchronous
background job queuing (the same as used for Redmine mails), returning
to the user earlier.

We don't specify the actual queue backend for this job, so any Redmine
installation can select an appropiate queue backend by themselves or
simply use the default builtin backends.
This commit is contained in:
Florian Krupicka
2021-08-24 16:52:12 +02:00
parent e47c55130d
commit f4fbf45895

View File

@@ -47,21 +47,8 @@ class Messenger
end
channels.each do |channel|
uri = URI url
params[:channel] = channel
http_options = { use_ssl: uri.scheme == 'https' }
http_options[:verify_mode] = OpenSSL::SSL::VERIFY_NONE unless RedmineMessenger.setting? :messenger_verify_ssl
begin
req = Net::HTTP::Post.new uri
req.set_form_data payload: params.to_json
Net::HTTP.start uri.hostname, uri.port, http_options do |http|
response = http.request req
Rails.logger.warn response.inspect unless [Net::HTTPSuccess, Net::HTTPRedirection, Net::HTTPOK].include? response
end
rescue StandardError => e
Rails.logger.warn "cannot connect to #{url}"
Rails.logger.warn e
end
DeliverMessageJob.perform_later url, params
end
end
@@ -304,4 +291,26 @@ class Messenger
[]
end
end
class DeliverMessageJob < ActiveJob::Base
queue_as :default
def perform(url, params)
uri = URI url
params[:channel] = channel
http_options = { use_ssl: uri.scheme == 'https' }
http_options[:verify_mode] = OpenSSL::SSL::VERIFY_NONE unless RedmineMessenger.setting? :messenger_verify_ssl
begin
req = Net::HTTP::Post.new uri
req.set_form_data payload: params.to_json
Net::HTTP.start uri.hostname, uri.port, http_options do |http|
response = http.request req
Rails.logger.warn response.inspect unless [Net::HTTPSuccess, Net::HTTPRedirection, Net::HTTPOK].include? response
end
rescue StandardError => e
Rails.logger.warn "cannot connect to #{url}"
Rails.logger.warn e
end
end
end
end