Decoupling Metric Store from Worker Coordinator - #988
Conversation
Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the
✨ Finishing touches🧪 Generate unit tests (beta)
Important Action Needed: IP Allowlist UpdateIf your organization protects your Git platform with IP whitelisting, please add the new CodeRabbit IP address to your allowlist:
Failure to add the new IP will result in interrupted reviews. Comment |
Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
PR Code Analyzer ❗AI-powered 'Code-Diff-Analyzer' found issues on commit f954800.
The table above displays the top 10 most important findings. Pull Requests Author(s): Please update your Pull Request according to the report above. Repository Maintainer(s): You can Thanks. |
PR Reviewer Guide 🔍(Review updated until commit a3bf0c9)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to a3bf0c9 Explore these optional code suggestions:
Previous suggestionsSuggestions up to commit d380153
Suggestions up to commit 33c6735
Suggestions up to commit 27d93db
Suggestions up to commit 13c52a3
Suggestions up to commit ab2e077
|
Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
PR Code Analyzer ❗AI-powered 'Code-Diff-Analyzer' found issues on commit 92c7eaf.
The table above displays the top 10 most important findings. Pull Requests Author(s): Please update your Pull Request according to the report above. Repository Maintainer(s): You can Thanks. |
|
Persistent review updated to latest commit 92c7eaf |
Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
PR Code Analyzer ❗AI-powered 'Code-Diff-Analyzer' found issues on commit b6de30c.
The table above displays the top 10 most important findings. Pull Requests Author(s): Please update your Pull Request according to the report above. Repository Maintainer(s): You can Thanks. |
|
Persistent review updated to latest commit b6de30c |
Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
|
Persistent review updated to latest commit 88207f8 |
Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
PR Code Analyzer ❗AI-powered 'Code-Diff-Analyzer' found issues on commit 46613ae.
The table above displays the top 10 most important findings. Pull Requests Author(s): Please update your Pull Request according to the report above. Repository Maintainer(s): You can Thanks. |
|
Persistent review updated to latest commit 46613ae |
Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
|
Persistent review updated to latest commit e255d1a |
Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
PR Code Analyzer ❗AI-powered 'Code-Diff-Analyzer' found issues on commit 1da9aaf.
The table above displays the top 10 most important findings. Pull Requests Author(s): Please update your Pull Request according to the report above. Repository Maintainer(s): You can Thanks. |
|
Persistent review updated to latest commit 1da9aaf |
Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
|
Persistent review updated to latest commit 440f088 |
Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
| actor.coordinator.update_samples.assert_called_once_with(latest_progress_per_client) | ||
|
|
||
| def test_worker_coordinator_updates_latest_progress_per_client(self): | ||
| coordinator = worker_coordinator.WorkerCoordinator.__new__(worker_coordinator.WorkerCoordinator) |
There was a problem hiding this comment.
I would prefer if the tests followed the existing pattern for how coordinators are initialized.
Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
| if msg.joinpoint_reached: | ||
| self.post_process_samples() | ||
| self.logger.debug("Join point reached message received in SamplePostProcessorActor. Notifying WorkerCoordinatorActor...") | ||
| self.send(self.worker_coordinator_actor, msg.joinpoint_reached) |
There was a problem hiding this comment.
just to be safe can we wrap this in a try/finally just to make sure the benchmark never hangs and this actor always sends the joinpoint reached message?
| self.target.send(self.target.sample_post_processor_actor, | ||
| GetExternalizableMetricsStore(True, | ||
| reason=ReasonForExternalizableRequest.TASK_FINISHED, waiting_period=waiting_period) | ||
| ) |
There was a problem hiding this comment.
There is a race condition here because the workers are being reactivated while the metric store results are in the process of being sent to the parent actor of worker_coordinator. This would mean that ProcessSample messages could be sent to the SPP actor while thematic store results are still being externalized.
…ore metric store is externalized. Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
|
The reason for these design choices are to further separate the different reasons for sending an externalized metric store and separating the join point forwarding logic instead of having it embedded within the ProcessSamples logic. The new method Additionally, try/catch blocks around Let me know if these changes are sufficient. I still have to clean up the logging statements. |
| if hasattr(self, "sample_post_processor_actor"): | ||
| self.logger.info("Shutting down SamplePostProcessorActor due to benchmark cancellation.") | ||
| self.send(self.sample_post_processor_actor, thespian.actors.ActorExitRequest()) | ||
| # shut down FeedbackActor if it's active | ||
| # we do this manually in the workercoordinator since it's fully responsible for the feedback actor | ||
| if hasattr(self, "feedback_actor"): |
There was a problem hiding this comment.
the two hasattr checks here are essentially no-ops since sample_post_processor_actor is set to None above. Easiest fix would be to say:
if hasattr(self, "sample_post_processor_actor") is not None:There was a problem hiding this comment.
Edit: my suggested fix would actually still be a no-op since hasattr(self, "sample_post_processor_actor") would return True and True is not None would be the same thing. Try this instead:
if self.sample_post_processor_actor is not None:| @actor.no_retry("worker_coordinator") # pylint: disable=no-value-for-parameter | ||
| def receiveMsg_TaskFinished(self, msg, sender): | ||
| self.on_task_finished(msg.metrics, msg.next_task_scheduled_in) |
There was a problem hiding this comment.
seems like this is now dead code and can be removed
| @actor.no_retry("worker_coordinator") # pylint: disable=no-value-for-parameter | ||
| def receiveMsg_TaskBoundaryFlushed(self, msg, sender): | ||
| self.on_task_finished(msg.metrics, msg.next_task_scheduled_in) | ||
| self.coordinator.drive_workers_for_next_task(msg.workers_curr_step, msg.next_task_scheduled_in) |
There was a problem hiding this comment.
I think it's a good idea here to add a guard incase the benchmark is aborted
There was a problem hiding this comment.
For this, I added a status variable to denote when the worker coordinator is exiting.
| if self.closed: | ||
| self.logger.debug("Ignoring task-boundary flush after SamplePostProcessorActor has closed.") | ||
| self.send(self.worker_coordinator_actor, TaskBoundaryFlushed(metric_results, msg.waiting_period, msg.workers_curr_step)) |
There was a problem hiding this comment.
if self.closed here let's just emit the debug log and not send anything
| except BaseException as e: | ||
| self.logger.exception("Could not flush samples at task boundary.") | ||
| self.send(self.worker_coordinator_actor, actor.BenchmarkFailure("Error in sample post processor ({})".format(str(e)))) | ||
| finally: | ||
| self.send(self.worker_coordinator_actor, TaskBoundaryFlushed(metric_results, msg.waiting_period, msg.workers_curr_step)) |
There was a problem hiding this comment.
I think here in the event of an Exception we would send a failure but then proceed to send TaskBoundaryFlushed. This could lead to the workers being re-driven after declaring a failure
| except BaseException as e: | ||
| self.logger.exception("Could not flush and close samples at benchmark completion.") | ||
| self.send(self.worker_coordinator_actor, actor.BenchmarkFailure("Error in sample post processor ({})".format(str(e)))) | ||
| self.close(process_samples=False, stop_telemetry=False, suppress_errors=True) | ||
| finally: | ||
| self.send(self.worker_coordinator_actor, BenchmarkComplete(metric_results)) |
There was a problem hiding this comment.
Same as my previous comment about double sending, here the orchestrator would see BenchmarkFailure but then BenchmarkComplete which I think could lead to confusion.
Let's only send TaskBoundaryFlushed or BenchmarkComplete messages on the success path
|
once you rebase the unit tests failures about |
|
Persistent review updated to latest commit ab2e077 |
Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
|
Persistent review updated to latest commit 13c52a3 |
Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
|
Persistent review updated to latest commit 27d93db |
|
Persistent review updated to latest commit 33c6735 |
|
Persistent review updated to latest commit d380153 |
OVI3D0
left a comment
There was a problem hiding this comment.
This LGTM and will be included with OSB's 3.0 release.
Signed-off-by: Anthony Leong <aj.leong623@gmail.com>
|
Persistent review updated to latest commit a3bf0c9 |
|
I think the last merge conflict came from registering the new telemetry device in #1102. I resolved it by making sure that the new device is registered in the updated prepare_telemetry location (That method was moved by this change). |
Description
There is a new actor called
SamplePostProcessorActor. However theSamplePostProcessorActoracts as an actor for processing samples directly from theWorkeractors as well as any task involving the metrics store. 'SamplePostProcessorActorinitialization:The new actor is initialized in the coordinator. This happens in the
prepare_benchmarkmethod. TheSamplePostProcessorActoris initialized after receiving theStartSamplePostProcessorActormessage which has the configurations for creating the metrics store, the metrics sample and profile sample post processor objects, and the telemetry collectors.StartTelemetryandStopTelemetrymessages are now used to start and stop the telemetry collection threads through the coordinatorWhich methods were changed:
send_samples: In the worker class, instead of just sending samples to the coordinator, aProcessSamplesmessage is sent to the newSamplePostProcessorActorwhich is then sent to theSamplePostprocessorinstance inside of theSamplePostProcessorActor.to_externalizable: In the metric store, theto_externalizablemethod is used to send the results of running the workload to the coordinator. We will now need to call the method through theSamplePostProcessorActorand theGetExternalizableMetricsStoremessage.close: When the coordinator is closed, the messageCloseMetricsStorewill now be used to signal to the new actor to close the metrics store.reset_relative_time: TheResetRelativeTimeRequestmessage will now be used instead to reset the relative time of the metric store in the new actor.One of the concerns if with synchronization. A lot of methods involving the metrics store that were synchronous are now handled through an asynchronous message to the
SamplePostProcessorActorwhich holds the metric store.Issues Resolved
[List any issues this PR will resolve]
Testing
[Describe how this change was tested]
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.