Introduce UserRefreshFromReplicaWorker that runs as a "safety-net" for correcting any wrong project authorization records
Currently, we run UserRefreshWithLowUrgencyWorker
as a safety net for correcting any wrong project authorization records.
However, our plan going forward is to make these safety-net jobs read from the replica first, and only if the replica says that the user needs a refresh, will another job be enqueued.
The problem with the existing class, ie, UserRefreshWithLowUrgencyWorker
is that its name does not suggest that the data will be read from replica.
Moreover, there is a specific requirement to use the UserRefreshWithLowUrgencyWorker
over here that would read from primary. So it is best to keep UserRefreshWithLowUrgencyWorker
as it is, as it has uses elsewhere.
So the plan is,
- Keep
UserRefreshWithLowUrgencyWorker
as it is and make no changes in this class. - Introduce
UserRefreshFromReplicaWorker
which will behave exactly like the currentUserRefreshWithLowUrgencyWorker
to start with. (so that it would read from primary) - In first iteration, replace calls to
UserRefreshWithLowUrgencyWorker
with calls toUserRefreshFromReplicaWorker
where ever it is required. - In second iteration, start reading data in
UserRefreshFromReplicaWorker
from the replica and make code changes like so, (this is being tracked as a separate issue at #333219 (closed))
module AuthorizedProjectUpdate
class UserRefreshFromReplicaWorker
include ApplicationWorker
feature_category :authentication_and_authorization
urgency :low
queue_namespace :authorized_project_update
deduplicate :until_executing, including_scheduled: true
data_consistency :delayed
idempotent!
def perform(user_id)
user = User.find_by(id: user_id)
return unless user
enqueue_project_authorizations_refresh(user) if project_authorizations_needs_refresh?(user)
end
private
def project_authorizations_needs_refresh?(user)
AuthorizedProjectUpdate::FindRecordsDueForRefreshService.new(user).needs_refresh?
end
def enqueue_project_authorizations_refresh(user)
with_context(user: user) do
AuthorizedProjectUpdate::UserRefreshWithLowUrgencyWorker.perform_async(user.id)
end
end
end
end
Edited by Manoj M J