-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CORE-133: Optimize SQL in billing account change synchronizer #3145
Conversation
@@ -540,6 +541,7 @@ trait RawlsBillingProjectComponent { | |||
) | |||
} | |||
|
|||
@VisibleForTesting | |||
def getLastChange(billingProject: RawlsBillingProjectName): ReadAction[Option[BillingAccountChange]] = | |||
BillingAccountChanges | |||
.withProjectName(billingProject) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is now only used in tests, so I annotated it
.filter(_.id.in(latestChangeIds)) | ||
.sortBy(_.id.asc) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the old unoptimized query, now unused.
@@ -47,7 +46,7 @@ object BillingAccountChangeSynchronizer { | |||
Behaviors.setup { context => | |||
val actor = BillingAccountChangeSynchronizer(dataSource, gcsDAO, samDAO) | |||
Behaviors.withTimers { scheduler => | |||
scheduler.startTimerAtFixedRate(UpdateBillingAccounts, initialDelay, pollInterval) | |||
scheduler.startTimerWithFixedDelay(UpdateBillingAccounts, initialDelay, pollInterval) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see https://doc.akka.io/japi/akka/snapshot/akka/actor/TimerScheduler.html for detailed explanation of the difference
BillingAccountChanges.latestChanges.unsynced | ||
.take(1) | ||
.result | ||
BillingAccountChanges.nextOutstanding().result |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the core of the PR - changing from the old query to the new one
_ <- validateStatusColumn.recover { case e: Exception => | ||
logger.warn(s"BillingAccountChangeStatus logic failed with ${e.getMessage}", e) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we no longer need to validate the old query and new query return the same results, since we're getting rid of the old query
} yield changes shouldBe List(change1, change2).map(_.value) | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the old query is gone, so this test can go too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Why is it better to take the task running time into account vs. just having them be "evenly spaced"?
@trholdridge imagine a task that runs for 7 seconds. If that task is scheduled via However, if that task is scheduled via In this PR's use case of polling for billing account changes, we aren't worried about delays of a few seconds; we'll get to the change when we get to it. So, let's choose the scheduling approach that is lighter on the system. If we had strict latency requirements we might choose otherwise. |
Ticket: https://broadworkbench.atlassian.net/browse/CORE-133
Followup to #3139. In that other PR, we added a new
STATUS
column to theBILLING_ACCOUNT_CHANGES
table, with logic to populate that column's values. We also added validation into theBillingAccountChangeSynchronizer
which compares the polling query it currently uses to a prospective new query using theSTATUS
column. After running for a week or so, we verified that the business logic aroundSTATUS
is correct.In this PR, we switch the
BillingAccountChangeSynchronizer
away from the current expensive polling query to the new optimized query using theSTATUS
column.As a bonus, this PR also changes the
BillingAccountChangeSynchronizer
from running at a fixed rate via startTimerAtFixedRate to running at a fixed delay via startTimerWithFixedDelay. Instead of running every N seconds, we'll now wait N seconds between runs. The difference is that the former does not take into account how long the task runs, while the latter does.PR checklist
model/
, then you should publish a new officialrawls-model
and updaterawls-model
in Orchestration's dependencies.