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
UserRefreshWithLowUrgencyWorkeras it is and make no changes in this class. - Introduce
UserRefreshFromReplicaWorkerwhich will behave exactly like the currentUserRefreshWithLowUrgencyWorkerto start with. (so that it would read from primary) - In first iteration, replace calls to
UserRefreshWithLowUrgencyWorkerwith calls toUserRefreshFromReplicaWorkerwhere ever it is required. - In second iteration, start reading data in
UserRefreshFromReplicaWorkerfrom 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