diff --git a/app/jobs/auto_upgrade_job.rb b/app/jobs/auto_upgrade_job.rb index 30c10bc7..34a0f3dc 100644 --- a/app/jobs/auto_upgrade_job.rb +++ b/app/jobs/auto_upgrade_job.rb @@ -1,5 +1,5 @@ class AutoUpgradeJob < ApplicationJob - queue_as :default + queue_as :latency_low def perform(*args) raise_if_disabled diff --git a/app/jobs/destroy_job.rb b/app/jobs/destroy_job.rb index 2296c45f..8ea120f6 100644 --- a/app/jobs/destroy_job.rb +++ b/app/jobs/destroy_job.rb @@ -1,5 +1,5 @@ class DestroyJob < ApplicationJob - queue_as :default + queue_as :latency_low def perform(model) model.destroy diff --git a/app/jobs/enrich_data_job.rb b/app/jobs/enrich_data_job.rb index 97286b82..f20875c8 100644 --- a/app/jobs/enrich_data_job.rb +++ b/app/jobs/enrich_data_job.rb @@ -1,5 +1,5 @@ class EnrichDataJob < ApplicationJob - queue_as :default + queue_as :latency_high def perform(account) account.enrich_data diff --git a/app/jobs/fetch_security_info_job.rb b/app/jobs/fetch_security_info_job.rb index 7dff6d0f..5eaafa43 100644 --- a/app/jobs/fetch_security_info_job.rb +++ b/app/jobs/fetch_security_info_job.rb @@ -1,5 +1,5 @@ class FetchSecurityInfoJob < ApplicationJob - queue_as :default + queue_as :latency_low def perform(security_id) return unless Security.security_info_provider.present? diff --git a/app/jobs/import_job.rb b/app/jobs/import_job.rb index f7fc2c01..8a7c490e 100644 --- a/app/jobs/import_job.rb +++ b/app/jobs/import_job.rb @@ -1,5 +1,5 @@ class ImportJob < ApplicationJob - queue_as :default + queue_as :latency_medium def perform(import) import.publish diff --git a/app/jobs/sync_job.rb b/app/jobs/sync_job.rb index c6f06253..187d18f7 100644 --- a/app/jobs/sync_job.rb +++ b/app/jobs/sync_job.rb @@ -1,5 +1,5 @@ class SyncJob < ApplicationJob - queue_as :default + queue_as :latency_medium def perform(sync) sync.perform diff --git a/app/jobs/user_purge_job.rb b/app/jobs/user_purge_job.rb index ff997807..2f173f7a 100644 --- a/app/jobs/user_purge_job.rb +++ b/app/jobs/user_purge_job.rb @@ -1,5 +1,5 @@ class UserPurgeJob < ApplicationJob - queue_as :default + queue_as :latency_low def perform(user) user.purge diff --git a/app/models/time_series.rb b/app/models/time_series.rb index 09091e8f..f9ef3ffb 100644 --- a/app/models/time_series.rb +++ b/app/models/time_series.rb @@ -37,6 +37,14 @@ class TimeSeries series: self end + def empty? + values.empty? + end + + def has_current_day_value? + values.any? { |v| v.date == Date.current } + end + # `as_json` returns the data shape used by D3 charts def as_json { diff --git a/app/views/accounts/chart.html.erb b/app/views/accounts/chart.html.erb index 67eee6fb..329edba2 100644 --- a/app/views/accounts/chart.html.erb +++ b/app/views/accounts/chart.html.erb @@ -17,15 +17,19 @@
- <% if series %> + <% if series.has_current_day_value? %>
+ <% elsif series.empty? %> +
+

No data available for the selected period.

+
<% else %>
-

No data available for the selected period.

+

Calculating latest balance data...

<% end %>
diff --git a/app/views/pages/dashboard/_net_worth_chart.html.erb b/app/views/pages/dashboard/_net_worth_chart.html.erb index f6bc9b5e..56d1adf7 100644 --- a/app/views/pages/dashboard/_net_worth_chart.html.erb +++ b/app/views/pages/dashboard/_net_worth_chart.html.erb @@ -1,12 +1,16 @@ <%# locals: (series:) %> -<% if series %> +<% if series.has_current_day_value? %>
+<% elsif series.empty? %> +
+

No data available for the selected period.

+
<% else %>
-

No data available for the selected period.

+

Calculating latest balance data...

<% end %> diff --git a/config/database.yml b/config/database.yml index 221e19e8..6e0652c4 100644 --- a/config/database.yml +++ b/config/database.yml @@ -1,7 +1,8 @@ default: &default adapter: postgresql encoding: unicode - pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> + # 3 connections for Puma, 8 for GoodJob (in async mode, the default for self-hosters) = 11 connections + pool: <%= ENV.fetch("DB_POOL_SIZE") { 11 } %> host: <%= ENV.fetch("DB_HOST") { "127.0.0.1" } %> port: <%= ENV.fetch("DB_PORT") { "5432" } %> user: <%= ENV.fetch("POSTGRES_USER") { nil } %> diff --git a/config/initializers/good_job.rb b/config/initializers/good_job.rb index 9ca92c0f..7649e5af 100644 --- a/config/initializers/good_job.rb +++ b/config/initializers/good_job.rb @@ -11,6 +11,14 @@ Rails.application.configure do } end + # 5 queue threads + 3 for job listener, cron, executor = 8 threads allocated + config.queues = { + "latency_low" => { max_threads: 1, priority: 10 }, # ~30s jobs + "latency_low,latency_medium" => { max_threads: 2, priority: 5 }, # ~1-2 min jobs + "latency_low,latency_medium,latency_high" => { max_threads: 1, priority: 1 }, # ~5+ min jobs + "*" => { max_threads: 1, priority: 0 } # fallback queue + } + # Auth for jobs admin dashboard ActiveSupport.on_load(:good_job_application_controller) do before_action do