mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-04 13:05:19 +02:00
Use Redis for ActiveJob and ActionCable (#2004)
* Use Redis for ActiveJob and ActionCable * Fix alwaysApply setting * Update queue names and weights * Tweak weights * Update job queues * Update docker setup guide * Remove deprecated upgrade columns from users table * Refactor Redis configuration for Sidekiq and caching in production environment * Add Sidekiq Sentry monitoring * queue naming fix * Clean up schema
This commit is contained in:
parent
a7db914005
commit
19cc63c8f4
75 changed files with 328 additions and 1684 deletions
|
@ -24,8 +24,6 @@ module Maybe
|
|||
# config.time_zone = "Central Time (US & Canada)"
|
||||
# config.eager_load_paths << Rails.root.join("extras")
|
||||
|
||||
config.active_job.queue_adapter = :good_job
|
||||
|
||||
# TODO: This is here for incremental adoption of localization. This can be removed when all translations are implemented.
|
||||
config.i18n.fallbacks = true
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
development:
|
||||
adapter: postgresql
|
||||
adapter: async
|
||||
|
||||
test:
|
||||
adapter: test
|
||||
|
||||
production:
|
||||
adapter: postgresql
|
||||
adapter: redis
|
||||
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
|
||||
channel_prefix: maybe_production
|
||||
|
|
|
@ -1 +1 @@
|
|||
HMC62biPQuF61XA8tnd/kvwdV2xr/zpfJxG+IHNgGtpuvPXi9oS+YemBGMLte+1Q7elzAAbmKg73699hVLkRcBCk/FaMQjGRF2lnJ9MpxSR/br8Uma2bSH40lIEjxAfzjr4JPSfsHxlArF30hfd+B9obPDOptLQbpENPBsmiuEHX7S0Y8SmKuzDUVrvdfeLoVuMiAZqOP5izpBAbXfvMjI3YH70iJAaPlfAxQqR89O2nSt+N27siyyfkypE3NHQKZFz+Rmo8uJDlaD3eo/uvQN4xsgRCMUar4X2iY4UOd+MIGAPqLzIUhhJ56G5MRDJ4XpJA6RDuGFc/LNyxdXt0WinUX8Yz7zKiKah1NkEhTkH+b2ylFbsN6cjlqcX0yw8Gw8B4osyHQGnj7Tuf1c8k1z3gBoaQALm8zxKCaJ9k6CopVM2GmbpCLcJqjN1L71wCe6MiWsv9LDF/pwuZNG6hWn0oykdkWeBEQyK8g4Wo1AHqgEi8XtRwbaX6yugO5WQFhjQG/LzXcG02E5Co5/r/G7ZSFpRC9ngoOx3LY6MihPRkTIOumCg3HHtAsWBeHe4L/rDIe4A=--hlLxVbnyuYXf7Rku--A6Cwdr3CAW6bRkl1rcRmRw==
|
||||
Be5nAlhacgJFHZJBgO8noswyX/VOrmkMem7wS3YQhoogzG0MCSVxCAVMbFyYFYUwqZrSPkAqUTpgH5OJJ1FB1gZfL9IYYWnEdTzMxM7IvhdDwYllYcM6smbvZEbOiqxLs9VdfC/qFS+1iFtsezBaqxfGdANJsJt3TxoRWl/ZbQ4Od1s0BNkMis1CDZt5RMEQlTz813cE5sXBlxhqEr9/2CaktwPIe5S/Oxrwo8vPFBvrNdox8BysiK9WDik8jJFSVwPSCvg43/MaIJUT0cOILdSxqrATXV143/h6ghNYtrJgoUNFT7wuu0FTU/ovTgtTqQEKG+7PDO1WLFn606bVknjPwfNMGBa9hX3LbRErDDIXNq69um9fPZ8Yq5f9jP++dPbAqbWBEg+JYsZmDgzr7LmtXVzQgAcuMkHaBbL8uxod8S1B6qhXhLNc8Dd1oeHVu0kcLFO2zaqdYRFNEY30JSjjXlG3GExXQE6aEluXvdF2gj9Hjhp7tEXZEJbIx+ZFy+6Xbrd1E2BE8AZUbalExAfudkPSYlAZ+z3fWc2RlNIuBzTYDOWH9Ai8mqsdyGNVEyizXQ==--j/6QtlLtP4mYXIFw--c+AKfDPo9stantWni+u+4Q==
|
|
@ -1,22 +1,7 @@
|
|||
default: &default
|
||||
adapter: postgresql
|
||||
encoding: unicode
|
||||
# Note on DB_POOL_SIZE:
|
||||
# -------------------------------------------------------------------------------------------------------------
|
||||
# To optimize for the simplest self-hosting setup, we run ActionCable, GoodJob, and Rails in the same process.
|
||||
#
|
||||
# This requires DB connections for each:
|
||||
#
|
||||
# Puma: Requires 3 connections (Rails default)
|
||||
# ActionCable: 5 connections (Rails defaults to 4 workers + 1 listener for Postgres adapter)
|
||||
# GoodJob: 15 connections to run in "async" mode. See `good_job.rb` for the breakdown.
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# Total: 23 connections
|
||||
#
|
||||
# We default to this value so that self-hosters don't need to configure anything. Hosted mode will require
|
||||
# a different pool size, as we run ActionCable, GoodJob, and Rails in separate processes.
|
||||
#
|
||||
pool: <%= ENV.fetch("DB_POOL_SIZE") { 23 } %>
|
||||
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 3 } %>
|
||||
host: <%= ENV.fetch("DB_HOST") { "127.0.0.1" } %>
|
||||
port: <%= ENV.fetch("DB_PORT") { "5432" } %>
|
||||
user: <%= ENV.fetch("POSTGRES_USER") { nil } %>
|
||||
|
|
|
@ -69,11 +69,12 @@ Rails.application.configure do
|
|||
# want to log everything, set the level to "debug".
|
||||
config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info")
|
||||
|
||||
# Use a different cache store in production.
|
||||
# config.cache_store = :mem_cache_store
|
||||
if ENV["CACHE_REDIS_URL"].present?
|
||||
config.cache_store = :redis_cache_store, { url: ENV["CACHE_REDIS_URL"] }
|
||||
end
|
||||
|
||||
config.action_mailer.perform_caching = false
|
||||
|
||||
config.action_mailer.deliver_later_queue_name = :high_priority
|
||||
config.action_mailer.default_url_options = { host: ENV["APP_DOMAIN"] }
|
||||
config.action_mailer.delivery_method = :smtp
|
||||
config.action_mailer.smtp_settings = {
|
||||
|
@ -105,4 +106,7 @@ Rails.application.configure do
|
|||
# ]
|
||||
# Skip DNS rebinding protection for the default health check endpoint.
|
||||
# config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
|
||||
|
||||
# set REDIS_URL for Sidekiq to use Redis
|
||||
config.active_job.queue_adapter = :sidekiq
|
||||
end
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
Rails.application.configure do
|
||||
config.good_job.enable_cron = true
|
||||
|
||||
if ENV["UPGRADES_ENABLED"] == "true"
|
||||
config.good_job.cron = {
|
||||
auto_upgrade: {
|
||||
cron: "every 2 minutes",
|
||||
class: "AutoUpgradeJob",
|
||||
description: "Check for new versions of the app and upgrade if necessary"
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
config.good_job.on_thread_error = ->(exception) { Rails.error.report(exception) }
|
||||
|
||||
# 7 dedicated queue threads + 5 catch-all threads + 3 for job listener, cron, executor = 15 threads allocated
|
||||
# `latency_low` queue for jobs ~30s
|
||||
# `latency_medium` queue for jobs ~1-2 min
|
||||
# `latency_high` queue for jobs ~5+ min
|
||||
config.good_job.queues = "latency_low:2;latency_low,latency_medium:3;latency_low,latency_medium,latency_high:2;*"
|
||||
|
||||
# Auth for jobs admin dashboard
|
||||
ActiveSupport.on_load(:good_job_application_controller) do
|
||||
before_action do
|
||||
raise ActionController::RoutingError.new("Not Found") unless current_user&.super_admin? || Rails.env.development?
|
||||
end
|
||||
|
||||
def current_user
|
||||
session = Session.find_by(id: cookies.signed[:session_token])
|
||||
session&.user
|
||||
end
|
||||
end
|
||||
end
|
9
config/initializers/sidekiq.rb
Normal file
9
config/initializers/sidekiq.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
require "sidekiq/web"
|
||||
|
||||
Sidekiq::Web.use(Rack::Auth::Basic) do |username, password|
|
||||
configured_username = ::Digest::SHA256.hexdigest(ENV.fetch("SIDEKIQ_WEB_USERNAME", "maybe"))
|
||||
configured_password = ::Digest::SHA256.hexdigest(ENV.fetch("SIDEKIQ_WEB_PASSWORD", "maybe"))
|
||||
|
||||
ActiveSupport::SecurityUtils.secure_compare(::Digest::SHA256.hexdigest(username), configured_username) &&
|
||||
ActiveSupport::SecurityUtils.secure_compare(::Digest::SHA256.hexdigest(password), configured_password)
|
||||
end
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
en:
|
||||
upgrader:
|
||||
deployer:
|
||||
null_deployer:
|
||||
success_message: 'No-op: null deployer initiated deploy successfully'
|
||||
render:
|
||||
deploy_log_error: 'Failed to deploy %{type} %{commit_sha} to Render: %{error_message}'
|
||||
deploy_log_info: Deploying %{type} %{commit_sha} to Render...
|
||||
error_message_failed_deploy: Failed to deploy to Render
|
||||
error_message_not_set: Render deploy hook URL is not set
|
||||
success_message: 'Triggered deployment to Render for commit: %{commit_sha}'
|
||||
troubleshooting_url: https://render.com/docs/deploy-hooks
|
|
@ -11,11 +11,6 @@ en:
|
|||
generate_tokens: Generate new code
|
||||
generated_tokens: Generated codes
|
||||
title: Require invite code for signup
|
||||
provider_settings:
|
||||
description: Configure settings for your hosting provider
|
||||
render_deploy_hook_label: Render Deploy Hook URL
|
||||
render_deploy_hook_placeholder: https://api.render.com/deploy/srv-xyz...
|
||||
title: Provider Settings
|
||||
show:
|
||||
general: General Settings
|
||||
invites: Invite Codes
|
||||
|
@ -38,14 +33,4 @@ en:
|
|||
success: Settings updated
|
||||
clear_cache:
|
||||
cache_cleared: Data cache has been cleared. This may take a few moments to complete.
|
||||
upgrade_settings:
|
||||
description: Configure how your application receives updates
|
||||
latest_commit_description: Automatically update to the latest commit (unstable)
|
||||
latest_commit_title: Latest Commit
|
||||
latest_release_description: Automatically update to the most recent release
|
||||
(stable)
|
||||
latest_release_title: Latest Release
|
||||
manual_description: You control when to download and install updates
|
||||
manual_title: Manual
|
||||
title: Auto Upgrade
|
||||
not_authorized: You are not authorized to perform this action
|
||||
|
|
|
@ -10,8 +10,3 @@ en:
|
|||
label: Amount
|
||||
syncing_notice:
|
||||
syncing: Syncing accounts data...
|
||||
upgrade_notification:
|
||||
app_upgraded: The app has been upgraded to %{version}.
|
||||
dismiss: Dismiss
|
||||
new_version_available: A new version of Maybe is available for upgrade.
|
||||
upgrade_now: Upgrade Now
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
---
|
||||
en:
|
||||
upgrades:
|
||||
acknowledge:
|
||||
upgrade_complete_dismiss: We hope you enjoy the new features!
|
||||
upgrade_dismissed: Upgrade dismissed
|
||||
upgrade_not_available: Upgrade not available
|
||||
upgrade_not_found: Upgrade not found
|
||||
deploy:
|
||||
upgrade_not_found: Upgrade not found
|
|
@ -1,3 +1,5 @@
|
|||
require "sidekiq/web"
|
||||
|
||||
Rails.application.routes.draw do
|
||||
# MFA routes
|
||||
resource :mfa, controller: "mfa", only: [ :new, :create ] do
|
||||
|
@ -6,7 +8,8 @@ Rails.application.routes.draw do
|
|||
delete :disable
|
||||
end
|
||||
|
||||
mount GoodJob::Engine => "good_job"
|
||||
# Uses basic auth - see config/initializers/sidekiq.rb
|
||||
mount Sidekiq::Web => "/sidekiq"
|
||||
|
||||
get "changelog", to: "pages#changelog"
|
||||
get "feedback", to: "pages#feedback"
|
||||
|
@ -158,14 +161,6 @@ Rails.application.routes.draw do
|
|||
get :accept, on: :member
|
||||
end
|
||||
|
||||
# For managing self-hosted upgrades and release notifications
|
||||
resources :upgrades, only: [] do
|
||||
member do
|
||||
post :acknowledge
|
||||
post :deploy
|
||||
end
|
||||
end
|
||||
|
||||
resources :currencies, only: %i[show]
|
||||
|
||||
resources :impersonation_sessions, only: [ :create ] do
|
||||
|
|
5
config/sidekiq.yml
Normal file
5
config/sidekiq.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
concurrency: <%= ENV.fetch("RAILS_MAX_THREADS") { 3 } %>
|
||||
queues:
|
||||
- [high_priority, 7]
|
||||
- [medium_priority, 2]
|
||||
- [low_priority, 1]
|
|
@ -22,16 +22,4 @@ cloudflare:
|
|||
bucket: <%= ENV['CLOUDFLARE_BUCKET'] %>
|
||||
request_checksum_calculation: "when_required"
|
||||
response_checksum_validation: "when_required"
|
||||
|
||||
# Removed in #702. Uncomment, add gems, update .env.example to enable.
|
||||
#google:
|
||||
# service: GCS
|
||||
# project: <%#= ENV["GCS_PROJECT"] %>
|
||||
# credentials: <%#= Rails.root.join("gcp-storage-keyfile.json") %>
|
||||
# bucket: <%#= ENV["GCS_BUCKET"] %>
|
||||
|
||||
#azure:
|
||||
# service: AzureStorage
|
||||
# storage_account_name: <%#= ENV["AZURE_STORAGE_ACCOUNT_NAME"] %>
|
||||
# storage_access_key: <%#= ENV["AZURE_STORAGE_ACCESS_KEY"] %>
|
||||
# container: <%#= ENV["AZURE_STORAGE_CONTAINER"] %>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue