You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

76 lines
2.1 KiB

  1. # frozen_string_literal: true
  2. dev_null = Logger.new('/dev/null')
  3. Rails.logger = dev_null
  4. ActiveRecord::Base.logger = dev_null
  5. ActiveJob::Base.logger = dev_null
  6. HttpLog.configuration.logger = dev_null
  7. Paperclip.options[:log] = false
  8. module Mastodon
  9. module CLIHelper
  10. def dry_run?
  11. options[:dry_run]
  12. end
  13. def create_progress_bar(total = nil)
  14. ProgressBar.create(total: total, format: '%c/%u |%b%i| %e')
  15. end
  16. def parallelize_with_progress(scope)
  17. if options[:concurrency] < 1
  18. say('Cannot run with this concurrency setting, must be at least 1', :red)
  19. exit(1)
  20. end
  21. ActiveRecord::Base.configurations[Rails.env]['pool'] = options[:concurrency] + 1
  22. progress = create_progress_bar(scope.count)
  23. pool = Concurrent::FixedThreadPool.new(options[:concurrency])
  24. total = Concurrent::AtomicFixnum.new(0)
  25. aggregate = Concurrent::AtomicFixnum.new(0)
  26. scope.reorder(nil).find_in_batches do |items|
  27. futures = []
  28. items.each do |item|
  29. futures << Concurrent::Future.execute(executor: pool) do
  30. begin
  31. if !progress.total.nil? && progress.progress + 1 > progress.total
  32. # The number of items has changed between start and now,
  33. # since there is no good way to predict the final count from
  34. # here, just change the progress bar to an indeterminate one
  35. progress.total = nil
  36. end
  37. progress.log("Processing #{item.id}") if options[:verbose]
  38. result = ActiveRecord::Base.connection_pool.with_connection do
  39. yield(item)
  40. end
  41. aggregate.increment(result) if result.is_a?(Integer)
  42. rescue => e
  43. progress.log pastel.red("Error processing #{item.id}: #{e}")
  44. ensure
  45. progress.increment
  46. end
  47. end
  48. end
  49. total.increment(items.size)
  50. futures.map(&:value)
  51. end
  52. progress.stop
  53. [total.value, aggregate.value]
  54. end
  55. def pastel
  56. @pastel ||= Pastel.new
  57. end
  58. end
  59. end