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.

58 lines
1.6 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 create_progress_bar(total = nil)
  11. ProgressBar.create(total: total, format: '%c/%u |%b%i| %e')
  12. end
  13. def parallelize_with_progress(scope)
  14. ActiveRecord::Base.configurations[Rails.env]['pool'] = options[:concurrency]
  15. progress = create_progress_bar(scope.count)
  16. pool = Concurrent::FixedThreadPool.new(options[:concurrency])
  17. total = Concurrent::AtomicFixnum.new(0)
  18. aggregate = Concurrent::AtomicFixnum.new(0)
  19. scope.reorder(nil).find_in_batches do |items|
  20. futures = []
  21. items.each do |item|
  22. futures << Concurrent::Future.execute(executor: pool) do
  23. ActiveRecord::Base.connection_pool.with_connection do
  24. begin
  25. progress.log("Processing #{item.id}") if options[:verbose]
  26. result = yield(item)
  27. aggregate.increment(result) if result.is_a?(Integer)
  28. rescue => e
  29. progress.log pastel.red("Error processing #{item.id}: #{e}")
  30. ensure
  31. progress.increment
  32. end
  33. end
  34. end
  35. end
  36. total.increment(items.size)
  37. futures.map(&:value)
  38. end
  39. progress.finish
  40. [total.value, aggregate.value]
  41. end
  42. def pastel
  43. @pastel ||= Pastel.new
  44. end
  45. end
  46. end