diff options
author | Thibaut Girka <thib@sitedethib.com> | 2018-08-21 18:24:48 +0200 |
---|---|---|
committer | Thibaut Girka <thib@sitedethib.com> | 2018-08-21 18:24:48 +0200 |
commit | 8b4abaa90d8dff64525d92c3ba1c750356608240 (patch) | |
tree | 51f194442d2ec7ab760b443b98c7685f64481ca7 /app | |
parent | c78918162642649ce294d89effbf2e815c2aa327 (diff) | |
parent | f06fa099625e928e5858ea81a20be1eddf6c6fbb (diff) |
Merge branch 'master' into glitch-soc/master
Conflicts: config/routes.rb Added the “endorsements” route from upstream.
Diffstat (limited to 'app')
33 files changed, 174 insertions, 49 deletions
diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index 3d20f0e88..85d9e784a 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -43,7 +43,7 @@ class AccountsController < ApplicationController format.json do skip_session! - render_cached_json(['activitypub', 'actor', @account.cache_key], content_type: 'application/activity+json') do + render_cached_json(['activitypub', 'actor', @account], content_type: 'application/activity+json') do ActiveModelSerializers::SerializableResource.new(@account, serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter) end end diff --git a/app/controllers/api/v1/endorsements_controller.rb b/app/controllers/api/v1/endorsements_controller.rb new file mode 100644 index 000000000..0f04b488f --- /dev/null +++ b/app/controllers/api/v1/endorsements_controller.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +class Api::V1::EndorsementsController < Api::BaseController + before_action -> { doorkeeper_authorize! :read, :'read:accounts' } + before_action :require_user! + after_action :insert_pagination_headers + + respond_to :json + + def index + @accounts = load_accounts + render json: @accounts, each_serializer: REST::AccountSerializer + end + + private + + def load_accounts + if unlimited? + endorsed_accounts.all + else + endorsed_accounts.paginate_by_max_id( + limit_param(DEFAULT_ACCOUNTS_LIMIT), + params[:max_id], + params[:since_id] + ) + end + end + + def endorsed_accounts + current_account.endorsed_accounts + end + + def insert_pagination_headers + set_pagination_headers(next_path, prev_path) + end + + def next_path + return if unlimited? + + if records_continue? + api_v1_endorsements_url pagination_params(max_id: pagination_max_id) + end + end + + def prev_path + return if unlimited? + + unless @accounts.empty? + api_v1_endorsements_url pagination_params(since_id: pagination_since_id) + end + end + + def pagination_max_id + @accounts.last.id + end + + def pagination_since_id + @accounts.first.id + end + + def records_continue? + @accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT) + end + + def pagination_params(core_params) + params.slice(:limit).permit(:limit).merge(core_params) + end + + def unlimited? + params[:limit] == '0' + end +end diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb index c6925d462..49a52f7a6 100644 --- a/app/controllers/api/v1/statuses_controller.rb +++ b/app/controllers/api/v1/statuses_controller.rb @@ -17,8 +17,7 @@ class Api::V1::StatusesController < Api::BaseController CONTEXT_LIMIT = 4_096 def show - cached = Rails.cache.read(@status.cache_key) - @status = cached unless cached.nil? + @status = cache_collection([@status], Status).first render json: @status, serializer: REST::StatusSerializer end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index cc92894a5..27cd0f4f9 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -178,12 +178,8 @@ class ApplicationController < ActionController::Base return raw unless klass.respond_to?(:with_includes) raw = raw.cache_ids.to_a if raw.is_a?(ActiveRecord::Relation) - uncached_ids = [] - cached_keys_with_value = Rails.cache.read_multi(*raw.map(&:cache_key)) - - raw.each do |item| - uncached_ids << item.id unless cached_keys_with_value.key?(item.cache_key) - end + cached_keys_with_value = Rails.cache.read_multi(*raw).transform_keys(&:id) + uncached_ids = raw.map(&:id) - cached_keys_with_value.keys klass.reload_stale_associations!(cached_keys_with_value.values) if klass.respond_to?(:reload_stale_associations!) @@ -191,11 +187,11 @@ class ApplicationController < ActionController::Base uncached = klass.where(id: uncached_ids).with_includes.map { |item| [item.id, item] }.to_h uncached.each_value do |item| - Rails.cache.write(item.cache_key, item) + Rails.cache.write(item, item) end end - raw.map { |item| cached_keys_with_value[item.cache_key] || uncached[item.id] }.compact + raw.map { |item| cached_keys_with_value[item.id] || uncached[item.id] }.compact end def respond_with_error(code) @@ -211,7 +207,6 @@ class ApplicationController < ActionController::Base def render_cached_json(cache_key, **options) options[:expires_in] ||= 3.minutes - cache_key = cache_key.join(':') if cache_key.is_a?(Enumerable) cache_public = options.key?(:public) ? options.delete(:public) : true content_type = options.delete(:content_type) || 'application/json' diff --git a/app/controllers/emojis_controller.rb b/app/controllers/emojis_controller.rb index c9725ccc0..5d306e600 100644 --- a/app/controllers/emojis_controller.rb +++ b/app/controllers/emojis_controller.rb @@ -9,7 +9,7 @@ class EmojisController < ApplicationController format.json do skip_session! - render_cached_json(['activitypub', 'emoji', @emoji.cache_key], content_type: 'application/activity+json') do + render_cached_json(['activitypub', 'emoji', @emoji], content_type: 'application/activity+json') do ActiveModelSerializers::SerializableResource.new(@emoji, serializer: ActivityPub::EmojiSerializer, adapter: ActivityPub::Adapter) end end diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb index 1940aaa1b..bc711a8e4 100644 --- a/app/controllers/statuses_controller.rb +++ b/app/controllers/statuses_controller.rb @@ -34,7 +34,7 @@ class StatusesController < ApplicationController format.json do skip_session! unless @stream_entry.hidden? - render_cached_json(['activitypub', 'note', @status.cache_key], content_type: 'application/activity+json', public: !@stream_entry.hidden?) do + render_cached_json(['activitypub', 'note', @status], content_type: 'application/activity+json', public: !@stream_entry.hidden?) do ActiveModelSerializers::SerializableResource.new(@status, serializer: ActivityPub::NoteSerializer, adapter: ActivityPub::Adapter) end end @@ -44,7 +44,7 @@ class StatusesController < ApplicationController def activity skip_session! - render_cached_json(['activitypub', 'activity', @status.cache_key], content_type: 'application/activity+json', public: !@stream_entry.hidden?) do + render_cached_json(['activitypub', 'activity', @status], content_type: 'application/activity+json', public: !@stream_entry.hidden?) do ActiveModelSerializers::SerializableResource.new(@status, serializer: ActivityPub::ActivitySerializer, adapter: ActivityPub::Adapter) end end diff --git a/app/javascript/mastodon/actions/timelines.js b/app/javascript/mastodon/actions/timelines.js index 11a199db6..e8fd441e1 100644 --- a/app/javascript/mastodon/actions/timelines.js +++ b/app/javascript/mastodon/actions/timelines.js @@ -55,7 +55,7 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) { return; } - if (!params.max_id && timeline.get('items', ImmutableList()).size > 0) { + if (!params.max_id && !params.pinned && timeline.get('items', ImmutableList()).size > 0) { params.since_id = timeline.getIn(['items', 0]); } diff --git a/app/javascript/mastodon/components/dropdown_menu.js b/app/javascript/mastodon/components/dropdown_menu.js index 0a6e7c627..e83f724e9 100644 --- a/app/javascript/mastodon/components/dropdown_menu.js +++ b/app/javascript/mastodon/components/dropdown_menu.js @@ -137,7 +137,7 @@ class DropdownMenu extends React.PureComponent { // It should not be transformed when mounting because the resulting // size will be used to determine the coordinate of the menu by // react-overlays - <div className='dropdown-menu' style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} ref={this.setRef}> + <div className={`dropdown-menu ${placement}`} style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} ref={this.setRef}> <div className={`dropdown-menu__arrow ${placement}`} style={{ left: arrowOffsetLeft, top: arrowOffsetTop }} /> <ul> diff --git a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js index a772c1c95..e19778fd2 100644 --- a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js +++ b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js @@ -28,6 +28,7 @@ class PrivacyDropdownMenu extends React.PureComponent { style: PropTypes.object, items: PropTypes.array.isRequired, value: PropTypes.string.isRequired, + placement: PropTypes.string.isRequired, onClose: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired, }; @@ -119,7 +120,7 @@ class PrivacyDropdownMenu extends React.PureComponent { render () { const { mounted } = this.state; - const { style, items, value } = this.props; + const { style, items, placement, value } = this.props; return ( <Motion defaultStyle={{ opacity: 0, scaleX: 0.85, scaleY: 0.75 }} style={{ opacity: spring(1, { damping: 35, stiffness: 400 }), scaleX: spring(1, { damping: 35, stiffness: 400 }), scaleY: spring(1, { damping: 35, stiffness: 400 }) }}> @@ -127,7 +128,7 @@ class PrivacyDropdownMenu extends React.PureComponent { // It should not be transformed when mounting because the resulting // size will be used to determine the coordinate of the menu by // react-overlays - <div className='privacy-dropdown__dropdown' style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} role='listbox' ref={this.setRef}> + <div className={`privacy-dropdown__dropdown ${placement}`} style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} role='listbox' ref={this.setRef}> {items.map(item => ( <div role='option' tabIndex='0' key={item.value} data-index={item.value} onKeyDown={this.handleKeyDown} onClick={this.handleClick} className={classNames('privacy-dropdown__option', { active: item.value === value })} aria-selected={item.value === value} ref={item.value === value ? this.setFocusRef : null}> <div className='privacy-dropdown__option__icon'> @@ -226,7 +227,7 @@ export default class PrivacyDropdown extends React.PureComponent { const valueOption = this.options.find(item => item.value === value); return ( - <div className={classNames('privacy-dropdown', { active: open })} onKeyDown={this.handleKeyDown}> + <div className={classNames('privacy-dropdown', placement, { active: open })} onKeyDown={this.handleKeyDown}> <div className={classNames('privacy-dropdown__value', { active: this.options.indexOf(valueOption) === 0 })}> <IconButton className='privacy-dropdown__value-icon' @@ -247,6 +248,7 @@ export default class PrivacyDropdown extends React.PureComponent { value={value} onClose={this.handleClose} onChange={this.handleChange} + placement={placement} /> </Overlay> </div> diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js index 67484fc63..34d52a7d2 100644 --- a/app/javascript/mastodon/features/ui/index.js +++ b/app/javascript/mastodon/features/ui/index.js @@ -89,6 +89,7 @@ const keyMap = { goToProfile: 'g u', goToBlocked: 'g b', goToMuted: 'g m', + goToRequests: 'g r', toggleHidden: 'x', }; @@ -427,6 +428,10 @@ export default class UI extends React.PureComponent { this.context.router.history.push('/mutes'); } + handleHotkeyGoToRequests = () => { + this.context.router.history.push('/follow_requests'); + } + render () { const { draggingOver } = this.state; const { children, isComposing, location, dropdownMenuIsOpen } = this.props; @@ -449,6 +454,7 @@ export default class UI extends React.PureComponent { goToProfile: this.handleHotkeyGoToProfile, goToBlocked: this.handleHotkeyGoToBlocked, goToMuted: this.handleHotkeyGoToMuted, + goToRequests: this.handleHotkeyGoToRequests, }; return ( diff --git a/app/javascript/mastodon/selectors/index.js b/app/javascript/mastodon/selectors/index.js index 106198f74..70f08a8eb 100644 --- a/app/javascript/mastodon/selectors/index.js +++ b/app/javascript/mastodon/selectors/index.js @@ -1,5 +1,6 @@ import { createSelector } from 'reselect'; import { List as ImmutableList } from 'immutable'; +import { me } from '../initial_state'; const getAccountBase = (state, id) => state.getIn(['accounts', id], null); const getAccountCounters = (state, id) => state.getIn(['accounts_counters', id], null); @@ -83,7 +84,7 @@ export const makeGetStatus = () => { statusReblog = null; } - const regex = regexFromFilters(filters); + const regex = (accountReblog || accountBase).get('id') !== me && regexFromFilters(filters); const filtered = regex && regex.test(statusBase.get('reblog') ? statusReblog.get('search_index') : statusBase.get('search_index')); return statusBase.withMutations(map => { diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 64a00c2c3..6073f9c0e 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -230,7 +230,6 @@ .dropdown-menu { position: absolute; - transform-origin: 50% 0; } .invisible { @@ -1634,6 +1633,22 @@ a.account__display-name { ul { list-style: none; } + + &.left { + transform-origin: 100% 50%; + } + + &.top { + transform-origin: 50% 100%; + } + + &.bottom { + transform-origin: 50% 0; + } + + &.right { + transform-origin: 0 50%; + } } .dropdown-menu__arrow { @@ -3300,7 +3315,14 @@ a.status-card { border-radius: 4px; margin-left: 40px; overflow: hidden; - transform-origin: 50% 0; + + &.top { + transform-origin: 50% 100%; + } + + &.bottom { + transform-origin: 50% 0; + } } .privacy-dropdown__option { @@ -3372,6 +3394,10 @@ a.status-card { } } + &.top .privacy-dropdown__value { + border-radius: 0 0 4px 4px; + } + .privacy-dropdown__dropdown { display: block; box-shadow: 2px 4px 6px rgba($base-shadow-color, 0.1); @@ -4176,6 +4202,10 @@ a.status-card { color: $highlight-text-color; } + .status__content p { + color: $inverted-text-color; + } + @media screen and (max-width: 480px) { max-height: 10vh; } diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss index 375c7b64b..22dbfa8cf 100644 --- a/app/javascript/styles/mastodon/forms.scss +++ b/app/javascript/styles/mastodon/forms.scss @@ -154,9 +154,8 @@ code { margin-bottom: 15px; } - li { - float: left; - width: 50%; + ul { + columns: 2; } } diff --git a/app/models/account_pin.rb b/app/models/account_pin.rb index 9a21c3405..b51d3d4cd 100644 --- a/app/models/account_pin.rb +++ b/app/models/account_pin.rb @@ -11,6 +11,7 @@ # class AccountPin < ApplicationRecord + include Paginable include RelationshipCacheable belongs_to :account diff --git a/app/models/form/status_batch.rb b/app/models/form/status_batch.rb index 4f08a3049..8f5fd1fa2 100644 --- a/app/models/form/status_batch.rb +++ b/app/models/form/status_batch.rb @@ -23,7 +23,7 @@ class Form::StatusBatch media_attached_status_ids = MediaAttachment.where(status_id: status_ids).pluck(:status_id) ApplicationRecord.transaction do - Status.where(id: media_attached_status_ids).find_each do |status| + Status.where(id: media_attached_status_ids).reorder(nil).find_each do |status| status.update!(sensitive: sensitive) log_action :update, status end @@ -35,7 +35,7 @@ class Form::StatusBatch end def delete_statuses - Status.where(id: status_ids).find_each do |status| + Status.where(id: status_ids).reorder(nil).find_each do |status| RemovalWorker.perform_async(status.id) log_action :destroy, status end diff --git a/app/models/notification.rb b/app/models/notification.rb index 4f6ec8e8e..b9bec0808 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -39,8 +39,6 @@ class Notification < ApplicationRecord validates :account_id, uniqueness: { scope: [:activity_type, :activity_id] } validates :activity_type, inclusion: { in: TYPE_CLASS_MAP.values } - scope :cache_ids, -> { select(:id, :updated_at, :activity_type, :activity_id) } - scope :browserable, ->(exclude_types = []) { types = TYPE_CLASS_MAP.values - activity_types_from_types(exclude_types + [:follow_request]) where(activity_type: types) @@ -68,6 +66,10 @@ class Notification < ApplicationRecord end class << self + def cache_ids + select(:id, :updated_at, :activity_type, :activity_id) + end + def reload_stale_associations!(cached_items) account_ids = (cached_items.map(&:from_account_id) + cached_items.map { |item| item.target_status&.account_id }.compact).uniq diff --git a/app/models/status.rb b/app/models/status.rb index 8cd6d3862..f38227b85 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -26,8 +26,6 @@ # class Status < ApplicationRecord - self.cache_versioning = false - include Paginable include Streamable include Cacheable diff --git a/app/services/after_block_domain_from_account_service.rb b/app/services/after_block_domain_from_account_service.rb index 0f1a8505d..56cc819fb 100644 --- a/app/services/after_block_domain_from_account_service.rb +++ b/app/services/after_block_domain_from_account_service.rb @@ -15,13 +15,13 @@ class AfterBlockDomainFromAccountService < BaseService private def reject_existing_followers! - @account.passive_relationships.where(account: Account.where(domain: @domain)).includes(:account).find_each do |follow| + @account.passive_relationships.where(account: Account.where(domain: @domain)).includes(:account).reorder(nil).find_each do |follow| reject_follow!(follow) end end def reject_pending_follow_requests! - FollowRequest.where(target_account: @account).where(account: Account.where(domain: @domain)).includes(:account).find_each do |follow_request| + FollowRequest.where(target_account: @account).where(account: Account.where(domain: @domain)).includes(:account).reorder(nil).find_each do |follow_request| reject_follow!(follow_request) end end diff --git a/app/services/backup_service.rb b/app/services/backup_service.rb index 8492c1117..da7db6462 100644 --- a/app/services/backup_service.rb +++ b/app/services/backup_service.rb @@ -18,7 +18,7 @@ class BackupService < BaseService def build_json! @collection = serialize(collection_presenter, ActivityPub::CollectionSerializer) - account.statuses.with_includes.find_in_batches do |statuses| + account.statuses.with_includes.reorder(nil).find_in_batches do |statuses| statuses.each do |status| item = serialize(status, ActivityPub::ActivitySerializer) item.delete(:'@context') @@ -60,7 +60,7 @@ class BackupService < BaseService end def dump_media_attachments!(tar) - MediaAttachment.attached.where(account: account).find_in_batches do |media_attachments| + MediaAttachment.attached.where(account: account).reorder(nil).find_in_batches do |media_attachments| media_attachments.each do |m| download_to_tar(tar, m.file, m.file.path) end diff --git a/app/services/block_domain_service.rb b/app/services/block_domain_service.rb index d082de40b..a1fe93665 100644 --- a/app/services/block_domain_service.rb +++ b/app/services/block_domain_service.rb @@ -43,14 +43,14 @@ class BlockDomainService < BaseService end def suspend_accounts! - blocked_domain_accounts.where(suspended: false).find_each do |account| + blocked_domain_accounts.where(suspended: false).reorder(nil).find_each do |account| UnsubscribeService.new.call(account) if account.subscribed? SuspendAccountService.new.call(account) end end def clear_account_images! - blocked_domain_accounts.find_each do |account| + blocked_domain_accounts.reorder(nil).find_each do |account| account.avatar.destroy if account.avatar.exists? account.header.destroy if account.header.exists? account.save @@ -58,7 +58,7 @@ class BlockDomainService < BaseService end def clear_account_attachments! - media_from_blocked_domain.find_each do |attachment| + media_from_blocked_domain.reorder(nil).find_each do |attachment| @affected_status_ids << attachment.status_id if attachment.status_id.present? attachment.file.destroy if attachment.file.exists? diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb index fb889140b..1a53093b8 100644 --- a/app/services/remove_status_service.rb +++ b/app/services/remove_status_service.rb @@ -43,13 +43,13 @@ class RemoveStatusService < BaseService end def remove_from_followers - @account.followers_for_local_distribution.find_each do |follower| + @account.followers_for_local_distribution.reorder(nil).find_each do |follower| FeedManager.instance.unpush_from_home(follower, @status) end end def remove_from_lists - @account.lists_for_local_distribution.select(:id, :account_id).find_each do |list| + @account.lists_for_local_distribution.select(:id, :account_id).reorder(nil).find_each do |list| FeedManager.instance.unpush_from_list(list, @status) end end diff --git a/app/services/suspend_account_service.rb b/app/services/suspend_account_service.rb index 0a98f5fb9..8fc79b8ad 100644 --- a/app/services/suspend_account_service.rb +++ b/app/services/suspend_account_service.rb @@ -23,9 +23,7 @@ class SuspendAccountService < BaseService def purge_content! if @account.local? - ActivityPub::RawDistributionWorker.perform_async(delete_actor_json, @account.id) - - ActivityPub::DeliveryWorker.push_bulk(Relay.enabled.pluck(:inbox_url)) do |inbox_url| + ActivityPub::DeliveryWorker.push_bulk(delivery_inboxes) do |inbox_url| [delete_actor_json, @account.id, inbox_url] end end @@ -75,4 +73,8 @@ class SuspendAccountService < BaseService @delete_actor_json = Oj.dump(ActivityPub::LinkedDataSignature.new(payload).sign!(@account)) end + + def delivery_inboxes + Account.inboxes + Relay.enabled.pluck(:inbox_url) + end end diff --git a/app/workers/maintenance/uncache_media_worker.rb b/app/workers/maintenance/uncache_media_worker.rb index f6a51a1b8..2d1a670a7 100644 --- a/app/workers/maintenance/uncache_media_worker.rb +++ b/app/workers/maintenance/uncache_media_worker.rb @@ -8,7 +8,7 @@ class Maintenance::UncacheMediaWorker def perform(media_attachment_id) media = MediaAttachment.find(media_attachment_id) - return unless media.file.exists? + return if media.file.blank? media.file.destroy media.save diff --git a/app/workers/refollow_worker.rb b/app/workers/refollow_worker.rb index 66bcd27c3..12f2bf671 100644 --- a/app/workers/refollow_worker.rb +++ b/app/workers/refollow_worker.rb @@ -9,7 +9,7 @@ class RefollowWorker target_account = Account.find(target_account_id) return unless target_account.protocol == :activitypub - target_account.followers.where(domain: nil).find_each do |follower| + target_account.followers.where(domain: nil).reorder(nil).find_each do |follower| # Locally unfollow remote account follower.unfollow!(target_account) diff --git a/app/workers/scheduler/backup_cleanup_scheduler.rb b/app/workers/scheduler/backup_cleanup_scheduler.rb index 5ab16c057..023a77307 100644 --- a/app/workers/scheduler/backup_cleanup_scheduler.rb +++ b/app/workers/scheduler/backup_cleanup_scheduler.rb @@ -3,8 +3,10 @@ class Scheduler::BackupCleanupScheduler include Sidekiq::Worker + sidekiq_options unique: :until_executed + def perform - old_backups.find_each(&:destroy!) + old_backups.reorder(nil).find_each(&:destroy!) end private diff --git a/app/workers/scheduler/doorkeeper_cleanup_scheduler.rb b/app/workers/scheduler/doorkeeper_cleanup_scheduler.rb index bab4ae886..fec08c6bc 100644 --- a/app/workers/scheduler/doorkeeper_cleanup_scheduler.rb +++ b/app/workers/scheduler/doorkeeper_cleanup_scheduler.rb @@ -3,6 +3,8 @@ class Scheduler::DoorkeeperCleanupScheduler include Sidekiq::Worker + sidekiq_options unique: :until_executed + def perform Doorkeeper::AccessToken.where('revoked_at IS NOT NULL').where('revoked_at < NOW()').delete_all Doorkeeper::AccessGrant.where('revoked_at IS NOT NULL').where('revoked_at < NOW()').delete_all diff --git a/app/workers/scheduler/email_scheduler.rb b/app/workers/scheduler/email_scheduler.rb index 36866061b..24117e424 100644 --- a/app/workers/scheduler/email_scheduler.rb +++ b/app/workers/scheduler/email_scheduler.rb @@ -3,8 +3,10 @@ class Scheduler::EmailScheduler include Sidekiq::Worker + sidekiq_options unique: :until_executed + def perform - eligible_users.find_each do |user| + eligible_users.reorder(nil).find_each do |user| next unless user.allows_digest_emails? DigestMailerWorker.perform_async(user.id) end diff --git a/app/workers/scheduler/feed_cleanup_scheduler.rb b/app/workers/scheduler/feed_cleanup_scheduler.rb index 42cf14128..b02bac883 100644 --- a/app/workers/scheduler/feed_cleanup_scheduler.rb +++ b/app/workers/scheduler/feed_cleanup_scheduler.rb @@ -3,6 +3,8 @@ class Scheduler::FeedCleanupScheduler include Sidekiq::Worker + sidekiq_options unique: :until_executed + def perform clean_home_feeds! clean_list_feeds! diff --git a/app/workers/scheduler/ip_cleanup_scheduler.rb b/app/workers/scheduler/ip_cleanup_scheduler.rb index 613a5e336..6bb93df7d 100644 --- a/app/workers/scheduler/ip_cleanup_scheduler.rb +++ b/app/workers/scheduler/ip_cleanup_scheduler.rb @@ -5,6 +5,8 @@ class Scheduler::IpCleanupScheduler RETENTION_PERIOD = 1.year + sidekiq_options unique: :until_executed + def perform time_ago = RETENTION_PERIOD.ago SessionActivation.where('updated_at < ?', time_ago).destroy_all diff --git a/app/workers/scheduler/media_cleanup_scheduler.rb b/app/workers/scheduler/media_cleanup_scheduler.rb index c35686fcb..a27e02953 100644 --- a/app/workers/scheduler/media_cleanup_scheduler.rb +++ b/app/workers/scheduler/media_cleanup_scheduler.rb @@ -3,6 +3,8 @@ class Scheduler::MediaCleanupScheduler include Sidekiq::Worker + sidekiq_options unique: :until_executed + def perform unattached_media.find_each(&:destroy) end diff --git a/app/workers/scheduler/subscriptions_cleanup_scheduler.rb b/app/workers/scheduler/subscriptions_cleanup_scheduler.rb index af2ae3120..06ba66205 100644 --- a/app/workers/scheduler/subscriptions_cleanup_scheduler.rb +++ b/app/workers/scheduler/subscriptions_cleanup_scheduler.rb @@ -3,6 +3,8 @@ class Scheduler::SubscriptionsCleanupScheduler include Sidekiq::Worker + sidekiq_options unique: :until_executed + def perform Subscription.expired.in_batches.delete_all end diff --git a/app/workers/scheduler/subscriptions_scheduler.rb b/app/workers/scheduler/subscriptions_scheduler.rb index dc16e85c2..4b0959af2 100644 --- a/app/workers/scheduler/subscriptions_scheduler.rb +++ b/app/workers/scheduler/subscriptions_scheduler.rb @@ -3,6 +3,8 @@ class Scheduler::SubscriptionsScheduler include Sidekiq::Worker + sidekiq_options unique: :until_executed + def perform Pubsubhubbub::SubscribeWorker.push_bulk(expiring_accounts.pluck(:id)) end diff --git a/app/workers/scheduler/user_cleanup_scheduler.rb b/app/workers/scheduler/user_cleanup_scheduler.rb index 245536cea..626fb1652 100644 --- a/app/workers/scheduler/user_cleanup_scheduler.rb +++ b/app/workers/scheduler/user_cleanup_scheduler.rb @@ -3,8 +3,10 @@ class Scheduler::UserCleanupScheduler include Sidekiq::Worker + sidekiq_options unique: :until_executed + def perform - User.where('confirmed_at is NULL AND confirmation_sent_at <= ?', 2.days.ago).find_in_batches do |batch| + User.where('confirmed_at is NULL AND confirmation_sent_at <= ?', 2.days.ago).reorder(nil).find_in_batches do |batch| Account.where(id: batch.map(&:account_id)).delete_all User.where(id: batch.map(&:id)).delete_all end |