Add progress indicators to MigrateAccountConversations (#9101)
* Add progress indicators to MigrateAccountConversations * Avoid running expensive query for explain * Use exec_query instead of execute
This commit is contained in:
		| @ -14,12 +14,29 @@ class MigrateAccountConversations < ActiveRecord::Migration[5.2] | ||||
|       sleep 1 | ||||
|     end | ||||
|  | ||||
|     local_direct_statuses.find_each do |status| | ||||
|     total        = estimate_rows(local_direct_statuses) + estimate_rows(notifications_about_direct_statuses) | ||||
|     migrated     = 0 | ||||
|     started_time = Time.zone.now | ||||
|     last_time    = Time.zone.now | ||||
|  | ||||
|     local_direct_statuses.includes(:account, mentions: :account).find_each do |status| | ||||
|       AccountConversation.add_status(status.account, status) | ||||
|       migrated += 1 | ||||
|  | ||||
|       if Time.zone.now - last_time > 1 | ||||
|         say_progress(migrated, total, started_time) | ||||
|         last_time = Time.zone.now | ||||
|       end | ||||
|     end | ||||
|  | ||||
|     notifications_about_direct_statuses.find_each do |notification| | ||||
|     notifications_about_direct_statuses.includes(:account, mention: { status: [:account, mentions: :account] }).find_each do |notification| | ||||
|       AccountConversation.add_status(notification.account, notification.target_status) | ||||
|       migrated += 1 | ||||
|  | ||||
|       if Time.zone.now - last_time > 1 | ||||
|         say_progress(migrated, total, started_time) | ||||
|         last_time = Time.zone.now | ||||
|       end | ||||
|     end | ||||
|   end | ||||
|  | ||||
| @ -28,16 +45,31 @@ class MigrateAccountConversations < ActiveRecord::Migration[5.2] | ||||
|  | ||||
|   private | ||||
|  | ||||
|   def estimate_rows(query) | ||||
|     result = exec_query("EXPLAIN #{query.to_sql}").first | ||||
|     result['QUERY PLAN'].scan(/ rows=([\d]+)/).first&.first&.to_i || 0 | ||||
|   end | ||||
|  | ||||
|   def say_progress(migrated, total, started_time) | ||||
|     status = "Migrated #{migrated} rows" | ||||
|  | ||||
|     percentage = 100.0 * migrated / total | ||||
|     status += " (~#{sprintf('%.2f', percentage)}%, " | ||||
|  | ||||
|     remaining_time = (100.0 - percentage) * (Time.zone.now - started_time) / percentage | ||||
|  | ||||
|     status += "#{(remaining_time / 60).to_i}:" | ||||
|     status += sprintf('%02d', remaining_time.to_i % 60) | ||||
|     status += ' remaining)' | ||||
|  | ||||
|     say status, true | ||||
|   end | ||||
|  | ||||
|   def local_direct_statuses | ||||
|     Status.unscoped | ||||
|           .local | ||||
|           .where(visibility: :direct) | ||||
|           .includes(:account, mentions: :account) | ||||
|     Status.unscoped.local.where(visibility: :direct) | ||||
|   end | ||||
|  | ||||
|   def notifications_about_direct_statuses | ||||
|     Notification.joins(mention: :status) | ||||
|                 .where(activity_type: 'Mention', statuses: { visibility: :direct }) | ||||
|                 .includes(:account, mention: { status: [:account, mentions: :account] }) | ||||
|     Notification.joins(mention: :status).where(activity_type: 'Mention', statuses: { visibility: :direct }) | ||||
|   end | ||||
| end | ||||
|  | ||||
		Reference in New Issue
	
	Block a user