DEV: Apply syntax_tree formatting to `config/*`
This commit is contained in:
parent
436b3b392b
commit
7c77cc6a58
1
.streerc
1
.streerc
|
@ -2,7 +2,6 @@
|
|||
--plugins=plugin/trailing_comma,disable_ternary
|
||||
--ignore-files=Gemfile
|
||||
--ignore-files=app/*
|
||||
--ignore-files=config/*
|
||||
--ignore-files=db/*
|
||||
--ignore-files=lib/*
|
||||
--ignore-files=spec/*
|
||||
|
|
|
@ -5,12 +5,12 @@ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.7.0")
|
|||
exit 1
|
||||
end
|
||||
|
||||
require File.expand_path('../boot', __FILE__)
|
||||
require 'active_record/railtie'
|
||||
require 'action_controller/railtie'
|
||||
require 'action_view/railtie'
|
||||
require 'action_mailer/railtie'
|
||||
require 'sprockets/railtie'
|
||||
require File.expand_path("../boot", __FILE__)
|
||||
require "active_record/railtie"
|
||||
require "action_controller/railtie"
|
||||
require "action_view/railtie"
|
||||
require "action_mailer/railtie"
|
||||
require "sprockets/railtie"
|
||||
|
||||
if !Rails.env.production?
|
||||
recommended = File.read(".ruby-version.sample").strip
|
||||
|
@ -20,66 +20,59 @@ if !Rails.env.production?
|
|||
end
|
||||
|
||||
# Plugin related stuff
|
||||
require_relative '../lib/plugin'
|
||||
require_relative '../lib/discourse_event'
|
||||
require_relative '../lib/discourse_plugin_registry'
|
||||
require_relative "../lib/plugin"
|
||||
require_relative "../lib/discourse_event"
|
||||
require_relative "../lib/discourse_plugin_registry"
|
||||
|
||||
require_relative '../lib/plugin_gem'
|
||||
require_relative "../lib/plugin_gem"
|
||||
|
||||
# Global config
|
||||
require_relative '../app/models/global_setting'
|
||||
require_relative "../app/models/global_setting"
|
||||
GlobalSetting.configure!
|
||||
if GlobalSetting.load_plugins?
|
||||
# Support for plugins to register custom setting providers. They can do this
|
||||
# by having a file, `register_provider.rb` in their root that will be run
|
||||
# at this point.
|
||||
|
||||
Dir.glob(File.join(File.dirname(__FILE__), '../plugins', '*', "register_provider.rb")) do |p|
|
||||
Dir.glob(File.join(File.dirname(__FILE__), "../plugins", "*", "register_provider.rb")) do |p|
|
||||
require p
|
||||
end
|
||||
end
|
||||
GlobalSetting.load_defaults
|
||||
if GlobalSetting.try(:cdn_url).present? && GlobalSetting.cdn_url !~ /^https?:\/\//
|
||||
if GlobalSetting.try(:cdn_url).present? && GlobalSetting.cdn_url !~ %r{^https?://}
|
||||
STDERR.puts "WARNING: Your CDN URL does not begin with a protocol like `https://` - this is probably not going to work"
|
||||
end
|
||||
|
||||
if ENV['SKIP_DB_AND_REDIS'] == '1'
|
||||
if ENV["SKIP_DB_AND_REDIS"] == "1"
|
||||
GlobalSetting.skip_db = true
|
||||
GlobalSetting.skip_redis = true
|
||||
end
|
||||
|
||||
if !GlobalSetting.skip_db?
|
||||
require 'rails_failover/active_record'
|
||||
end
|
||||
require "rails_failover/active_record" if !GlobalSetting.skip_db?
|
||||
|
||||
if !GlobalSetting.skip_redis?
|
||||
require 'rails_failover/redis'
|
||||
end
|
||||
require "rails_failover/redis" if !GlobalSetting.skip_redis?
|
||||
|
||||
require 'pry-rails' if Rails.env.development?
|
||||
require 'pry-byebug' if Rails.env.development?
|
||||
require "pry-rails" if Rails.env.development?
|
||||
require "pry-byebug" if Rails.env.development?
|
||||
|
||||
require 'discourse_fonts'
|
||||
require "discourse_fonts"
|
||||
|
||||
require_relative '../lib/ember_cli'
|
||||
require_relative "../lib/ember_cli"
|
||||
|
||||
if defined?(Bundler)
|
||||
bundler_groups = [:default]
|
||||
|
||||
if !Rails.env.production?
|
||||
bundler_groups = bundler_groups.concat(Rails.groups(
|
||||
assets: %w(development test profile)
|
||||
))
|
||||
bundler_groups = bundler_groups.concat(Rails.groups(assets: %w[development test profile]))
|
||||
end
|
||||
|
||||
Bundler.require(*bundler_groups)
|
||||
end
|
||||
|
||||
require_relative '../lib/require_dependency_backward_compatibility'
|
||||
require_relative "../lib/require_dependency_backward_compatibility"
|
||||
|
||||
module Discourse
|
||||
class Application < Rails::Application
|
||||
|
||||
def config.database_configuration
|
||||
if Rails.env.production?
|
||||
GlobalSetting.database_config
|
||||
|
@ -91,18 +84,23 @@ module Discourse
|
|||
# Application configuration should go into files in config/initializers
|
||||
# -- all .rb files in that directory are automatically loaded.
|
||||
|
||||
require 'discourse'
|
||||
require 'js_locale_helper'
|
||||
require "discourse"
|
||||
require "js_locale_helper"
|
||||
|
||||
# tiny file needed by site settings
|
||||
require 'highlight_js'
|
||||
require "highlight_js"
|
||||
|
||||
config.load_defaults 6.1
|
||||
config.active_record.cache_versioning = false # our custom cache class doesn’t support this
|
||||
config.action_controller.forgery_protection_origin_check = false
|
||||
config.active_record.belongs_to_required_by_default = false
|
||||
config.active_record.legacy_connection_handling = true
|
||||
config.active_record.yaml_column_permitted_classes = [Hash, HashWithIndifferentAccess, Time, Symbol]
|
||||
config.active_record.yaml_column_permitted_classes = [
|
||||
Hash,
|
||||
HashWithIndifferentAccess,
|
||||
Time,
|
||||
Symbol,
|
||||
]
|
||||
|
||||
# we skip it cause we configure it in the initializer
|
||||
# the railtie for message_bus would insert it in the
|
||||
|
@ -111,7 +109,8 @@ module Discourse
|
|||
config.skip_multisite_middleware = true
|
||||
config.skip_rails_failover_active_record_middleware = true
|
||||
|
||||
multisite_config_path = ENV['DISCOURSE_MULTISITE_CONFIG_PATH'] || GlobalSetting.multisite_config_path
|
||||
multisite_config_path =
|
||||
ENV["DISCOURSE_MULTISITE_CONFIG_PATH"] || GlobalSetting.multisite_config_path
|
||||
config.multisite_config_path = File.absolute_path(multisite_config_path, Rails.root)
|
||||
|
||||
# Custom directories with classes and modules you want to be autoloadable.
|
||||
|
@ -129,14 +128,14 @@ module Discourse
|
|||
|
||||
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
||||
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
||||
config.time_zone = 'UTC'
|
||||
config.time_zone = "UTC"
|
||||
|
||||
# auto-load locales in plugins
|
||||
# NOTE: we load both client & server locales since some might be used by PrettyText
|
||||
config.i18n.load_path += Dir["#{Rails.root}/plugins/*/config/locales/*.yml"]
|
||||
|
||||
# Configure the default encoding used in templates for Ruby 1.9.
|
||||
config.encoding = 'utf-8'
|
||||
config.encoding = "utf-8"
|
||||
|
||||
# see: http://stackoverflow.com/questions/11894180/how-does-one-correctly-add-custom-sql-dml-in-migrations/11894420#11894420
|
||||
config.active_record.schema_format = :sql
|
||||
|
@ -145,7 +144,7 @@ module Discourse
|
|||
config.active_record.use_schema_cache_dump = false
|
||||
|
||||
# per https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet
|
||||
config.pbkdf2_iterations = 64000
|
||||
config.pbkdf2_iterations = 64_000
|
||||
config.pbkdf2_algorithm = "sha256"
|
||||
|
||||
# rack lock is nothing but trouble, get rid of it
|
||||
|
@ -160,32 +159,39 @@ module Discourse
|
|||
# supports etags (post 1.7)
|
||||
config.middleware.delete Rack::ETag
|
||||
|
||||
if !(Rails.env.development? || ENV['SKIP_ENFORCE_HOSTNAME'] == "1")
|
||||
require 'middleware/enforce_hostname'
|
||||
if !(Rails.env.development? || ENV["SKIP_ENFORCE_HOSTNAME"] == "1")
|
||||
require "middleware/enforce_hostname"
|
||||
config.middleware.insert_after Rack::MethodOverride, Middleware::EnforceHostname
|
||||
end
|
||||
|
||||
require 'content_security_policy/middleware'
|
||||
config.middleware.swap ActionDispatch::ContentSecurityPolicy::Middleware, ContentSecurityPolicy::Middleware
|
||||
require "content_security_policy/middleware"
|
||||
config.middleware.swap ActionDispatch::ContentSecurityPolicy::Middleware,
|
||||
ContentSecurityPolicy::Middleware
|
||||
|
||||
require 'middleware/discourse_public_exceptions'
|
||||
require "middleware/discourse_public_exceptions"
|
||||
config.exceptions_app = Middleware::DiscoursePublicExceptions.new(Rails.public_path)
|
||||
|
||||
require 'discourse_js_processor'
|
||||
require 'discourse_sourcemapping_url_processor'
|
||||
require "discourse_js_processor"
|
||||
require "discourse_sourcemapping_url_processor"
|
||||
|
||||
Sprockets.register_mime_type 'application/javascript', extensions: ['.js', '.es6', '.js.es6'], charset: :unicode
|
||||
Sprockets.register_postprocessor 'application/javascript', DiscourseJsProcessor
|
||||
Sprockets.register_mime_type "application/javascript",
|
||||
extensions: %w[.js .es6 .js.es6],
|
||||
charset: :unicode
|
||||
Sprockets.register_postprocessor "application/javascript", DiscourseJsProcessor
|
||||
|
||||
Discourse::Application.initializer :prepend_ember_assets do |app|
|
||||
# Needs to be in its own initializer so it runs after the append_assets_path initializer defined by Sprockets
|
||||
app.config.assets.paths.unshift "#{app.config.root}/app/assets/javascripts/discourse/dist/assets"
|
||||
Sprockets.unregister_postprocessor 'application/javascript', Sprockets::Rails::SourcemappingUrlProcessor
|
||||
Sprockets.register_postprocessor 'application/javascript', DiscourseSourcemappingUrlProcessor
|
||||
app
|
||||
.config
|
||||
.assets
|
||||
.paths.unshift "#{app.config.root}/app/assets/javascripts/discourse/dist/assets"
|
||||
Sprockets.unregister_postprocessor "application/javascript",
|
||||
Sprockets::Rails::SourcemappingUrlProcessor
|
||||
Sprockets.register_postprocessor "application/javascript", DiscourseSourcemappingUrlProcessor
|
||||
end
|
||||
|
||||
require 'discourse_redis'
|
||||
require 'logster/redis_store'
|
||||
require "discourse_redis"
|
||||
require "logster/redis_store"
|
||||
# Use redis for our cache
|
||||
config.cache_store = DiscourseRedis.new_redis_store
|
||||
Discourse.redis = DiscourseRedis.new
|
||||
|
@ -198,7 +204,7 @@ module Discourse
|
|||
# our setup does not use rack cache and instead defers to nginx
|
||||
config.action_dispatch.rack_cache = nil
|
||||
|
||||
require 'auth'
|
||||
require "auth"
|
||||
|
||||
if GlobalSetting.relative_url_root.present?
|
||||
config.relative_url_root = GlobalSetting.relative_url_root
|
||||
|
@ -207,38 +213,28 @@ module Discourse
|
|||
if Rails.env.test? && GlobalSetting.load_plugins?
|
||||
Discourse.activate_plugins!
|
||||
elsif GlobalSetting.load_plugins?
|
||||
Plugin.initialization_guard do
|
||||
Discourse.activate_plugins!
|
||||
end
|
||||
Plugin.initialization_guard { Discourse.activate_plugins! }
|
||||
end
|
||||
|
||||
# Use discourse-fonts gem to symlink fonts and generate .scss file
|
||||
fonts_path = File.join(config.root, 'public/fonts')
|
||||
fonts_path = File.join(config.root, "public/fonts")
|
||||
Discourse::Utils.atomic_ln_s(DiscourseFonts.path_for_fonts, fonts_path)
|
||||
|
||||
require 'stylesheet/manager'
|
||||
require 'svg_sprite'
|
||||
require "stylesheet/manager"
|
||||
require "svg_sprite"
|
||||
|
||||
config.after_initialize do
|
||||
# Load plugins
|
||||
Plugin.initialization_guard do
|
||||
Discourse.plugins.each(&:notify_after_initialize)
|
||||
end
|
||||
Plugin.initialization_guard { Discourse.plugins.each(&:notify_after_initialize) }
|
||||
|
||||
# we got to clear the pool in case plugins connect
|
||||
ActiveRecord::Base.connection_handler.clear_active_connections!
|
||||
end
|
||||
|
||||
if ENV['RBTRACE'] == "1"
|
||||
require 'rbtrace'
|
||||
end
|
||||
require "rbtrace" if ENV["RBTRACE"] == "1"
|
||||
|
||||
if ENV['RAILS_QUERY_LOG_TAGS'] == "1"
|
||||
config.active_record.query_log_tags_enabled = true
|
||||
end
|
||||
config.active_record.query_log_tags_enabled = true if ENV["RAILS_QUERY_LOG_TAGS"] == "1"
|
||||
|
||||
config.generators do |g|
|
||||
g.test_framework :rspec, fixture: false
|
||||
end
|
||||
config.generators { |g| g.test_framework :rspec, fixture: false }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,48 +1,49 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
if ENV['DISCOURSE_DUMP_HEAP'] == "1"
|
||||
require 'objspace'
|
||||
if ENV["DISCOURSE_DUMP_HEAP"] == "1"
|
||||
require "objspace"
|
||||
ObjectSpace.trace_object_allocations_start
|
||||
end
|
||||
|
||||
require 'rubygems'
|
||||
require "rubygems"
|
||||
|
||||
# Set up gems listed in the Gemfile.
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
||||
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__)
|
||||
|
||||
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
||||
require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])
|
||||
|
||||
if (ENV['DISABLE_BOOTSNAP'] != '1')
|
||||
if (ENV["DISABLE_BOOTSNAP"] != "1")
|
||||
begin
|
||||
require 'bootsnap'
|
||||
require "bootsnap"
|
||||
rescue LoadError
|
||||
# not a strong requirement
|
||||
end
|
||||
|
||||
if defined? Bootsnap
|
||||
if defined?(Bootsnap)
|
||||
Bootsnap.setup(
|
||||
cache_dir: 'tmp/cache', # Path to your cache
|
||||
load_path_cache: true, # Should we optimize the LOAD_PATH with a cache?
|
||||
compile_cache_iseq: true, # Should compile Ruby code into ISeq cache?
|
||||
compile_cache_yaml: false # Skip YAML cache for now, cause we were seeing issues with it
|
||||
cache_dir: "tmp/cache", # Path to your cache
|
||||
load_path_cache: true, # Should we optimize the LOAD_PATH with a cache?
|
||||
compile_cache_iseq: true, # Should compile Ruby code into ISeq cache?
|
||||
compile_cache_yaml: false, # Skip YAML cache for now, cause we were seeing issues with it
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# Parallel spec system
|
||||
if ENV['RAILS_ENV'] == "test" && ENV['TEST_ENV_NUMBER']
|
||||
if ENV['TEST_ENV_NUMBER'] == ''
|
||||
if ENV["RAILS_ENV"] == "test" && ENV["TEST_ENV_NUMBER"]
|
||||
if ENV["TEST_ENV_NUMBER"] == ""
|
||||
n = 1
|
||||
else
|
||||
n = ENV['TEST_ENV_NUMBER'].to_i
|
||||
n = ENV["TEST_ENV_NUMBER"].to_i
|
||||
end
|
||||
|
||||
port = 10000 + n
|
||||
port = 10_000 + n
|
||||
|
||||
STDERR.puts "Setting up parallel test mode - starting Redis #{n} on port #{port}"
|
||||
|
||||
`rm -rf tmp/test_data_#{n} && mkdir -p tmp/test_data_#{n}/redis`
|
||||
pid = Process.spawn("redis-server --dir tmp/test_data_#{n}/redis --port #{port}", out: "/dev/null")
|
||||
pid =
|
||||
Process.spawn("redis-server --dir tmp/test_data_#{n}/redis --port #{port}", out: "/dev/null")
|
||||
|
||||
ENV["DISCOURSE_REDIS_PORT"] = port.to_s
|
||||
ENV["RAILS_DB"] = "discourse_test_#{n}"
|
||||
|
|
|
@ -7,7 +7,7 @@ Discourse::Application.configure do
|
|||
config.cache_classes = true
|
||||
|
||||
# Full error reports are disabled and caching is turned on
|
||||
config.consider_all_requests_local = false
|
||||
config.consider_all_requests_local = false
|
||||
config.action_controller.perform_caching = true
|
||||
|
||||
# Disable Rails's static asset server (Apache or nginx will already do this)
|
||||
|
@ -23,19 +23,20 @@ Discourse::Application.configure do
|
|||
config.assets.digest = true
|
||||
|
||||
# Specifies the header that your server uses for sending files
|
||||
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
|
||||
config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for nginx
|
||||
|
||||
# you may use other configuration here for mail eg: sendgrid
|
||||
|
||||
config.action_mailer.delivery_method = :smtp
|
||||
config.action_mailer.smtp_settings = {
|
||||
address: ENV['SMTP_ADDRESS'],
|
||||
port: ENV['SMTP_PORT'],
|
||||
domain: ENV['SMTP_DOMAIN'],
|
||||
user_name: ENV['SMTP_USERNAME'],
|
||||
password: ENV['SMTP_PASSWORD'],
|
||||
authentication: 'plain',
|
||||
enable_starttls_auto: true }
|
||||
address: ENV["SMTP_ADDRESS"],
|
||||
port: ENV["SMTP_PORT"],
|
||||
domain: ENV["SMTP_DOMAIN"],
|
||||
user_name: ENV["SMTP_USERNAME"],
|
||||
password: ENV["SMTP_PASSWORD"],
|
||||
authentication: "plain",
|
||||
enable_starttls_auto: true,
|
||||
}
|
||||
|
||||
#config.action_mailer.delivery_method = :sendmail
|
||||
#config.action_mailer.sendmail_settings = {arguments: '-i'}
|
||||
|
@ -59,5 +60,4 @@ Discourse::Application.configure do
|
|||
# Discourse strongly recommend you use a CDN.
|
||||
# For origin pull cdns all you need to do is register an account and configure
|
||||
# config.action_controller.asset_host = "http://YOUR_CDN_HERE"
|
||||
|
||||
end
|
||||
|
|
|
@ -7,6 +7,7 @@ require_relative "application"
|
|||
Rails.application.initialize!
|
||||
|
||||
# When in "dev" mode, ensure we won't be sending any emails
|
||||
if Rails.env.development? && ActionMailer::Base.smtp_settings.slice(:address, :port) != { address: "localhost", port: 1025 }
|
||||
if Rails.env.development? &&
|
||||
ActionMailer::Base.smtp_settings.slice(:address, :port) != { address: "localhost", port: 1025 }
|
||||
fail "In development mode, you should be using mailhog otherwise you might end up sending thousands of digest emails"
|
||||
end
|
||||
|
|
|
@ -16,7 +16,7 @@ Discourse::Application.configure do
|
|||
config.active_record.use_schema_cache_dump = true
|
||||
|
||||
# Show full error reports and disable caching
|
||||
config.consider_all_requests_local = true
|
||||
config.consider_all_requests_local = true
|
||||
config.action_controller.perform_caching = false
|
||||
|
||||
config.action_controller.asset_host = GlobalSetting.cdn_url
|
||||
|
@ -32,27 +32,23 @@ Discourse::Application.configure do
|
|||
|
||||
config.assets.debug = false
|
||||
|
||||
config.public_file_server.headers = {
|
||||
'Access-Control-Allow-Origin' => '*'
|
||||
}
|
||||
config.public_file_server.headers = { "Access-Control-Allow-Origin" => "*" }
|
||||
|
||||
# Raise an error on page load if there are pending migrations
|
||||
config.active_record.migration_error = :page_load
|
||||
config.watchable_dirs['lib'] = [:rb]
|
||||
config.watchable_dirs["lib"] = [:rb]
|
||||
|
||||
# we recommend you use mailhog https://github.com/mailhog/MailHog
|
||||
config.action_mailer.smtp_settings = { address: "localhost", port: 1025 }
|
||||
|
||||
config.action_mailer.raise_delivery_errors = true
|
||||
|
||||
config.log_level = ENV['DISCOURSE_DEV_LOG_LEVEL'] if ENV['DISCOURSE_DEV_LOG_LEVEL']
|
||||
config.log_level = ENV["DISCOURSE_DEV_LOG_LEVEL"] if ENV["DISCOURSE_DEV_LOG_LEVEL"]
|
||||
|
||||
if ENV['RAILS_VERBOSE_QUERY_LOGS'] == "1"
|
||||
config.active_record.verbose_query_logs = true
|
||||
end
|
||||
config.active_record.verbose_query_logs = true if ENV["RAILS_VERBOSE_QUERY_LOGS"] == "1"
|
||||
|
||||
if defined?(BetterErrors)
|
||||
BetterErrors::Middleware.allow_ip! ENV['TRUSTED_IP'] if ENV['TRUSTED_IP']
|
||||
BetterErrors::Middleware.allow_ip! ENV["TRUSTED_IP"] if ENV["TRUSTED_IP"]
|
||||
|
||||
if defined?(Unicorn) && ENV["UNICORN_WORKERS"].to_i != 1
|
||||
# BetterErrors doesn't work with multiple unicorn workers. Disable it to avoid confusion
|
||||
|
@ -60,51 +56,44 @@ Discourse::Application.configure do
|
|||
end
|
||||
end
|
||||
|
||||
if !ENV["DISABLE_MINI_PROFILER"]
|
||||
config.load_mini_profiler = true
|
||||
end
|
||||
config.load_mini_profiler = true if !ENV["DISABLE_MINI_PROFILER"]
|
||||
|
||||
if hosts = ENV['DISCOURSE_DEV_HOSTS']
|
||||
if hosts = ENV["DISCOURSE_DEV_HOSTS"]
|
||||
Discourse.deprecate("DISCOURSE_DEV_HOSTS is deprecated. Use RAILS_DEVELOPMENT_HOSTS instead.")
|
||||
config.hosts.concat(hosts.split(","))
|
||||
end
|
||||
|
||||
require 'middleware/turbo_dev'
|
||||
require "middleware/turbo_dev"
|
||||
config.middleware.insert 0, Middleware::TurboDev
|
||||
require 'middleware/missing_avatars'
|
||||
require "middleware/missing_avatars"
|
||||
config.middleware.insert 1, Middleware::MissingAvatars
|
||||
|
||||
config.enable_anon_caching = false
|
||||
if RUBY_ENGINE == "ruby"
|
||||
require 'rbtrace'
|
||||
end
|
||||
require "rbtrace" if RUBY_ENGINE == "ruby"
|
||||
|
||||
if emails = GlobalSetting.developer_emails
|
||||
config.developer_emails = emails.split(",").map(&:downcase).map(&:strip)
|
||||
end
|
||||
|
||||
if ENV["DISCOURSE_SKIP_CSS_WATCHER"] != "1" && (defined?(Rails::Server) || defined?(Puma) || defined?(Unicorn))
|
||||
require 'stylesheet/watcher'
|
||||
if ENV["DISCOURSE_SKIP_CSS_WATCHER"] != "1" &&
|
||||
(defined?(Rails::Server) || defined?(Puma) || defined?(Unicorn))
|
||||
require "stylesheet/watcher"
|
||||
STDERR.puts "Starting CSS change watcher"
|
||||
@watcher = Stylesheet::Watcher.watch
|
||||
end
|
||||
|
||||
config.after_initialize do
|
||||
if ENV["RAILS_COLORIZE_LOGGING"] == "1"
|
||||
config.colorize_logging = true
|
||||
end
|
||||
config.colorize_logging = true if ENV["RAILS_COLORIZE_LOGGING"] == "1"
|
||||
|
||||
if ENV["RAILS_VERBOSE_QUERY_LOGS"] == "1"
|
||||
ActiveRecord::LogSubscriber.backtrace_cleaner.add_silencer do |line|
|
||||
line =~ /lib\/freedom_patches/
|
||||
line =~ %r{lib/freedom_patches}
|
||||
end
|
||||
end
|
||||
|
||||
if ENV["RAILS_DISABLE_ACTIVERECORD_LOGS"] == "1"
|
||||
ActiveRecord::Base.logger = nil
|
||||
end
|
||||
ActiveRecord::Base.logger = nil if ENV["RAILS_DISABLE_ACTIVERECORD_LOGS"] == "1"
|
||||
|
||||
if ENV['BULLET']
|
||||
if ENV["BULLET"]
|
||||
Bullet.enable = true
|
||||
Bullet.rails_logger = true
|
||||
end
|
||||
|
|
|
@ -8,7 +8,7 @@ Discourse::Application.configure do
|
|||
config.eager_load = true
|
||||
|
||||
# Full error reports are disabled and caching is turned on
|
||||
config.consider_all_requests_local = false
|
||||
config.consider_all_requests_local = false
|
||||
config.action_controller.perform_caching = true
|
||||
|
||||
# Disable Rails's static asset server (Apache or nginx will already do this)
|
||||
|
@ -34,19 +34,19 @@ Discourse::Application.configure do
|
|||
authentication: GlobalSetting.smtp_authentication,
|
||||
enable_starttls_auto: GlobalSetting.smtp_enable_start_tls,
|
||||
open_timeout: GlobalSetting.smtp_open_timeout,
|
||||
read_timeout: GlobalSetting.smtp_read_timeout
|
||||
read_timeout: GlobalSetting.smtp_read_timeout,
|
||||
}
|
||||
|
||||
settings[:openssl_verify_mode] = GlobalSetting.smtp_openssl_verify_mode if GlobalSetting.smtp_openssl_verify_mode
|
||||
settings[
|
||||
:openssl_verify_mode
|
||||
] = GlobalSetting.smtp_openssl_verify_mode if GlobalSetting.smtp_openssl_verify_mode
|
||||
|
||||
if GlobalSetting.smtp_force_tls
|
||||
settings[:tls] = true
|
||||
end
|
||||
settings[:tls] = true if GlobalSetting.smtp_force_tls
|
||||
|
||||
config.action_mailer.smtp_settings = settings.compact
|
||||
else
|
||||
config.action_mailer.delivery_method = :sendmail
|
||||
config.action_mailer.sendmail_settings = { arguments: '-i' }
|
||||
config.action_mailer.sendmail_settings = { arguments: "-i" }
|
||||
end
|
||||
|
||||
# Send deprecation notices to registered listeners
|
||||
|
|
|
@ -11,7 +11,7 @@ Discourse::Application.configure do
|
|||
config.log_level = :info
|
||||
|
||||
# Full error reports are disabled and caching is turned on
|
||||
config.consider_all_requests_local = false
|
||||
config.consider_all_requests_local = false
|
||||
config.action_controller.perform_caching = true
|
||||
|
||||
# in profile mode we serve static assets
|
||||
|
@ -27,7 +27,7 @@ Discourse::Application.configure do
|
|||
config.assets.digest = true
|
||||
|
||||
# Specifies the header that your server uses for sending files
|
||||
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
|
||||
config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for nginx
|
||||
|
||||
# we recommend you use mailhog https://github.com/mailhog/MailHog
|
||||
config.action_mailer.smtp_settings = { address: "localhost", port: 1025 }
|
||||
|
@ -39,9 +39,7 @@ Discourse::Application.configure do
|
|||
config.load_mini_profiler = false
|
||||
|
||||
# we don't need full logster support, but need to keep it working
|
||||
config.after_initialize do
|
||||
Logster.logger = Rails.logger
|
||||
end
|
||||
config.after_initialize { Logster.logger = Rails.logger }
|
||||
|
||||
# for profiling with perftools
|
||||
# config.middleware.use ::Rack::PerftoolsProfiler, default_printer: 'gif'
|
||||
|
|
|
@ -46,21 +46,22 @@ Discourse::Application.configure do
|
|||
|
||||
config.eager_load = false
|
||||
|
||||
if ENV['RAILS_ENABLE_TEST_LOG']
|
||||
if ENV["RAILS_ENABLE_TEST_LOG"]
|
||||
config.logger = Logger.new(STDOUT)
|
||||
config.log_level = ENV['RAILS_TEST_LOG_LEVEL'].present? ? ENV['RAILS_TEST_LOG_LEVEL'].to_sym : :info
|
||||
config.log_level =
|
||||
ENV["RAILS_TEST_LOG_LEVEL"].present? ? ENV["RAILS_TEST_LOG_LEVEL"].to_sym : :info
|
||||
else
|
||||
config.logger = Logger.new(nil)
|
||||
config.log_level = :fatal
|
||||
end
|
||||
|
||||
if defined? RspecErrorTracker
|
||||
if defined?(RspecErrorTracker)
|
||||
config.middleware.insert_after ActionDispatch::Flash, RspecErrorTracker
|
||||
end
|
||||
|
||||
config.after_initialize do
|
||||
SiteSetting.defaults.tap do |s|
|
||||
s.set_regardless_of_locale(:s3_upload_bucket, 'bucket')
|
||||
s.set_regardless_of_locale(:s3_upload_bucket, "bucket")
|
||||
s.set_regardless_of_locale(:min_post_length, 5)
|
||||
s.set_regardless_of_locale(:min_first_post_length, 5)
|
||||
s.set_regardless_of_locale(:min_personal_message_post_length, 10)
|
||||
|
@ -73,7 +74,7 @@ Discourse::Application.configure do
|
|||
s.set_regardless_of_locale(:allow_uncategorized_topics, true)
|
||||
|
||||
# disable plugins
|
||||
if ENV['LOAD_PLUGINS'] == '1'
|
||||
if ENV["LOAD_PLUGINS"] == "1"
|
||||
s.set_regardless_of_locale(:discourse_narrative_bot_enabled, false)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,25 +8,35 @@ if Rails.env.development? && !Rails.configuration.cache_classes && Discourse.run
|
|||
*Dir["#{Rails.root}/app/*"].reject { |path| path.end_with? "/assets" },
|
||||
"#{Rails.root}/config",
|
||||
"#{Rails.root}/lib",
|
||||
"#{Rails.root}/plugins"
|
||||
"#{Rails.root}/plugins",
|
||||
]
|
||||
|
||||
Listen.to(*paths, only: /\.rb$/) do |modified, added, removed|
|
||||
supervisor_pid = UNICORN_DEV_SUPERVISOR_PID
|
||||
auto_restart = supervisor_pid && ENV["AUTO_RESTART"] != "0"
|
||||
Listen
|
||||
.to(*paths, only: /\.rb$/) do |modified, added, removed|
|
||||
supervisor_pid = UNICORN_DEV_SUPERVISOR_PID
|
||||
auto_restart = supervisor_pid && ENV["AUTO_RESTART"] != "0"
|
||||
|
||||
files = modified + added + removed
|
||||
files = modified + added + removed
|
||||
|
||||
not_autoloaded = files.filter_map do |file|
|
||||
autoloaded = Rails.autoloaders.main.autoloads.key? file
|
||||
Pathname.new(file).relative_path_from(Rails.root) if !autoloaded
|
||||
not_autoloaded =
|
||||
files.filter_map do |file|
|
||||
autoloaded = Rails.autoloaders.main.autoloads.key? file
|
||||
Pathname.new(file).relative_path_from(Rails.root) if !autoloaded
|
||||
end
|
||||
|
||||
if not_autoloaded.length > 0
|
||||
message =
|
||||
(
|
||||
if auto_restart
|
||||
"Restarting server..."
|
||||
else
|
||||
"Server restart required. Automate this by setting AUTO_RESTART=1."
|
||||
end
|
||||
)
|
||||
STDERR.puts "[DEV]: Edited files which are not autoloaded. #{message}"
|
||||
STDERR.puts not_autoloaded.map { |path| "- #{path}".indent(7) }.join("\n")
|
||||
Process.kill("USR2", supervisor_pid) if auto_restart
|
||||
end
|
||||
end
|
||||
|
||||
if not_autoloaded.length > 0
|
||||
message = auto_restart ? "Restarting server..." : "Server restart required. Automate this by setting AUTO_RESTART=1."
|
||||
STDERR.puts "[DEV]: Edited files which are not autoloaded. #{message}"
|
||||
STDERR.puts not_autoloaded.map { |path| "- #{path}".indent(7) }.join("\n")
|
||||
Process.kill("USR2", supervisor_pid) if auto_restart
|
||||
end
|
||||
end.start
|
||||
.start
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'mini_sql_multisite_connection'
|
||||
require "mini_sql_multisite_connection"
|
||||
::DB = MiniSqlMultisiteConnection.instance
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
unless Discourse.skip_post_deployment_migrations?
|
||||
ActiveRecord::Tasks::DatabaseTasks.migrations_paths << Rails.root.join(
|
||||
Discourse::DB_POST_MIGRATE_PATH
|
||||
).to_s
|
||||
ActiveRecord::Tasks::DatabaseTasks.migrations_paths << Rails
|
||||
.root
|
||||
.join(Discourse::DB_POST_MIGRATE_PATH)
|
||||
.to_s
|
||||
end
|
||||
|
|
|
@ -15,31 +15,32 @@
|
|||
# Warning: this could create some very large files!
|
||||
|
||||
if ENV["TRACE_PG_CONNECTIONS"]
|
||||
PG::Connection.prepend(Module.new do
|
||||
TRACE_DIR = "tmp/pgtrace"
|
||||
PG::Connection.prepend(
|
||||
Module.new do
|
||||
TRACE_DIR = "tmp/pgtrace"
|
||||
|
||||
def initialize(*args)
|
||||
super(*args).tap do
|
||||
next if ENV["TRACE_PG_CONNECTIONS"] == "SIDEKIQ" && !Sidekiq.server?
|
||||
FileUtils.mkdir_p(TRACE_DIR)
|
||||
@trace_filename = "#{TRACE_DIR}/#{Process.pid}_#{self.object_id}.txt"
|
||||
trace File.new(@trace_filename, "w")
|
||||
def initialize(*args)
|
||||
super(*args).tap do
|
||||
next if ENV["TRACE_PG_CONNECTIONS"] == "SIDEKIQ" && !Sidekiq.server?
|
||||
FileUtils.mkdir_p(TRACE_DIR)
|
||||
@trace_filename = "#{TRACE_DIR}/#{Process.pid}_#{self.object_id}.txt"
|
||||
trace File.new(@trace_filename, "w")
|
||||
end
|
||||
@access_log_mutex = Mutex.new
|
||||
@accessor_thread = nil
|
||||
end
|
||||
@access_log_mutex = Mutex.new
|
||||
@accessor_thread = nil
|
||||
end
|
||||
|
||||
def close
|
||||
super.tap do
|
||||
next if ENV["TRACE_PG_CONNECTIONS"] == "SIDEKIQ" && !Sidekiq.server?
|
||||
File.delete(@trace_filename)
|
||||
def close
|
||||
super.tap do
|
||||
next if ENV["TRACE_PG_CONNECTIONS"] == "SIDEKIQ" && !Sidekiq.server?
|
||||
File.delete(@trace_filename)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def log_access(&blk)
|
||||
@access_log_mutex.synchronize do
|
||||
if !@accessor_thread.nil?
|
||||
Rails.logger.error <<~TEXT
|
||||
def log_access(&blk)
|
||||
@access_log_mutex.synchronize do
|
||||
if !@accessor_thread.nil?
|
||||
Rails.logger.error <<~TEXT
|
||||
PG Clash: A connection is being accessed from two locations
|
||||
|
||||
#{@accessor_thread} was using the connection. Backtrace:
|
||||
|
@ -51,37 +52,38 @@ if ENV["TRACE_PG_CONNECTIONS"]
|
|||
#{Thread.current&.backtrace&.join("\n")}
|
||||
TEXT
|
||||
|
||||
if ENV["ON_PG_CLASH"] == "byebug"
|
||||
require "byebug"
|
||||
byebug # rubocop:disable Lint/Debugger
|
||||
if ENV["ON_PG_CLASH"] == "byebug"
|
||||
require "byebug"
|
||||
byebug # rubocop:disable Lint/Debugger
|
||||
end
|
||||
end
|
||||
@accessor_thread = Thread.current
|
||||
end
|
||||
@accessor_thread = Thread.current
|
||||
yield
|
||||
ensure
|
||||
@access_log_mutex.synchronize { @accessor_thread = nil }
|
||||
end
|
||||
yield
|
||||
ensure
|
||||
@access_log_mutex.synchronize do
|
||||
@accessor_thread = nil
|
||||
end
|
||||
end
|
||||
|
||||
end)
|
||||
end,
|
||||
)
|
||||
|
||||
class PG::Connection
|
||||
LOG_ACCESS_METHODS = [:exec, :sync_exec, :async_exec,
|
||||
:sync_exec_params, :async_exec_params,
|
||||
:sync_prepare, :async_prepare,
|
||||
:sync_exec_prepared, :async_exec_prepared,
|
||||
]
|
||||
LOG_ACCESS_METHODS = %i[
|
||||
exec
|
||||
sync_exec
|
||||
async_exec
|
||||
sync_exec_params
|
||||
async_exec_params
|
||||
sync_prepare
|
||||
async_prepare
|
||||
sync_exec_prepared
|
||||
async_exec_prepared
|
||||
]
|
||||
|
||||
LOG_ACCESS_METHODS.each do |method|
|
||||
new_method = "#{method}_without_logging".to_sym
|
||||
alias_method new_method, method
|
||||
|
||||
define_method(method) do |*args, &blk|
|
||||
log_access { send(new_method, *args, &blk) }
|
||||
end
|
||||
define_method(method) { |*args, &blk| log_access { send(new_method, *args, &blk) } }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -11,7 +11,7 @@ module DiscourseInflector
|
|||
|
||||
def self.camelize(basename, abspath)
|
||||
return basename.camelize if abspath.ends_with?("onceoff.rb")
|
||||
return 'Jobs' if abspath.ends_with?("jobs/base.rb")
|
||||
return "Jobs" if abspath.ends_with?("jobs/base.rb")
|
||||
@overrides[basename] || basename.camelize
|
||||
end
|
||||
|
||||
|
@ -26,27 +26,29 @@ Rails.autoloaders.each do |autoloader|
|
|||
# We have filenames that do not follow Zeitwerk's camelization convention. Maintain an inflections for these files
|
||||
# for now until we decide to fix them one day.
|
||||
autoloader.inflector.inflect(
|
||||
'canonical_url' => 'CanonicalURL',
|
||||
'clean_up_unmatched_ips' => 'CleanUpUnmatchedIPs',
|
||||
'homepage_constraint' => 'HomePageConstraint',
|
||||
'ip_addr' => 'IPAddr',
|
||||
'onpdiff' => 'ONPDiff',
|
||||
'pop3_polling_enabled_setting_validator' => 'POP3PollingEnabledSettingValidator',
|
||||
'version' => 'Discourse',
|
||||
'onceoff' => 'Jobs',
|
||||
'regular' => 'Jobs',
|
||||
'scheduled' => 'Jobs',
|
||||
'google_oauth2_authenticator' => 'GoogleOAuth2Authenticator',
|
||||
'omniauth_strategies' => 'OmniAuthStrategies',
|
||||
'csrf_token_verifier' => 'CSRFTokenVerifier',
|
||||
'html' => 'HTML',
|
||||
'json' => 'JSON',
|
||||
'ssrf_detector' => 'SSRFDetector',
|
||||
'http' => 'HTTP',
|
||||
"canonical_url" => "CanonicalURL",
|
||||
"clean_up_unmatched_ips" => "CleanUpUnmatchedIPs",
|
||||
"homepage_constraint" => "HomePageConstraint",
|
||||
"ip_addr" => "IPAddr",
|
||||
"onpdiff" => "ONPDiff",
|
||||
"pop3_polling_enabled_setting_validator" => "POP3PollingEnabledSettingValidator",
|
||||
"version" => "Discourse",
|
||||
"onceoff" => "Jobs",
|
||||
"regular" => "Jobs",
|
||||
"scheduled" => "Jobs",
|
||||
"google_oauth2_authenticator" => "GoogleOAuth2Authenticator",
|
||||
"omniauth_strategies" => "OmniAuthStrategies",
|
||||
"csrf_token_verifier" => "CSRFTokenVerifier",
|
||||
"html" => "HTML",
|
||||
"json" => "JSON",
|
||||
"ssrf_detector" => "SSRFDetector",
|
||||
"http" => "HTTP",
|
||||
)
|
||||
end
|
||||
Rails.autoloaders.main.ignore("lib/tasks",
|
||||
"lib/generators",
|
||||
"lib/freedom_patches",
|
||||
"lib/i18n/backend",
|
||||
"lib/unicorn_logstash_patch.rb")
|
||||
Rails.autoloaders.main.ignore(
|
||||
"lib/tasks",
|
||||
"lib/generators",
|
||||
"lib/freedom_patches",
|
||||
"lib/i18n/backend",
|
||||
"lib/unicorn_logstash_patch.rb",
|
||||
)
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
if Rails.env.development? && ENV['DISCOURSE_FLUSH_REDIS']
|
||||
if Rails.env.development? && ENV["DISCOURSE_FLUSH_REDIS"]
|
||||
puts "Flushing redis (development mode)"
|
||||
Discourse.redis.flushdb
|
||||
end
|
||||
|
||||
begin
|
||||
if Gem::Version.new(Discourse.redis.info['redis_version']) < Gem::Version.new("6.2.0")
|
||||
if Gem::Version.new(Discourse.redis.info["redis_version"]) < Gem::Version.new("6.2.0")
|
||||
STDERR.puts "Discourse requires Redis 6.2.0 or up"
|
||||
exit 1
|
||||
end
|
||||
|
|
|
@ -14,16 +14,12 @@ if defined?(RailsFailover::Redis)
|
|||
Discourse.request_refresh!
|
||||
MessageBus.keepalive_interval = message_bus_keepalive_interval
|
||||
|
||||
ObjectSpace.each_object(DistributedCache) do |cache|
|
||||
cache.clear
|
||||
end
|
||||
ObjectSpace.each_object(DistributedCache) { |cache| cache.clear }
|
||||
|
||||
SiteSetting.refresh!
|
||||
end
|
||||
|
||||
if Rails.logger.respond_to? :chained
|
||||
RailsFailover::Redis.logger = Rails.logger.chained.first
|
||||
end
|
||||
RailsFailover::Redis.logger = Rails.logger.chained.first if Rails.logger.respond_to? :chained
|
||||
end
|
||||
|
||||
if defined?(RailsFailover::ActiveRecord)
|
||||
|
@ -73,10 +69,7 @@ if defined?(RailsFailover::ActiveRecord)
|
|||
end
|
||||
|
||||
RailsFailover::ActiveRecord.register_force_reading_role_callback do
|
||||
Discourse.redis.exists?(
|
||||
Discourse::PG_READONLY_MODE_KEY,
|
||||
Discourse::PG_FORCE_READONLY_MODE_KEY
|
||||
)
|
||||
Discourse.redis.exists?(Discourse::PG_READONLY_MODE_KEY, Discourse::PG_FORCE_READONLY_MODE_KEY)
|
||||
rescue => e
|
||||
if !e.is_a?(Redis::CannotConnectError)
|
||||
Rails.logger.warn "#{e.class} #{e.message}: #{e.backtrace.join("\n")}"
|
||||
|
|
|
@ -30,7 +30,8 @@ def setup_message_bus_env(env)
|
|||
extra_headers = {
|
||||
"Access-Control-Allow-Origin" => Discourse.base_url_no_prefix,
|
||||
"Access-Control-Allow-Methods" => "GET, POST",
|
||||
"Access-Control-Allow-Headers" => "X-SILENCE-LOGGER, X-Shared-Session-Key, Dont-Chunk, Discourse-Present",
|
||||
"Access-Control-Allow-Headers" =>
|
||||
"X-SILENCE-LOGGER, X-Shared-Session-Key, Dont-Chunk, Discourse-Present",
|
||||
"Access-Control-Max-Age" => "7200",
|
||||
}
|
||||
|
||||
|
@ -40,7 +41,7 @@ def setup_message_bus_env(env)
|
|||
rescue Discourse::InvalidAccess => e
|
||||
# this is bad we need to remove the cookie
|
||||
if e.opts[:delete_cookie].present?
|
||||
extra_headers['Set-Cookie'] = '_t=del; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT'
|
||||
extra_headers["Set-Cookie"] = "_t=del; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT"
|
||||
end
|
||||
rescue => e
|
||||
Discourse.warn_exception(e, message: "Unexpected error in Message Bus", env: env)
|
||||
|
@ -51,23 +52,22 @@ def setup_message_bus_env(env)
|
|||
raise Discourse::InvalidAccess if !user_id && SiteSetting.login_required
|
||||
|
||||
is_admin = !!(user && user.admin?)
|
||||
group_ids = if is_admin
|
||||
# special rule, admin is allowed access to all groups
|
||||
Group.pluck(:id)
|
||||
elsif user
|
||||
user.groups.pluck('groups.id')
|
||||
end
|
||||
group_ids =
|
||||
if is_admin
|
||||
# special rule, admin is allowed access to all groups
|
||||
Group.pluck(:id)
|
||||
elsif user
|
||||
user.groups.pluck("groups.id")
|
||||
end
|
||||
|
||||
if env[Auth::DefaultCurrentUserProvider::BAD_TOKEN]
|
||||
extra_headers['Discourse-Logged-Out'] = '1'
|
||||
end
|
||||
extra_headers["Discourse-Logged-Out"] = "1" if env[Auth::DefaultCurrentUserProvider::BAD_TOKEN]
|
||||
|
||||
hash = {
|
||||
extra_headers: extra_headers,
|
||||
user_id: user_id,
|
||||
group_ids: group_ids,
|
||||
is_admin: is_admin,
|
||||
site_id: RailsMultisite::ConnectionManagement.current_db
|
||||
site_id: RailsMultisite::ConnectionManagement.current_db,
|
||||
}
|
||||
env["__mb"] = hash
|
||||
end
|
||||
|
@ -99,7 +99,7 @@ MessageBus.on_middleware_error do |env, e|
|
|||
if Discourse::InvalidAccess === e
|
||||
[403, {}, ["Invalid Access"]]
|
||||
elsif RateLimiter::LimitExceeded === e
|
||||
[429, { 'Retry-After' => e.available_in.to_s }, [e.description]]
|
||||
[429, { "Retry-After" => e.available_in.to_s }, [e.description]]
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -119,8 +119,9 @@ end
|
|||
|
||||
MessageBus.backend_instance.max_backlog_size = GlobalSetting.message_bus_max_backlog_size
|
||||
MessageBus.backend_instance.clear_every = GlobalSetting.message_bus_clear_every
|
||||
MessageBus.long_polling_enabled = GlobalSetting.enable_long_polling.nil? ? true : GlobalSetting.enable_long_polling
|
||||
MessageBus.long_polling_interval = GlobalSetting.long_polling_interval || 25000
|
||||
MessageBus.long_polling_enabled =
|
||||
GlobalSetting.enable_long_polling.nil? ? true : GlobalSetting.enable_long_polling
|
||||
MessageBus.long_polling_interval = GlobalSetting.long_polling_interval || 25_000
|
||||
|
||||
if Rails.env == "test" || $0 =~ /rake$/
|
||||
# disable keepalive in testing
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
Discourse.git_version
|
||||
|
||||
if GlobalSetting.skip_redis?
|
||||
require 'site_settings/local_process_provider'
|
||||
require "site_settings/local_process_provider"
|
||||
Rails.cache = Discourse.cache
|
||||
Rails.application.config.to_prepare do
|
||||
SiteSetting.provider = SiteSettings::LocalProcessProvider.new
|
||||
|
@ -19,7 +19,8 @@ Rails.application.config.to_prepare do
|
|||
begin
|
||||
SiteSetting.refresh!
|
||||
|
||||
unless String === SiteSetting.push_api_secret_key && SiteSetting.push_api_secret_key.length == 32
|
||||
unless String === SiteSetting.push_api_secret_key &&
|
||||
SiteSetting.push_api_secret_key.length == 32
|
||||
SiteSetting.push_api_secret_key = SecureRandom.hex
|
||||
end
|
||||
rescue ActiveRecord::StatementInvalid
|
||||
|
|
|
@ -5,17 +5,15 @@ return if GlobalSetting.skip_db?
|
|||
Rails.application.config.to_prepare do
|
||||
# Some sanity checking so we don't count on an unindexed column on boot
|
||||
begin
|
||||
if ActiveRecord::Base.connection.table_exists?(:users) &&
|
||||
User.limit(20).count < 20 &&
|
||||
User.where(admin: true).human_users.count == 0
|
||||
|
||||
if ActiveRecord::Base.connection.table_exists?(:users) && User.limit(20).count < 20 &&
|
||||
User.where(admin: true).human_users.count == 0
|
||||
notice =
|
||||
if GlobalSetting.developer_emails.blank?
|
||||
"Congratulations, you installed Discourse! Unfortunately, no administrator emails were defined during setup, so finalizing the configuration <a href='https://meta.discourse.org/t/create-admin-account-from-console/17274'>may be difficult</a>."
|
||||
else
|
||||
emails = GlobalSetting.developer_emails.split(",")
|
||||
if emails.length > 1
|
||||
emails = emails[0..-2].join(', ') << " or #{emails[-1]} "
|
||||
emails = emails[0..-2].join(", ") << " or #{emails[-1]} "
|
||||
else
|
||||
emails = emails[0]
|
||||
end
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# If Mini Profiler is included via gem
|
||||
if Rails.configuration.respond_to?(:load_mini_profiler) && Rails.configuration.load_mini_profiler && RUBY_ENGINE == "ruby"
|
||||
require 'rack-mini-profiler'
|
||||
require 'stackprof'
|
||||
if Rails.configuration.respond_to?(:load_mini_profiler) && Rails.configuration.load_mini_profiler &&
|
||||
RUBY_ENGINE == "ruby"
|
||||
require "rack-mini-profiler"
|
||||
require "stackprof"
|
||||
|
||||
begin
|
||||
require 'memory_profiler'
|
||||
require "memory_profiler"
|
||||
rescue => e
|
||||
STDERR.put "#{e} failed to require mini profiler"
|
||||
end
|
||||
|
@ -20,55 +21,56 @@ if defined?(Rack::MiniProfiler) && defined?(Rack::MiniProfiler::Config)
|
|||
# raw_connection means results are not namespaced
|
||||
#
|
||||
# namespacing gets complex, cause mini profiler is in the rack chain way before multisite
|
||||
Rack::MiniProfiler.config.storage_instance = Rack::MiniProfiler::RedisStore.new(
|
||||
connection: DiscourseRedis.new(nil, namespace: false)
|
||||
)
|
||||
Rack::MiniProfiler.config.storage_instance =
|
||||
Rack::MiniProfiler::RedisStore.new(connection: DiscourseRedis.new(nil, namespace: false))
|
||||
|
||||
Rack::MiniProfiler.config.snapshot_every_n_requests = GlobalSetting.mini_profiler_snapshots_period
|
||||
Rack::MiniProfiler.config.snapshots_transport_destination_url = GlobalSetting.mini_profiler_snapshots_transport_url
|
||||
Rack::MiniProfiler.config.snapshots_transport_auth_key = GlobalSetting.mini_profiler_snapshots_transport_auth_key
|
||||
Rack::MiniProfiler.config.snapshots_transport_destination_url =
|
||||
GlobalSetting.mini_profiler_snapshots_transport_url
|
||||
Rack::MiniProfiler.config.snapshots_transport_auth_key =
|
||||
GlobalSetting.mini_profiler_snapshots_transport_auth_key
|
||||
Rack::MiniProfiler.config.skip_paths = [
|
||||
/^\/message-bus/,
|
||||
/^\/extra-locales/,
|
||||
/topics\/timings/,
|
||||
%r{^/message-bus},
|
||||
%r{^/extra-locales},
|
||||
%r{topics/timings},
|
||||
/assets/,
|
||||
/\/user_avatar\//,
|
||||
/\/letter_avatar\//,
|
||||
/\/letter_avatar_proxy\//,
|
||||
/\/highlight-js\//,
|
||||
/\/svg-sprite\//,
|
||||
%r{/user_avatar/},
|
||||
%r{/letter_avatar/},
|
||||
%r{/letter_avatar_proxy/},
|
||||
%r{/highlight-js/},
|
||||
%r{/svg-sprite/},
|
||||
/qunit/,
|
||||
/srv\/status/,
|
||||
%r{srv/status},
|
||||
/commits-widget/,
|
||||
/^\/cdn_asset/,
|
||||
/^\/logs/,
|
||||
/^\/site_customizations/,
|
||||
/^\/uploads/,
|
||||
/^\/secure-media-uploads/,
|
||||
/^\/secure-uploads/,
|
||||
/^\/javascripts\//,
|
||||
/^\/images\//,
|
||||
/^\/stylesheets\//,
|
||||
/^\/favicon\/proxied/,
|
||||
/^\/theme-javascripts/
|
||||
%r{^/cdn_asset},
|
||||
%r{^/logs},
|
||||
%r{^/site_customizations},
|
||||
%r{^/uploads},
|
||||
%r{^/secure-media-uploads},
|
||||
%r{^/secure-uploads},
|
||||
%r{^/javascripts/},
|
||||
%r{^/images/},
|
||||
%r{^/stylesheets/},
|
||||
%r{^/favicon/proxied},
|
||||
%r{^/theme-javascripts},
|
||||
]
|
||||
|
||||
# we DO NOT WANT mini-profiler loading on anything but real desktops and laptops
|
||||
# so let's rule out all handheld, tablet, and mobile devices
|
||||
Rack::MiniProfiler.config.pre_authorize_cb = lambda do |env|
|
||||
env['HTTP_USER_AGENT'] !~ /iPad|iPhone|Android/
|
||||
end
|
||||
Rack::MiniProfiler.config.pre_authorize_cb =
|
||||
lambda { |env| env["HTTP_USER_AGENT"] !~ /iPad|iPhone|Android/ }
|
||||
|
||||
# without a user provider our results will use the ip address for namespacing
|
||||
# with a load balancer in front this becomes really bad as some results can
|
||||
# be stored associated with ip1 as the user and retrieved using ip2 causing 404s
|
||||
Rack::MiniProfiler.config.user_provider = lambda do |env|
|
||||
request = Rack::Request.new(env)
|
||||
id = request.cookies["_t"] || request.ip || "unknown"
|
||||
id = id.to_s
|
||||
# some security, lets not have these tokens floating about
|
||||
Digest::MD5.hexdigest(id)
|
||||
end
|
||||
Rack::MiniProfiler.config.user_provider =
|
||||
lambda do |env|
|
||||
request = Rack::Request.new(env)
|
||||
id = request.cookies["_t"] || request.ip || "unknown"
|
||||
id = id.to_s
|
||||
# some security, lets not have these tokens floating about
|
||||
Digest::MD5.hexdigest(id)
|
||||
end
|
||||
|
||||
# Cookie path should be set to the base path so Discourse's session cookie path
|
||||
# does not get clobbered.
|
||||
|
@ -77,15 +79,15 @@ if defined?(Rack::MiniProfiler) && defined?(Rack::MiniProfiler::Config)
|
|||
Rack::MiniProfiler.config.position = "right"
|
||||
|
||||
Rack::MiniProfiler.config.backtrace_ignores ||= []
|
||||
Rack::MiniProfiler.config.backtrace_ignores << /lib\/rack\/message_bus.rb/
|
||||
Rack::MiniProfiler.config.backtrace_ignores << /config\/initializers\/silence_logger/
|
||||
Rack::MiniProfiler.config.backtrace_ignores << /config\/initializers\/quiet_logger/
|
||||
Rack::MiniProfiler.config.backtrace_ignores << %r{lib/rack/message_bus.rb}
|
||||
Rack::MiniProfiler.config.backtrace_ignores << %r{config/initializers/silence_logger}
|
||||
Rack::MiniProfiler.config.backtrace_ignores << %r{config/initializers/quiet_logger}
|
||||
|
||||
Rack::MiniProfiler.config.backtrace_includes = [/^\/?(app|config|lib|test|plugins)/]
|
||||
Rack::MiniProfiler.config.backtrace_includes = [%r{^/?(app|config|lib|test|plugins)}]
|
||||
|
||||
Rack::MiniProfiler.config.max_traces_to_show = 100 if Rails.env.development?
|
||||
|
||||
Rack::MiniProfiler.counter_method(Redis::Client, :call) { 'redis' }
|
||||
Rack::MiniProfiler.counter_method(Redis::Client, :call) { "redis" }
|
||||
# Rack::MiniProfiler.counter_method(ActiveRecord::QueryMethods, 'build_arel')
|
||||
# Rack::MiniProfiler.counter_method(Array, 'uniq')
|
||||
# require "#{Rails.root}/vendor/backports/notification"
|
||||
|
@ -115,10 +117,11 @@ if defined?(Rack::MiniProfiler) && defined?(Rack::MiniProfiler::Config)
|
|||
end
|
||||
|
||||
if ENV["PRINT_EXCEPTIONS"]
|
||||
trace = TracePoint.new(:raise) do |tp|
|
||||
puts tp.raised_exception
|
||||
puts tp.raised_exception.backtrace.join("\n")
|
||||
puts
|
||||
end
|
||||
trace =
|
||||
TracePoint.new(:raise) do |tp|
|
||||
puts tp.raised_exception
|
||||
puts tp.raised_exception.backtrace.join("\n")
|
||||
puts
|
||||
end
|
||||
trace.enable
|
||||
end
|
||||
|
|
|
@ -6,18 +6,17 @@ class Discourse::Cors
|
|||
def initialize(app, options = nil)
|
||||
@app = app
|
||||
if GlobalSetting.enable_cors && GlobalSetting.cors_origin.present?
|
||||
@global_origins = GlobalSetting.cors_origin.split(',').map { |x| x.strip.chomp('/') }
|
||||
@global_origins = GlobalSetting.cors_origin.split(",").map { |x| x.strip.chomp("/") }
|
||||
end
|
||||
end
|
||||
|
||||
def call(env)
|
||||
|
||||
cors_origins = @global_origins || []
|
||||
cors_origins += SiteSetting.cors_origins.split('|') if SiteSetting.cors_origins.present?
|
||||
cors_origins += SiteSetting.cors_origins.split("|") if SiteSetting.cors_origins.present?
|
||||
cors_origins = cors_origins.presence
|
||||
|
||||
if env['REQUEST_METHOD'] == ('OPTIONS') && env['HTTP_ACCESS_CONTROL_REQUEST_METHOD']
|
||||
return [200, Discourse::Cors.apply_headers(cors_origins, env, {}), []]
|
||||
if env["REQUEST_METHOD"] == ("OPTIONS") && env["HTTP_ACCESS_CONTROL_REQUEST_METHOD"]
|
||||
return 200, Discourse::Cors.apply_headers(cors_origins, env, {}), []
|
||||
end
|
||||
|
||||
env[Discourse::Cors::ORIGINS_ENV] = cors_origins if cors_origins
|
||||
|
@ -31,21 +30,24 @@ class Discourse::Cors
|
|||
end
|
||||
|
||||
def self.apply_headers(cors_origins, env, headers)
|
||||
request_method = env['REQUEST_METHOD']
|
||||
request_method = env["REQUEST_METHOD"]
|
||||
|
||||
if env['REQUEST_PATH'] =~ /\/(javascripts|assets)\// && Discourse.is_cdn_request?(env, request_method)
|
||||
if env["REQUEST_PATH"] =~ %r{/(javascripts|assets)/} &&
|
||||
Discourse.is_cdn_request?(env, request_method)
|
||||
Discourse.apply_cdn_headers(headers)
|
||||
elsif cors_origins
|
||||
origin = nil
|
||||
if origin = env['HTTP_ORIGIN']
|
||||
if origin = env["HTTP_ORIGIN"]
|
||||
origin = nil unless cors_origins.include?(origin)
|
||||
end
|
||||
|
||||
headers['Access-Control-Allow-Origin'] = origin || cors_origins[0]
|
||||
headers['Access-Control-Allow-Headers'] = 'Content-Type, Cache-Control, X-Requested-With, X-CSRF-Token, Discourse-Present, User-Api-Key, User-Api-Client-Id, Authorization'
|
||||
headers['Access-Control-Allow-Credentials'] = 'true'
|
||||
headers['Access-Control-Allow-Methods'] = 'POST, PUT, GET, OPTIONS, DELETE'
|
||||
headers['Access-Control-Max-Age'] = '7200'
|
||||
headers["Access-Control-Allow-Origin"] = origin || cors_origins[0]
|
||||
headers[
|
||||
"Access-Control-Allow-Headers"
|
||||
] = "Content-Type, Cache-Control, X-Requested-With, X-CSRF-Token, Discourse-Present, User-Api-Key, User-Api-Client-Id, Authorization"
|
||||
headers["Access-Control-Allow-Credentials"] = "true"
|
||||
headers["Access-Control-Allow-Methods"] = "POST, PUT, GET, OPTIONS, DELETE"
|
||||
headers["Access-Control-Max-Age"] = "7200"
|
||||
end
|
||||
|
||||
headers
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
%i(
|
||||
topic_recovered
|
||||
).each do |event|
|
||||
DiscourseEvent.on(event) do |topic, _|
|
||||
WebHook.enqueue_topic_hooks(event, topic)
|
||||
end
|
||||
%i[topic_recovered].each do |event|
|
||||
DiscourseEvent.on(event) { |topic, _| WebHook.enqueue_topic_hooks(event, topic) }
|
||||
end
|
||||
|
||||
DiscourseEvent.on(:topic_status_updated) do |topic, status|
|
||||
|
@ -16,18 +12,12 @@ DiscourseEvent.on(:topic_created) do |topic, _, _|
|
|||
WebHook.enqueue_topic_hooks(:topic_created, topic)
|
||||
end
|
||||
|
||||
%i(
|
||||
post_created
|
||||
post_recovered
|
||||
).each do |event|
|
||||
DiscourseEvent.on(event) do |post, _, _|
|
||||
WebHook.enqueue_post_hooks(event, post)
|
||||
end
|
||||
%i[post_created post_recovered].each do |event|
|
||||
DiscourseEvent.on(event) { |post, _, _| WebHook.enqueue_post_hooks(event, post) }
|
||||
end
|
||||
|
||||
DiscourseEvent.on(:post_edited) do |post, topic_changed|
|
||||
unless post.topic&.trashed?
|
||||
|
||||
# if we are editing the OP and the topic is changed, do not send
|
||||
# the post_edited event -- this event is sent separately because
|
||||
# when we update the OP in the UI we send two API calls in this order:
|
||||
|
@ -42,49 +32,30 @@ DiscourseEvent.on(:post_edited) do |post, topic_changed|
|
|||
end
|
||||
end
|
||||
|
||||
%i(
|
||||
%i[
|
||||
user_logged_out
|
||||
user_created
|
||||
user_logged_in
|
||||
user_approved
|
||||
user_updated
|
||||
user_confirmed_email
|
||||
).each do |event|
|
||||
DiscourseEvent.on(event) do |user|
|
||||
WebHook.enqueue_object_hooks(:user, user, event)
|
||||
end
|
||||
].each do |event|
|
||||
DiscourseEvent.on(event) { |user| WebHook.enqueue_object_hooks(:user, user, event) }
|
||||
end
|
||||
|
||||
%i(
|
||||
group_created
|
||||
group_updated
|
||||
).each do |event|
|
||||
DiscourseEvent.on(event) do |group|
|
||||
WebHook.enqueue_object_hooks(:group, group, event)
|
||||
end
|
||||
%i[group_created group_updated].each do |event|
|
||||
DiscourseEvent.on(event) { |group| WebHook.enqueue_object_hooks(:group, group, event) }
|
||||
end
|
||||
|
||||
%i(
|
||||
category_created
|
||||
category_updated
|
||||
).each do |event|
|
||||
DiscourseEvent.on(event) do |category|
|
||||
WebHook.enqueue_object_hooks(:category, category, event)
|
||||
end
|
||||
%i[category_created category_updated].each do |event|
|
||||
DiscourseEvent.on(event) { |category| WebHook.enqueue_object_hooks(:category, category, event) }
|
||||
end
|
||||
|
||||
%i(
|
||||
tag_created
|
||||
tag_updated
|
||||
).each do |event|
|
||||
DiscourseEvent.on(event) do |tag|
|
||||
WebHook.enqueue_object_hooks(:tag, tag, event, TagSerializer)
|
||||
end
|
||||
%i[tag_created tag_updated].each do |event|
|
||||
DiscourseEvent.on(event) { |tag| WebHook.enqueue_object_hooks(:tag, tag, event, TagSerializer) }
|
||||
end
|
||||
|
||||
%i(
|
||||
user_badge_granted
|
||||
).each do |event|
|
||||
%i[user_badge_granted].each do |event|
|
||||
# user_badge_revoked
|
||||
DiscourseEvent.on(event) do |badge, user_id|
|
||||
ub = UserBadge.find_by(badge: badge, user_id: user_id)
|
||||
|
@ -92,30 +63,43 @@ end
|
|||
end
|
||||
end
|
||||
|
||||
%i(
|
||||
reviewable_created
|
||||
reviewable_score_updated
|
||||
).each do |event|
|
||||
%i[reviewable_created reviewable_score_updated].each do |event|
|
||||
DiscourseEvent.on(event) do |reviewable|
|
||||
WebHook.enqueue_object_hooks(:reviewable, reviewable, event, reviewable.serializer)
|
||||
end
|
||||
end
|
||||
|
||||
DiscourseEvent.on(:reviewable_transitioned_to) do |status, reviewable|
|
||||
WebHook.enqueue_object_hooks(:reviewable, reviewable, :reviewable_transitioned_to, reviewable.serializer)
|
||||
WebHook.enqueue_object_hooks(
|
||||
:reviewable,
|
||||
reviewable,
|
||||
:reviewable_transitioned_to,
|
||||
reviewable.serializer,
|
||||
)
|
||||
end
|
||||
|
||||
DiscourseEvent.on(:notification_created) do |notification|
|
||||
WebHook.enqueue_object_hooks(:notification, notification, :notification_created, NotificationSerializer)
|
||||
WebHook.enqueue_object_hooks(
|
||||
:notification,
|
||||
notification,
|
||||
:notification_created,
|
||||
NotificationSerializer,
|
||||
)
|
||||
end
|
||||
|
||||
DiscourseEvent.on(:user_added_to_group) do |user, group, options|
|
||||
group_user = GroupUser.find_by(user: user, group: group)
|
||||
WebHook.enqueue_object_hooks(:group_user, group_user, :user_added_to_group, WebHookGroupUserSerializer)
|
||||
WebHook.enqueue_object_hooks(
|
||||
:group_user,
|
||||
group_user,
|
||||
:user_added_to_group,
|
||||
WebHookGroupUserSerializer,
|
||||
)
|
||||
end
|
||||
|
||||
DiscourseEvent.on(:user_promoted) do |payload|
|
||||
user_id, new_trust_level, old_trust_level = payload.values_at(:user_id, :new_trust_level, :old_trust_level)
|
||||
user_id, new_trust_level, old_trust_level =
|
||||
payload.values_at(:user_id, :new_trust_level, :old_trust_level)
|
||||
|
||||
next if new_trust_level < old_trust_level
|
||||
|
||||
|
@ -130,8 +114,13 @@ DiscourseEvent.on(:like_created) do |post_action|
|
|||
category_id = topic&.category_id
|
||||
tag_ids = topic&.tag_ids
|
||||
|
||||
WebHook.enqueue_object_hooks(:like,
|
||||
post_action, :post_liked, WebHookLikeSerializer,
|
||||
group_ids: group_ids, category_id: category_id, tag_ids: tag_ids
|
||||
WebHook.enqueue_object_hooks(
|
||||
:like,
|
||||
post_action,
|
||||
:post_liked,
|
||||
WebHookLikeSerializer,
|
||||
group_ids: group_ids,
|
||||
category_id: category_id,
|
||||
tag_ids: tag_ids,
|
||||
)
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'excon'
|
||||
require "excon"
|
||||
Excon::DEFAULTS[:omit_default_port] = true
|
||||
|
|
|
@ -6,10 +6,11 @@ DiscourseEvent.on(:site_setting_changed) do |name, old_value, new_value|
|
|||
# Enabling `must_approve_users` on an existing site is odd, so we assume that the
|
||||
# existing users are approved.
|
||||
if name == :must_approve_users && new_value == true
|
||||
|
||||
User.where(approved: false)
|
||||
User
|
||||
.where(approved: false)
|
||||
.joins("LEFT JOIN reviewables r ON r.target_id = users.id")
|
||||
.where(r: { id: nil }).update_all(approved: true)
|
||||
.where(r: { id: nil })
|
||||
.update_all(approved: true)
|
||||
end
|
||||
|
||||
if name == :emoji_set
|
||||
|
@ -19,31 +20,28 @@ DiscourseEvent.on(:site_setting_changed) do |name, old_value, new_value|
|
|||
after = "/images/emoji/#{new_value}/"
|
||||
|
||||
Scheduler::Defer.later("Fix Emoji Links") do
|
||||
DB.exec("UPDATE posts SET cooked = REPLACE(cooked, :before, :after) WHERE cooked LIKE :like",
|
||||
DB.exec(
|
||||
"UPDATE posts SET cooked = REPLACE(cooked, :before, :after) WHERE cooked LIKE :like",
|
||||
before: before,
|
||||
after: after,
|
||||
like: "%#{before}%"
|
||||
like: "%#{before}%",
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
Stylesheet::Manager.clear_color_scheme_cache! if [:base_font, :heading_font].include?(name)
|
||||
Stylesheet::Manager.clear_color_scheme_cache! if %i[base_font heading_font].include?(name)
|
||||
|
||||
Report.clear_cache(:storage_stats) if [:backup_location, :s3_backup_bucket].include?(name)
|
||||
Report.clear_cache(:storage_stats) if %i[backup_location s3_backup_bucket].include?(name)
|
||||
|
||||
if name == :slug_generation_method
|
||||
Scheduler::Defer.later("Null topic slug") do
|
||||
Topic.update_all(slug: nil)
|
||||
end
|
||||
Scheduler::Defer.later("Null topic slug") { Topic.update_all(slug: nil) }
|
||||
end
|
||||
|
||||
Jobs.enqueue(:update_s3_inventory) if [:enable_s3_inventory, :s3_upload_bucket].include?(name)
|
||||
Jobs.enqueue(:update_s3_inventory) if %i[enable_s3_inventory s3_upload_bucket].include?(name)
|
||||
|
||||
SvgSprite.expire_cache if name.to_s.include?("_icon")
|
||||
|
||||
if SiteIconManager::WATCHED_SETTINGS.include?(name)
|
||||
SiteIconManager.ensure_optimized!
|
||||
end
|
||||
SiteIconManager.ensure_optimized! if SiteIconManager::WATCHED_SETTINGS.include?(name)
|
||||
|
||||
# Make sure medium and high priority thresholds were calculated.
|
||||
if name == :reviewable_low_priority_threshold && Reviewable.min_score_for_priority(:medium) > 0
|
||||
|
|
|
@ -9,7 +9,7 @@ enabled =
|
|||
Rails.env.production?
|
||||
end
|
||||
|
||||
if !ENV['DISCOURSE_DISABLE_ANON_CACHE'] && enabled
|
||||
if !ENV["DISCOURSE_DISABLE_ANON_CACHE"] && enabled
|
||||
# in an ideal world this is position 0, but mobile detection uses ... session and request and params
|
||||
Rails.configuration.middleware.insert_after ActionDispatch::Flash, Middleware::AnonymousCache
|
||||
end
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
# order: after 02-freedom_patches.rb
|
||||
|
||||
require 'i18n/backend/discourse_i18n'
|
||||
require 'i18n/backend/fallback_locale_list'
|
||||
require "i18n/backend/discourse_i18n"
|
||||
require "i18n/backend/fallback_locale_list"
|
||||
|
||||
# Requires the `translate_accelerator.rb` freedom patch to be loaded
|
||||
Rails.application.reloader.to_prepare do
|
||||
|
@ -11,7 +11,7 @@ Rails.application.reloader.to_prepare do
|
|||
I18n.fallbacks = I18n::Backend::FallbackLocaleList.new
|
||||
I18n.config.missing_interpolation_argument_handler = proc { throw(:exception) }
|
||||
I18n.reload!
|
||||
I18n.init_accelerator!(overrides_enabled: ENV['DISABLE_TRANSLATION_OVERRIDES'] != '1')
|
||||
I18n.init_accelerator!(overrides_enabled: ENV["DISABLE_TRANSLATION_OVERRIDES"] != "1")
|
||||
|
||||
unless Rails.env.test?
|
||||
MessageBus.subscribe("/i18n-flush") do
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
|
||||
if GlobalSetting.skip_redis?
|
||||
Rails.application.reloader.to_prepare do
|
||||
if Rails.logger.respond_to? :chained
|
||||
Rails.logger = Rails.logger.chained.first
|
||||
end
|
||||
Rails.logger = Rails.logger.chained.first if Rails.logger.respond_to? :chained
|
||||
end
|
||||
return
|
||||
end
|
||||
|
@ -39,9 +37,7 @@ if Rails.env.production?
|
|||
# https://github.com/rails/rails/blob/f2caed1e/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb#L39-L42
|
||||
/^ActionController::RoutingError \(No route matches/,
|
||||
/^ActionDispatch::Http::MimeNegotiation::InvalidType/,
|
||||
|
||||
/^PG::Error: ERROR:\s+duplicate key/,
|
||||
|
||||
/^ActionController::UnknownFormat/,
|
||||
/^ActionController::UnknownHttpMethod/,
|
||||
/^AbstractController::ActionNotFound/,
|
||||
|
@ -51,29 +47,21 @@ if Rails.env.production?
|
|||
# Column:
|
||||
#
|
||||
/(?m).*?Line: (?:\D|0).*?Column: (?:\D|0)/,
|
||||
|
||||
# suppress empty JS errors (covers MSIE 9, etc)
|
||||
/^(Syntax|Script) error.*Line: (0|1)\b/m,
|
||||
|
||||
# CSRF errors are not providing enough data
|
||||
# suppress unconditionally for now
|
||||
/^Can't verify CSRF token authenticity.$/,
|
||||
|
||||
# Yandex bot triggers this JS error a lot
|
||||
/^Uncaught ReferenceError: I18n is not defined/,
|
||||
|
||||
# related to browser plugins somehow, we don't care
|
||||
/Error calling method on NPObject/,
|
||||
|
||||
# 404s can be dealt with elsewhere
|
||||
/^ActiveRecord::RecordNotFound/,
|
||||
|
||||
# bad asset requested, no need to log
|
||||
/^ActionController::BadRequest/,
|
||||
|
||||
# we can't do anything about invalid parameters
|
||||
/Rack::QueryParser::InvalidParameterError/,
|
||||
|
||||
# we handle this cleanly in the message bus middleware
|
||||
# no point logging to logster
|
||||
/RateLimiter::LimitExceeded.*/m,
|
||||
|
@ -98,33 +86,37 @@ store.redis_raw_connection = redis.without_namespace
|
|||
severities = [Logger::WARN, Logger::ERROR, Logger::FATAL, Logger::UNKNOWN]
|
||||
|
||||
RailsMultisite::ConnectionManagement.each_connection do
|
||||
error_rate_per_minute = SiteSetting.alert_admins_if_errors_per_minute rescue 0
|
||||
error_rate_per_minute =
|
||||
begin
|
||||
SiteSetting.alert_admins_if_errors_per_minute
|
||||
rescue StandardError
|
||||
0
|
||||
end
|
||||
|
||||
if (error_rate_per_minute || 0) > 0
|
||||
store.register_rate_limit_per_minute(severities, error_rate_per_minute) do |rate|
|
||||
MessageBus.publish("/logs_error_rate_exceeded",
|
||||
{
|
||||
rate: rate,
|
||||
duration: 'minute',
|
||||
publish_at: Time.current.to_i
|
||||
},
|
||||
group_ids: [Group::AUTO_GROUPS[:admins]]
|
||||
)
|
||||
MessageBus.publish(
|
||||
"/logs_error_rate_exceeded",
|
||||
{ rate: rate, duration: "minute", publish_at: Time.current.to_i },
|
||||
group_ids: [Group::AUTO_GROUPS[:admins]],
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
error_rate_per_hour = SiteSetting.alert_admins_if_errors_per_hour rescue 0
|
||||
error_rate_per_hour =
|
||||
begin
|
||||
SiteSetting.alert_admins_if_errors_per_hour
|
||||
rescue StandardError
|
||||
0
|
||||
end
|
||||
|
||||
if (error_rate_per_hour || 0) > 0
|
||||
store.register_rate_limit_per_hour(severities, error_rate_per_hour) do |rate|
|
||||
MessageBus.publish("/logs_error_rate_exceeded",
|
||||
{
|
||||
rate: rate,
|
||||
duration: 'hour',
|
||||
publish_at: Time.current.to_i,
|
||||
},
|
||||
group_ids: [Group::AUTO_GROUPS[:admins]]
|
||||
)
|
||||
MessageBus.publish(
|
||||
"/logs_error_rate_exceeded",
|
||||
{ rate: rate, duration: "hour", publish_at: Time.current.to_i },
|
||||
group_ids: [Group::AUTO_GROUPS[:admins]],
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -137,13 +129,13 @@ if Rails.configuration.multisite
|
|||
end
|
||||
|
||||
Logster.config.project_directories = [
|
||||
{ path: Rails.root.to_s, url: "https://github.com/discourse/discourse", main_app: true }
|
||||
{ path: Rails.root.to_s, url: "https://github.com/discourse/discourse", main_app: true },
|
||||
]
|
||||
Discourse.plugins.each do |plugin|
|
||||
next if !plugin.metadata.url
|
||||
|
||||
Logster.config.project_directories << {
|
||||
path: "#{Rails.root.to_s}/plugins/#{plugin.directory_name}",
|
||||
url: plugin.metadata.url
|
||||
url: plugin.metadata.url,
|
||||
}
|
||||
end
|
||||
|
|
|
@ -6,13 +6,13 @@ Rails.application.config.to_prepare do
|
|||
twitter_client: TwitterApi,
|
||||
redirect_limit: 3,
|
||||
user_agent: "Discourse Forum Onebox v#{Discourse::VERSION::STRING}",
|
||||
allowed_ports: [80, 443, SiteSetting.port.to_i]
|
||||
allowed_ports: [80, 443, SiteSetting.port.to_i],
|
||||
}
|
||||
else
|
||||
Onebox.options = {
|
||||
twitter_client: TwitterApi,
|
||||
redirect_limit: 3,
|
||||
user_agent: "Discourse Forum Onebox v#{Discourse::VERSION::STRING}"
|
||||
user_agent: "Discourse Forum Onebox v#{Discourse::VERSION::STRING}",
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,13 +3,11 @@
|
|||
return if GlobalSetting.skip_db?
|
||||
|
||||
Rails.application.config.to_prepare do
|
||||
require 'web-push'
|
||||
require "web-push"
|
||||
|
||||
def generate_vapid_key?
|
||||
SiteSetting.vapid_public_key.blank? ||
|
||||
SiteSetting.vapid_private_key.blank? ||
|
||||
SiteSetting.vapid_public_key_bytes.blank? ||
|
||||
SiteSetting.vapid_base_url != Discourse.base_url
|
||||
SiteSetting.vapid_public_key.blank? || SiteSetting.vapid_private_key.blank? ||
|
||||
SiteSetting.vapid_public_key_bytes.blank? || SiteSetting.vapid_base_url != Discourse.base_url
|
||||
end
|
||||
|
||||
SiteSetting.vapid_base_url = Discourse.base_url if SiteSetting.vapid_base_url.blank?
|
||||
|
@ -19,15 +17,12 @@ Rails.application.config.to_prepare do
|
|||
SiteSetting.vapid_public_key = vapid_key.public_key
|
||||
SiteSetting.vapid_private_key = vapid_key.private_key
|
||||
|
||||
SiteSetting.vapid_public_key_bytes = Base64.urlsafe_decode64(SiteSetting.vapid_public_key).bytes.join("|")
|
||||
SiteSetting.vapid_public_key_bytes =
|
||||
Base64.urlsafe_decode64(SiteSetting.vapid_public_key).bytes.join("|")
|
||||
SiteSetting.vapid_base_url = Discourse.base_url
|
||||
|
||||
if ActiveRecord::Base.connection.table_exists?(:push_subscriptions)
|
||||
PushSubscription.delete_all
|
||||
end
|
||||
PushSubscription.delete_all if ActiveRecord::Base.connection.table_exists?(:push_subscriptions)
|
||||
end
|
||||
|
||||
DiscourseEvent.on(:user_logged_out) do |user|
|
||||
PushNotificationPusher.clear_subscriptions(user)
|
||||
end
|
||||
DiscourseEvent.on(:user_logged_out) { |user| PushNotificationPusher.clear_subscriptions(user) }
|
||||
end
|
||||
|
|
|
@ -1,30 +1,23 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Rails.application.config.assets.configure do |env|
|
||||
env.logger = Logger.new('/dev/null')
|
||||
end
|
||||
Rails.application.config.assets.configure { |env| env.logger = Logger.new("/dev/null") }
|
||||
|
||||
module DiscourseRackQuietAssetsLogger
|
||||
def call(env)
|
||||
override = false
|
||||
if (env['PATH_INFO'].index("/assets/") == 0) ||
|
||||
(env['PATH_INFO'].index("/stylesheets") == 0) ||
|
||||
(env['PATH_INFO'].index("/svg-sprite") == 0) ||
|
||||
(env['PATH_INFO'].index("/manifest") == 0) ||
|
||||
(env['PATH_INFO'].index("/service-worker") == 0) ||
|
||||
(env['PATH_INFO'].index("mini-profiler-resources") == 0) ||
|
||||
(env['PATH_INFO'].index("/srv/status") == 0)
|
||||
if (env["PATH_INFO"].index("/assets/") == 0) || (env["PATH_INFO"].index("/stylesheets") == 0) ||
|
||||
(env["PATH_INFO"].index("/svg-sprite") == 0) ||
|
||||
(env["PATH_INFO"].index("/manifest") == 0) ||
|
||||
(env["PATH_INFO"].index("/service-worker") == 0) ||
|
||||
(env["PATH_INFO"].index("mini-profiler-resources") == 0) ||
|
||||
(env["PATH_INFO"].index("/srv/status") == 0)
|
||||
if ::Logster::Logger === Rails.logger
|
||||
override = true
|
||||
Rails.logger.override_level = Logger::ERROR
|
||||
end
|
||||
end
|
||||
|
||||
super(env).tap do
|
||||
if override
|
||||
Rails.logger.override_level = nil
|
||||
end
|
||||
end
|
||||
super(env).tap { Rails.logger.override_level = nil if override }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -4,8 +4,15 @@
|
|||
|
||||
Rails.application.config.session_store(
|
||||
:discourse_cookie_store,
|
||||
key: '_forum_session',
|
||||
path: (Rails.application.config.relative_url_root.nil?) ? '/' : Rails.application.config.relative_url_root
|
||||
key: "_forum_session",
|
||||
path:
|
||||
(
|
||||
if (Rails.application.config.relative_url_root.nil?)
|
||||
"/"
|
||||
else
|
||||
Rails.application.config.relative_url_root
|
||||
end
|
||||
),
|
||||
)
|
||||
|
||||
Rails.application.config.to_prepare do
|
||||
|
|
|
@ -1,22 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "sidekiq/pausable"
|
||||
require 'sidekiq_logster_reporter'
|
||||
require "sidekiq_logster_reporter"
|
||||
|
||||
Sidekiq.configure_client do |config|
|
||||
config.redis = Discourse.sidekiq_redis_config
|
||||
end
|
||||
Sidekiq.configure_client { |config| config.redis = Discourse.sidekiq_redis_config }
|
||||
|
||||
Sidekiq.configure_server do |config|
|
||||
config.redis = Discourse.sidekiq_redis_config
|
||||
|
||||
config.server_middleware do |chain|
|
||||
chain.add Sidekiq::Pausable
|
||||
end
|
||||
config.server_middleware { |chain| chain.add Sidekiq::Pausable }
|
||||
end
|
||||
|
||||
if Sidekiq.server?
|
||||
|
||||
module Sidekiq
|
||||
class CLI
|
||||
private
|
||||
|
@ -34,13 +29,17 @@ if Sidekiq.server?
|
|||
# warm up AR
|
||||
RailsMultisite::ConnectionManagement.safe_each_connection do
|
||||
(ActiveRecord::Base.connection.tables - %w[schema_migrations versions]).each do |table|
|
||||
table.classify.constantize.first rescue nil
|
||||
begin
|
||||
table.classify.constantize.first
|
||||
rescue StandardError
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
scheduler_hostname = ENV["UNICORN_SCHEDULER_HOSTNAME"]
|
||||
|
||||
if !scheduler_hostname || scheduler_hostname.split(',').include?(Discourse.os_hostname)
|
||||
if !scheduler_hostname || scheduler_hostname.split(",").include?(Discourse.os_hostname)
|
||||
begin
|
||||
MiniScheduler.start(workers: GlobalSetting.mini_scheduler_workers)
|
||||
rescue MiniScheduler::DistributedMutex::Timeout
|
||||
|
@ -57,9 +56,11 @@ else
|
|||
# Instead, this patch adds a dedicated logger instance and patches
|
||||
# the #add method to forward messages to Rails.logger.
|
||||
Sidekiq.logger = Logger.new(nil)
|
||||
Sidekiq.logger.define_singleton_method(:add) do |severity, message = nil, progname = nil, &blk|
|
||||
Rails.logger.add(severity, message, progname, &blk)
|
||||
end
|
||||
Sidekiq
|
||||
.logger
|
||||
.define_singleton_method(:add) do |severity, message = nil, progname = nil, &blk|
|
||||
Rails.logger.add(severity, message, progname, &blk)
|
||||
end
|
||||
end
|
||||
|
||||
Sidekiq.error_handlers.clear
|
||||
|
@ -69,28 +70,20 @@ Sidekiq.strict_args!
|
|||
|
||||
Rails.application.config.to_prepare do
|
||||
# Ensure that scheduled jobs are loaded before mini_scheduler is configured.
|
||||
if Rails.env.development?
|
||||
Dir.glob("#{Rails.root}/app/jobs/scheduled/*.rb") do |f|
|
||||
require(f)
|
||||
end
|
||||
end
|
||||
Dir.glob("#{Rails.root}/app/jobs/scheduled/*.rb") { |f| require(f) } if Rails.env.development?
|
||||
|
||||
MiniScheduler.configure do |config|
|
||||
config.redis = Discourse.redis
|
||||
|
||||
config.job_exception_handler do |ex, context|
|
||||
Discourse.handle_job_exception(ex, context)
|
||||
end
|
||||
config.job_exception_handler { |ex, context| Discourse.handle_job_exception(ex, context) }
|
||||
|
||||
config.job_ran do |stat|
|
||||
DiscourseEvent.trigger(:scheduled_job_ran, stat)
|
||||
end
|
||||
config.job_ran { |stat| DiscourseEvent.trigger(:scheduled_job_ran, stat) }
|
||||
|
||||
config.skip_schedule { Sidekiq.paused? }
|
||||
|
||||
config.before_sidekiq_web_request do
|
||||
RailsMultisite::ConnectionManagement.establish_connection(
|
||||
db: RailsMultisite::ConnectionManagement::DEFAULT
|
||||
db: RailsMultisite::ConnectionManagement::DEFAULT,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class SilenceLogger < Rails::Rack::Logger
|
||||
PATH_INFO = 'PATH_INFO'
|
||||
HTTP_X_SILENCE_LOGGER = 'HTTP_X_SILENCE_LOGGER'
|
||||
PATH_INFO = "PATH_INFO"
|
||||
HTTP_X_SILENCE_LOGGER = "HTTP_X_SILENCE_LOGGER"
|
||||
|
||||
def initialize(app, opts = {})
|
||||
@app = app
|
||||
|
@ -17,11 +17,9 @@ class SilenceLogger < Rails::Rack::Logger
|
|||
path_info = env[PATH_INFO]
|
||||
override = false
|
||||
|
||||
if env[HTTP_X_SILENCE_LOGGER] ||
|
||||
@opts[:silenced].include?(path_info) ||
|
||||
path_info.start_with?('/logs') ||
|
||||
path_info.start_with?('/user_avatar') ||
|
||||
path_info.start_with?('/letter_avatar')
|
||||
if env[HTTP_X_SILENCE_LOGGER] || @opts[:silenced].include?(path_info) ||
|
||||
path_info.start_with?("/logs") || path_info.start_with?("/user_avatar") ||
|
||||
path_info.start_with?("/letter_avatar")
|
||||
if ::Logster::Logger === Rails.logger
|
||||
override = true
|
||||
Rails.logger.override_level = Logger::WARN
|
||||
|
@ -35,10 +33,10 @@ class SilenceLogger < Rails::Rack::Logger
|
|||
end
|
||||
end
|
||||
|
||||
silenced = [
|
||||
"/mini-profiler-resources/results",
|
||||
"/mini-profiler-resources/includes.js",
|
||||
"/mini-profiler-resources/includes.css",
|
||||
"/mini-profiler-resources/jquery.tmpl.js"
|
||||
silenced = %w[
|
||||
/mini-profiler-resources/results
|
||||
/mini-profiler-resources/includes.js
|
||||
/mini-profiler-resources/includes.css
|
||||
/mini-profiler-resources/jquery.tmpl.js
|
||||
]
|
||||
Rails.configuration.middleware.swap Rails::Rack::Logger, SilenceLogger, silenced: silenced
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
# Check that the app is configured correctly. Raise some helpful errors if something is wrong.
|
||||
|
||||
if defined?(Rails::Server) && Rails.env.production? # Only run these checks when starting up a production server
|
||||
|
||||
if ['localhost', 'production.localhost'].include?(Discourse.current_hostname)
|
||||
if %w[localhost production.localhost].include?(Discourse.current_hostname)
|
||||
puts <<~TEXT
|
||||
|
||||
Discourse.current_hostname = '#{Discourse.current_hostname}'
|
||||
|
@ -18,7 +17,7 @@ if defined?(Rails::Server) && Rails.env.production? # Only run these checks when
|
|||
raise "Invalid host_names in database.yml"
|
||||
end
|
||||
|
||||
if !Dir.glob(File.join(Rails.root, 'public', 'assets', 'application*.js')).present?
|
||||
if !Dir.glob(File.join(Rails.root, "public", "assets", "application*.js")).present?
|
||||
puts <<~TEXT
|
||||
|
||||
Assets have not been precompiled. Please run the following command
|
||||
|
|
|
@ -6,11 +6,7 @@
|
|||
# is enabled by default.
|
||||
|
||||
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
|
||||
ActiveSupport.on_load(:action_controller) do
|
||||
wrap_parameters format: [:json]
|
||||
end
|
||||
ActiveSupport.on_load(:action_controller) { wrap_parameters format: [:json] }
|
||||
|
||||
# Disable root element in JSON by default.
|
||||
ActiveSupport.on_load(:active_record) do
|
||||
self.include_root_in_json = false
|
||||
end
|
||||
ActiveSupport.on_load(:active_record) { self.include_root_in_json = false }
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Rails.application.config.to_prepare do
|
||||
if (Rails.env.production? && SiteSetting.logging_provider == 'lograge') || (ENV["ENABLE_LOGRAGE"] == "1")
|
||||
require 'lograge'
|
||||
if (Rails.env.production? && SiteSetting.logging_provider == "lograge") ||
|
||||
(ENV["ENABLE_LOGRAGE"] == "1")
|
||||
require "lograge"
|
||||
|
||||
if Rails.configuration.multisite
|
||||
Rails.logger.formatter = ActiveSupport::Logger::SimpleFormatter.new
|
||||
|
@ -11,20 +12,20 @@ Rails.application.config.to_prepare do
|
|||
Rails.application.configure do
|
||||
config.lograge.enabled = true
|
||||
|
||||
Lograge.ignore(lambda do |event|
|
||||
# this is our hijack magic status,
|
||||
# no point logging this cause we log again
|
||||
# direct from hijack
|
||||
event.payload[:status] == 418
|
||||
end)
|
||||
Lograge.ignore(
|
||||
lambda do |event|
|
||||
# this is our hijack magic status,
|
||||
# no point logging this cause we log again
|
||||
# direct from hijack
|
||||
event.payload[:status] == 418
|
||||
end,
|
||||
)
|
||||
|
||||
config.lograge.custom_payload do |controller|
|
||||
begin
|
||||
username =
|
||||
begin
|
||||
if controller.respond_to?(:current_user)
|
||||
controller.current_user&.username
|
||||
end
|
||||
controller.current_user&.username if controller.respond_to?(:current_user)
|
||||
rescue Discourse::InvalidAccess, Discourse::ReadOnly, ActiveRecord::ReadOnlyError
|
||||
nil
|
||||
end
|
||||
|
@ -36,78 +37,77 @@ Rails.application.config.to_prepare do
|
|||
nil
|
||||
end
|
||||
|
||||
{
|
||||
ip: ip,
|
||||
username: username
|
||||
}
|
||||
{ ip: ip, username: username }
|
||||
rescue => e
|
||||
Rails.logger.warn("Failed to append custom payload: #{e.message}\n#{e.backtrace.join("\n")}")
|
||||
Rails.logger.warn(
|
||||
"Failed to append custom payload: #{e.message}\n#{e.backtrace.join("\n")}",
|
||||
)
|
||||
{}
|
||||
end
|
||||
end
|
||||
|
||||
config.lograge.custom_options = lambda do |event|
|
||||
begin
|
||||
exceptions = %w(controller action format id)
|
||||
config.lograge.custom_options =
|
||||
lambda do |event|
|
||||
begin
|
||||
exceptions = %w[controller action format id]
|
||||
|
||||
params = event.payload[:params].except(*exceptions)
|
||||
params = event.payload[:params].except(*exceptions)
|
||||
|
||||
if (file = params[:file]) && file.respond_to?(:headers)
|
||||
params[:file] = file.headers
|
||||
if (file = params[:file]) && file.respond_to?(:headers)
|
||||
params[:file] = file.headers
|
||||
end
|
||||
|
||||
if (files = params[:files]) && files.respond_to?(:map)
|
||||
params[:files] = files.map { |f| f.respond_to?(:headers) ? f.headers : f }
|
||||
end
|
||||
|
||||
output = {
|
||||
params: params.to_query,
|
||||
database: RailsMultisite::ConnectionManagement.current_db,
|
||||
}
|
||||
|
||||
if data = (Thread.current[:_method_profiler] || event.payload[:timings])
|
||||
sql = data[:sql]
|
||||
|
||||
if sql
|
||||
output[:db] = sql[:duration] * 1000
|
||||
output[:db_calls] = sql[:calls]
|
||||
end
|
||||
|
||||
redis = data[:redis]
|
||||
|
||||
if redis
|
||||
output[:redis] = redis[:duration] * 1000
|
||||
output[:redis_calls] = redis[:calls]
|
||||
end
|
||||
|
||||
net = data[:net]
|
||||
|
||||
if net
|
||||
output[:net] = net[:duration] * 1000
|
||||
output[:net_calls] = net[:calls]
|
||||
end
|
||||
end
|
||||
|
||||
output
|
||||
rescue RateLimiter::LimitExceeded
|
||||
# no idea who this is, but they are limited
|
||||
{}
|
||||
rescue => e
|
||||
Rails.logger.warn(
|
||||
"Failed to append custom options: #{e.message}\n#{e.backtrace.join("\n")}",
|
||||
)
|
||||
{}
|
||||
end
|
||||
|
||||
if (files = params[:files]) && files.respond_to?(:map)
|
||||
params[:files] = files.map do |f|
|
||||
f.respond_to?(:headers) ? f.headers : f
|
||||
end
|
||||
end
|
||||
|
||||
output = {
|
||||
params: params.to_query,
|
||||
database: RailsMultisite::ConnectionManagement.current_db,
|
||||
}
|
||||
|
||||
if data = (Thread.current[:_method_profiler] || event.payload[:timings])
|
||||
sql = data[:sql]
|
||||
|
||||
if sql
|
||||
output[:db] = sql[:duration] * 1000
|
||||
output[:db_calls] = sql[:calls]
|
||||
end
|
||||
|
||||
redis = data[:redis]
|
||||
|
||||
if redis
|
||||
output[:redis] = redis[:duration] * 1000
|
||||
output[:redis_calls] = redis[:calls]
|
||||
end
|
||||
|
||||
net = data[:net]
|
||||
|
||||
if net
|
||||
output[:net] = net[:duration] * 1000
|
||||
output[:net_calls] = net[:calls]
|
||||
end
|
||||
end
|
||||
|
||||
output
|
||||
rescue RateLimiter::LimitExceeded
|
||||
# no idea who this is, but they are limited
|
||||
{}
|
||||
rescue => e
|
||||
Rails.logger.warn("Failed to append custom options: #{e.message}\n#{e.backtrace.join("\n")}")
|
||||
{}
|
||||
end
|
||||
end
|
||||
|
||||
if ENV["LOGSTASH_URI"]
|
||||
config.lograge.formatter = Lograge::Formatters::Logstash.new
|
||||
|
||||
require 'discourse_logstash_logger'
|
||||
require "discourse_logstash_logger"
|
||||
|
||||
config.lograge.logger = DiscourseLogstashLogger.logger(
|
||||
uri: ENV['LOGSTASH_URI'], type: :rails
|
||||
)
|
||||
config.lograge.logger =
|
||||
DiscourseLogstashLogger.logger(uri: ENV["LOGSTASH_URI"], type: :rails)
|
||||
|
||||
# Remove ActiveSupport::Logger from the chain and replace with Lograge's
|
||||
# logger
|
||||
|
|
|
@ -11,13 +11,11 @@ Rails.configuration.middleware.unshift(MessageBus::Rack::Middleware)
|
|||
|
||||
# no reason to track this in development, that is 300+ redis calls saved per
|
||||
# page view (we serve all assets out of thin in development)
|
||||
if Rails.env != 'development' || ENV['TRACK_REQUESTS']
|
||||
require 'middleware/request_tracker'
|
||||
if Rails.env != "development" || ENV["TRACK_REQUESTS"]
|
||||
require "middleware/request_tracker"
|
||||
Rails.configuration.middleware.unshift Middleware::RequestTracker
|
||||
|
||||
if GlobalSetting.enable_performance_http_headers
|
||||
MethodProfiler.ensure_discourse_instrumentation!
|
||||
end
|
||||
MethodProfiler.ensure_discourse_instrumentation! if GlobalSetting.enable_performance_http_headers
|
||||
end
|
||||
|
||||
if Rails.env.test?
|
||||
|
@ -30,23 +28,27 @@ if Rails.env.test?
|
|||
super(env)
|
||||
end
|
||||
end
|
||||
Rails.configuration.middleware.unshift TestMultisiteMiddleware, RailsMultisite::DiscoursePatches.config
|
||||
Rails.configuration.middleware.unshift TestMultisiteMiddleware,
|
||||
RailsMultisite::DiscoursePatches.config
|
||||
elsif Rails.configuration.multisite
|
||||
assets_hostnames = GlobalSetting.cdn_hostnames
|
||||
|
||||
if assets_hostnames.empty?
|
||||
assets_hostnames =
|
||||
Discourse::Application.config.database_configuration[Rails.env]["host_names"]
|
||||
assets_hostnames = Discourse::Application.config.database_configuration[Rails.env]["host_names"]
|
||||
end
|
||||
|
||||
RailsMultisite::ConnectionManagement.asset_hostnames = assets_hostnames
|
||||
|
||||
# Multisite needs to be first, because the request tracker and message bus rely on it
|
||||
Rails.configuration.middleware.unshift RailsMultisite::Middleware, RailsMultisite::DiscoursePatches.config
|
||||
Rails.configuration.middleware.unshift RailsMultisite::Middleware,
|
||||
RailsMultisite::DiscoursePatches.config
|
||||
Rails.configuration.middleware.delete ActionDispatch::Executor
|
||||
|
||||
if defined?(RailsFailover::ActiveRecord) && Rails.configuration.active_record_rails_failover
|
||||
Rails.configuration.middleware.insert_after(RailsMultisite::Middleware, RailsFailover::ActiveRecord::Middleware)
|
||||
Rails.configuration.middleware.insert_after(
|
||||
RailsMultisite::Middleware,
|
||||
RailsFailover::ActiveRecord::Middleware,
|
||||
)
|
||||
end
|
||||
|
||||
if Rails.env.development?
|
||||
|
@ -57,5 +59,8 @@ elsif Rails.configuration.multisite
|
|||
end
|
||||
end
|
||||
elsif defined?(RailsFailover::ActiveRecord) && Rails.configuration.active_record_rails_failover
|
||||
Rails.configuration.middleware.insert_before(MessageBus::Rack::Middleware, RailsFailover::ActiveRecord::Middleware)
|
||||
Rails.configuration.middleware.insert_before(
|
||||
MessageBus::Rack::Middleware,
|
||||
RailsFailover::ActiveRecord::Middleware,
|
||||
)
|
||||
end
|
||||
|
|
|
@ -2,18 +2,32 @@
|
|||
|
||||
if !GlobalSetting.skip_redis?
|
||||
if GlobalSetting.respond_to?(:redis_slave_host) && GlobalSetting.redis_slave_host.present?
|
||||
Discourse.deprecate("redis_slave_host is deprecated, use redis_replica_host instead", drop_from: "2.8")
|
||||
Discourse.deprecate(
|
||||
"redis_slave_host is deprecated, use redis_replica_host instead",
|
||||
drop_from: "2.8",
|
||||
)
|
||||
end
|
||||
|
||||
if GlobalSetting.respond_to?(:redis_slave_port) && GlobalSetting.redis_slave_port.present?
|
||||
Discourse.deprecate("redis_slave_port is deprecated, use redis_replica_port instead", drop_from: "2.8")
|
||||
Discourse.deprecate(
|
||||
"redis_slave_port is deprecated, use redis_replica_port instead",
|
||||
drop_from: "2.8",
|
||||
)
|
||||
end
|
||||
|
||||
if GlobalSetting.respond_to?(:message_bus_redis_slave_host) && GlobalSetting.message_bus_redis_slave_host.present?
|
||||
Discourse.deprecate("message_bus_redis_slave_host is deprecated, use message_bus_redis_replica_host", drop_from: "2.8")
|
||||
if GlobalSetting.respond_to?(:message_bus_redis_slave_host) &&
|
||||
GlobalSetting.message_bus_redis_slave_host.present?
|
||||
Discourse.deprecate(
|
||||
"message_bus_redis_slave_host is deprecated, use message_bus_redis_replica_host",
|
||||
drop_from: "2.8",
|
||||
)
|
||||
end
|
||||
|
||||
if GlobalSetting.respond_to?(:message_bus_redis_slave_port) && GlobalSetting.message_bus_redis_slave_port.present?
|
||||
Discourse.deprecate("message_bus_redis_slave_port is deprecated, use message_bus_redis_replica_port", drop_from: "2.8")
|
||||
if GlobalSetting.respond_to?(:message_bus_redis_slave_port) &&
|
||||
GlobalSetting.message_bus_redis_slave_port.present?
|
||||
Discourse.deprecate(
|
||||
"message_bus_redis_slave_port is deprecated, use message_bus_redis_replica_port",
|
||||
drop_from: "2.8",
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,11 +17,13 @@ Rails.application.config.assets.paths << "#{Rails.root}/public/javascripts"
|
|||
# folder are already added.
|
||||
|
||||
# explicitly precompile any images in plugins ( /assets/images ) path
|
||||
Rails.application.config.assets.precompile += [lambda do |filename, path|
|
||||
path =~ /assets\/images/ && !%w(.js .css).include?(File.extname(filename))
|
||||
end]
|
||||
Rails.application.config.assets.precompile += [
|
||||
lambda do |filename, path|
|
||||
path =~ %r{assets/images} && !%w[.js .css].include?(File.extname(filename))
|
||||
end,
|
||||
]
|
||||
|
||||
Rails.application.config.assets.precompile += %w{
|
||||
Rails.application.config.assets.precompile += %w[
|
||||
discourse.js
|
||||
vendor.js
|
||||
admin.js
|
||||
|
@ -49,15 +51,21 @@ Rails.application.config.assets.precompile += %w{
|
|||
embed-application.js
|
||||
scripts/discourse-test-listen-boot
|
||||
scripts/discourse-boot
|
||||
}
|
||||
]
|
||||
|
||||
Rails.application.config.assets.precompile += EmberCli.assets.map { |name| name.sub('.js', '.map') }
|
||||
Rails.application.config.assets.precompile += EmberCli.assets.map { |name| name.sub(".js", ".map") }
|
||||
|
||||
# Precompile all available locales
|
||||
unless GlobalSetting.try(:omit_base_locales)
|
||||
Dir.glob("#{Rails.root}/app/assets/javascripts/locales/*.js.erb").each do |file|
|
||||
Rails.application.config.assets.precompile << "locales/#{file.match(/([a-z_A-Z]+\.js)\.erb$/)[1]}"
|
||||
end
|
||||
Dir
|
||||
.glob("#{Rails.root}/app/assets/javascripts/locales/*.js.erb")
|
||||
.each do |file|
|
||||
Rails
|
||||
.application
|
||||
.config
|
||||
.assets
|
||||
.precompile << "locales/#{file.match(/([a-z_A-Z]+\.js)\.erb$/)[1]}"
|
||||
end
|
||||
end
|
||||
|
||||
# out of the box sprockets 3 grabs loose files that are hanging in assets,
|
||||
|
@ -65,18 +73,16 @@ end
|
|||
Rails.application.config.assets.precompile.delete(Sprockets::Railtie::LOOSE_APP_ASSETS)
|
||||
|
||||
# We don't want application from node_modules, only from the root
|
||||
Rails.application.config.assets.precompile.delete(/(?:\/|\\|\A)application\.(css|js)$/)
|
||||
Rails.application.config.assets.precompile += ['application.js']
|
||||
Rails.application.config.assets.precompile.delete(%r{(?:/|\\|\A)application\.(css|js)$})
|
||||
Rails.application.config.assets.precompile += ["application.js"]
|
||||
|
||||
start_path = ::Rails.root.join("app/assets").to_s
|
||||
exclude = ['.es6', '.hbs', '.hbr', '.js', '.css', '.lock', '.json', '.log', '.html', '']
|
||||
exclude = [".es6", ".hbs", ".hbr", ".js", ".css", ".lock", ".json", ".log", ".html", ""]
|
||||
Rails.application.config.assets.precompile << lambda do |logical_path, filename|
|
||||
filename.start_with?(start_path) &&
|
||||
!filename.include?("/node_modules/") &&
|
||||
!filename.include?("/dist/") &&
|
||||
!exclude.include?(File.extname(logical_path))
|
||||
filename.start_with?(start_path) && !filename.include?("/node_modules/") &&
|
||||
!filename.include?("/dist/") && !exclude.include?(File.extname(logical_path))
|
||||
end
|
||||
|
||||
Discourse.find_plugin_js_assets(include_disabled: true).each do |file|
|
||||
Rails.application.config.assets.precompile << "#{file}.js"
|
||||
end
|
||||
Discourse
|
||||
.find_plugin_js_assets(include_disabled: true)
|
||||
.each { |file| Rails.application.config.assets.precompile << "#{file}.js" }
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Configure sensitive parameters which will be filtered from the log file.
|
||||
Rails.application.config.filter_parameters += [
|
||||
:password,
|
||||
:pop3_polling_password,
|
||||
:api_key,
|
||||
:s3_secret_access_key,
|
||||
:twitter_consumer_secret,
|
||||
:facebook_app_secret,
|
||||
:github_client_secret,
|
||||
:second_factor_token,
|
||||
Rails.application.config.filter_parameters += %i[
|
||||
password
|
||||
pop3_polling_password
|
||||
api_key
|
||||
s3_secret_access_key
|
||||
twitter_consumer_secret
|
||||
facebook_app_secret
|
||||
github_client_secret
|
||||
second_factor_token
|
||||
]
|
||||
|
|
|
@ -102,5 +102,5 @@ Rails.application.config.action_dispatch.default_headers = {
|
|||
"X-Content-Type-Options" => "nosniff",
|
||||
"X-Download-Options" => "noopen",
|
||||
"X-Permitted-Cross-Domain-Policies" => "none",
|
||||
"Referrer-Policy" => "strict-origin-when-cross-origin"
|
||||
"Referrer-Policy" => "strict-origin-when-cross-origin",
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
# source: https://github.com/svenfuchs/i18n/blob/master/test/test_data/locales/plurals.rb
|
||||
|
||||
# stree-ignore
|
||||
{
|
||||
af: { i18n: { plural: { keys: [:one, :other], rule: lambda { |n| n == 1 ? :one : :other } } } },
|
||||
am: { i18n: { plural: { keys: [:one, :other], rule: lambda { |n| [0, 1].include?(n) ? :one : :other } } } },
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
if ENV['RAILS_ENV'] == 'production'
|
||||
|
||||
if ENV["RAILS_ENV"] == "production"
|
||||
# First, you need to change these below to your situation.
|
||||
APP_ROOT = ENV["APP_ROOT"] || '/home/discourse/discourse'
|
||||
APP_ROOT = ENV["APP_ROOT"] || "/home/discourse/discourse"
|
||||
num_workers = ENV["NUM_WEBS"].to_i > 0 ? ENV["NUM_WEBS"].to_i : 4
|
||||
|
||||
# Second, you can choose how many threads that you are going to run at same time.
|
||||
|
@ -16,5 +15,4 @@ if ENV['RAILS_ENV'] == 'production'
|
|||
pidfile "#{APP_ROOT}/tmp/pids/puma.pid"
|
||||
state_path "#{APP_ROOT}/tmp/pids/puma.state"
|
||||
preload_app!
|
||||
|
||||
end
|
||||
|
|
1373
config/routes.rb
1373
config/routes.rb
File diff suppressed because it is too large
Load Diff
|
@ -7,7 +7,5 @@
|
|||
# spring binstub rails
|
||||
# spring binstub rake
|
||||
# spring binstub rspec
|
||||
Spring.after_fork do
|
||||
Discourse.after_fork
|
||||
end
|
||||
Spring.after_fork { Discourse.after_fork }
|
||||
Spring::Commands::Rake.environment_matchers["spec"] = "test"
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
# See http://unicorn.bogomips.org/Unicorn/Configurator.html
|
||||
|
||||
if (ENV["LOGSTASH_UNICORN_URI"] || "").length > 0
|
||||
require_relative '../lib/discourse_logstash_logger'
|
||||
require_relative '../lib/unicorn_logstash_patch'
|
||||
logger DiscourseLogstashLogger.logger(uri: ENV['LOGSTASH_UNICORN_URI'], type: :unicorn)
|
||||
require_relative "../lib/discourse_logstash_logger"
|
||||
require_relative "../lib/unicorn_logstash_patch"
|
||||
logger DiscourseLogstashLogger.logger(uri: ENV["LOGSTASH_UNICORN_URI"], type: :unicorn)
|
||||
end
|
||||
|
||||
discourse_path = File.expand_path(File.expand_path(File.dirname(__FILE__)) + "/../")
|
||||
|
@ -16,11 +16,10 @@ worker_processes (ENV["UNICORN_WORKERS"] || 3).to_i
|
|||
working_directory discourse_path
|
||||
|
||||
# listen "#{discourse_path}/tmp/sockets/unicorn.sock"
|
||||
listen ENV["UNICORN_LISTENER"] || "#{(ENV["UNICORN_BIND_ALL"] ? "" : "127.0.0.1:")}#{(ENV["UNICORN_PORT"] || 3000).to_i}"
|
||||
listen ENV["UNICORN_LISTENER"] ||
|
||||
"#{(ENV["UNICORN_BIND_ALL"] ? "" : "127.0.0.1:")}#{(ENV["UNICORN_PORT"] || 3000).to_i}"
|
||||
|
||||
if !File.exist?("#{discourse_path}/tmp/pids")
|
||||
FileUtils.mkdir_p("#{discourse_path}/tmp/pids")
|
||||
end
|
||||
FileUtils.mkdir_p("#{discourse_path}/tmp/pids") if !File.exist?("#{discourse_path}/tmp/pids")
|
||||
|
||||
# feel free to point this anywhere accessible on the filesystem
|
||||
pid (ENV["UNICORN_PID_PATH"] || "#{discourse_path}/tmp/pids/unicorn.pid")
|
||||
|
@ -52,7 +51,6 @@ check_client_connection false
|
|||
|
||||
initialized = false
|
||||
before_fork do |server, worker|
|
||||
|
||||
unless initialized
|
||||
Discourse.preload_rails!
|
||||
|
||||
|
@ -67,7 +65,7 @@ before_fork do |server, worker|
|
|||
|
||||
initialized = true
|
||||
|
||||
supervisor = ENV['UNICORN_SUPERVISOR_PID'].to_i
|
||||
supervisor = ENV["UNICORN_SUPERVISOR_PID"].to_i
|
||||
if supervisor > 0
|
||||
Thread.new do
|
||||
while true
|
||||
|
@ -80,14 +78,12 @@ before_fork do |server, worker|
|
|||
end
|
||||
end
|
||||
|
||||
sidekiqs = ENV['UNICORN_SIDEKIQS'].to_i
|
||||
sidekiqs = ENV["UNICORN_SIDEKIQS"].to_i
|
||||
if sidekiqs > 0
|
||||
server.logger.info "starting #{sidekiqs} supervised sidekiqs"
|
||||
|
||||
require 'demon/sidekiq'
|
||||
Demon::Sidekiq.after_fork do
|
||||
DiscourseEvent.trigger(:sidekiq_fork_started)
|
||||
end
|
||||
require "demon/sidekiq"
|
||||
Demon::Sidekiq.after_fork { DiscourseEvent.trigger(:sidekiq_fork_started) }
|
||||
|
||||
Demon::Sidekiq.start(sidekiqs)
|
||||
|
||||
|
@ -98,13 +94,14 @@ before_fork do |server, worker|
|
|||
|
||||
# Trap USR1, so we can re-issue to sidekiq workers
|
||||
# but chain the default unicorn implementation as well
|
||||
old_handler = Signal.trap("USR1") do
|
||||
Demon::Sidekiq.kill("USR1")
|
||||
old_handler.call
|
||||
end
|
||||
old_handler =
|
||||
Signal.trap("USR1") do
|
||||
Demon::Sidekiq.kill("USR1")
|
||||
old_handler.call
|
||||
end
|
||||
end
|
||||
|
||||
if ENV['DISCOURSE_ENABLE_EMAIL_SYNC_DEMON'] == 'true'
|
||||
if ENV["DISCOURSE_ENABLE_EMAIL_SYNC_DEMON"] == "true"
|
||||
server.logger.info "starting up EmailSync demon"
|
||||
Demon::EmailSync.start
|
||||
Signal.trap("SIGTSTP") do
|
||||
|
@ -119,13 +116,13 @@ before_fork do |server, worker|
|
|||
end
|
||||
|
||||
class ::Unicorn::HttpServer
|
||||
alias :master_sleep_orig :master_sleep
|
||||
alias master_sleep_orig master_sleep
|
||||
|
||||
def max_sidekiq_rss
|
||||
rss = `ps -eo rss,args | grep sidekiq | grep -v grep | awk '{print $1}'`
|
||||
.split("\n")
|
||||
.map(&:to_i)
|
||||
.max
|
||||
rss =
|
||||
`ps -eo rss,args | grep sidekiq | grep -v grep | awk '{print $1}'`.split("\n")
|
||||
.map(&:to_i)
|
||||
.max
|
||||
|
||||
rss ||= 0
|
||||
|
||||
|
@ -133,18 +130,24 @@ before_fork do |server, worker|
|
|||
end
|
||||
|
||||
def max_allowed_sidekiq_rss
|
||||
[ENV['UNICORN_SIDEKIQ_MAX_RSS'].to_i, 500].max.megabytes
|
||||
[ENV["UNICORN_SIDEKIQ_MAX_RSS"].to_i, 500].max.megabytes
|
||||
end
|
||||
|
||||
def force_kill_rogue_sidekiq
|
||||
info = `ps -eo pid,rss,args | grep sidekiq | grep -v grep | awk '{print $1,$2}'`
|
||||
info.split("\n").each do |row|
|
||||
pid, mem = row.split(" ").map(&:to_i)
|
||||
if pid > 0 && (mem * 1024) > max_allowed_sidekiq_rss
|
||||
Rails.logger.warn "Detected rogue Sidekiq pid #{pid} mem #{mem * 1024}, killing"
|
||||
Process.kill("KILL", pid) rescue nil
|
||||
info
|
||||
.split("\n")
|
||||
.each do |row|
|
||||
pid, mem = row.split(" ").map(&:to_i)
|
||||
if pid > 0 && (mem * 1024) > max_allowed_sidekiq_rss
|
||||
Rails.logger.warn "Detected rogue Sidekiq pid #{pid} mem #{mem * 1024}, killing"
|
||||
begin
|
||||
Process.kill("KILL", pid)
|
||||
rescue StandardError
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def check_sidekiq_heartbeat
|
||||
|
@ -152,13 +155,15 @@ before_fork do |server, worker|
|
|||
@sidekiq_next_heartbeat_check ||= Time.now.to_i + @sidekiq_heartbeat_interval
|
||||
|
||||
if @sidekiq_next_heartbeat_check < Time.now.to_i
|
||||
|
||||
last_heartbeat = Jobs::RunHeartbeat.last_heartbeat
|
||||
restart = false
|
||||
|
||||
sidekiq_rss = max_sidekiq_rss
|
||||
if sidekiq_rss > max_allowed_sidekiq_rss
|
||||
Rails.logger.warn("Sidekiq is consuming too much memory (using: %0.2fM) for '%s', restarting" % [(sidekiq_rss.to_f / 1.megabyte), ENV["DISCOURSE_HOSTNAME"]])
|
||||
Rails.logger.warn(
|
||||
"Sidekiq is consuming too much memory (using: %0.2fM) for '%s', restarting" %
|
||||
[(sidekiq_rss.to_f / 1.megabyte), ENV["DISCOURSE_HOSTNAME"]],
|
||||
)
|
||||
restart = true
|
||||
end
|
||||
|
||||
|
@ -185,16 +190,18 @@ before_fork do |server, worker|
|
|||
email_sync_pids = Demon::EmailSync.demons.map { |uid, demon| demon.pid }
|
||||
return 0 if email_sync_pids.empty?
|
||||
|
||||
rss = `ps -eo pid,rss,args | grep '#{email_sync_pids.join('|')}' | grep -v grep | awk '{print $2}'`
|
||||
.split("\n")
|
||||
.map(&:to_i)
|
||||
.max
|
||||
rss =
|
||||
`ps -eo pid,rss,args | grep '#{email_sync_pids.join("|")}' | grep -v grep | awk '{print $2}'`.split(
|
||||
"\n",
|
||||
)
|
||||
.map(&:to_i)
|
||||
.max
|
||||
|
||||
(rss || 0) * 1024
|
||||
end
|
||||
|
||||
def max_allowed_email_sync_rss
|
||||
[ENV['UNICORN_EMAIL_SYNC_MAX_RSS'].to_i, 500].max.megabytes
|
||||
[ENV["UNICORN_EMAIL_SYNC_MAX_RSS"].to_i, 500].max.megabytes
|
||||
end
|
||||
|
||||
def check_email_sync_heartbeat
|
||||
|
@ -207,16 +214,22 @@ before_fork do |server, worker|
|
|||
restart = false
|
||||
|
||||
# Restart process if it does not respond anymore
|
||||
last_heartbeat_ago = Time.now.to_i - Discourse.redis.get(Demon::EmailSync::HEARTBEAT_KEY).to_i
|
||||
last_heartbeat_ago =
|
||||
Time.now.to_i - Discourse.redis.get(Demon::EmailSync::HEARTBEAT_KEY).to_i
|
||||
if last_heartbeat_ago > Demon::EmailSync::HEARTBEAT_INTERVAL.to_i
|
||||
STDERR.puts("EmailSync heartbeat test failed (last heartbeat was #{last_heartbeat_ago}s ago), restarting")
|
||||
STDERR.puts(
|
||||
"EmailSync heartbeat test failed (last heartbeat was #{last_heartbeat_ago}s ago), restarting",
|
||||
)
|
||||
restart = true
|
||||
end
|
||||
|
||||
# Restart process if memory usage is too high
|
||||
email_sync_rss = max_email_sync_rss
|
||||
if email_sync_rss > max_allowed_email_sync_rss
|
||||
STDERR.puts("EmailSync is consuming too much memory (using: %0.2fM) for '%s', restarting" % [(email_sync_rss.to_f / 1.megabyte), ENV["DISCOURSE_HOSTNAME"]])
|
||||
STDERR.puts(
|
||||
"EmailSync is consuming too much memory (using: %0.2fM) for '%s', restarting" %
|
||||
[(email_sync_rss.to_f / 1.megabyte), ENV["DISCOURSE_HOSTNAME"]],
|
||||
)
|
||||
restart = true
|
||||
end
|
||||
|
||||
|
@ -224,25 +237,22 @@ before_fork do |server, worker|
|
|||
end
|
||||
|
||||
def master_sleep(sec)
|
||||
sidekiqs = ENV['UNICORN_SIDEKIQS'].to_i
|
||||
sidekiqs = ENV["UNICORN_SIDEKIQS"].to_i
|
||||
if sidekiqs > 0
|
||||
Demon::Sidekiq.ensure_running
|
||||
check_sidekiq_heartbeat
|
||||
end
|
||||
|
||||
if ENV['DISCOURSE_ENABLE_EMAIL_SYNC_DEMON'] == 'true'
|
||||
if ENV["DISCOURSE_ENABLE_EMAIL_SYNC_DEMON"] == "true"
|
||||
Demon::EmailSync.ensure_running
|
||||
check_email_sync_heartbeat
|
||||
end
|
||||
|
||||
DiscoursePluginRegistry.demon_processes.each do |demon_class|
|
||||
demon_class.ensure_running
|
||||
end
|
||||
DiscoursePluginRegistry.demon_processes.each { |demon_class| demon_class.ensure_running }
|
||||
|
||||
master_sleep_orig(sec)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Discourse.redis.close
|
||||
|
|
Loading…
Reference in New Issue