-
Notifications
You must be signed in to change notification settings - Fork 296
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
[Proposal] Adding control-queue monitor with dedicated orchestrator to each control-queue. #1058
base: main
Are you sure you want to change the base?
Conversation
/// <summary> | ||
/// | ||
/// </summary> | ||
public class FileWriter |
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 will be removed and structed logging will be added.
Hi @pasaini-microsoft: Thanks for opening this PR. As we discussed internally, I'll loop in the other DTFx/DF maintainers for discussion regarding the scope of the PR, as well as the design. I'm personally most excited about the ability to create an instanceID targetting a specific partition, so at the very least I'd like to get that in. It would help greatly if you could update the PR description to contain not just a list of the changes, but also a small motivation and background behind this change. For example, you can explain that you're using this utility in your own app to help you detect stuck orchestrations, and so on. Thanks! |
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.
Finished a partial pass. Please see my comment here for my thoughts on how I'd like to move this forward: #1058 (review)
/// Time interval between control queue heartbeat orchestration. | ||
/// </summary> | ||
public TimeSpan ControlQueueHearbeatOrchestrationInterval { get; set; } = DefaultControlQueueHearbeatOrchestrationInterval; | ||
|
||
/// <summary> | ||
/// Time interval between control queue heartbeat orchestration. | ||
/// </summary> | ||
public TimeSpan ControlQueueOrchHeartbeatDetectionInterval { get; set; } = DefaultControlQueueOrchHeartbeatDetectionInterval; | ||
|
||
/// <summary> | ||
/// Time interval between control queue heartbeat orchestration. | ||
/// </summary> | ||
public TimeSpan ControlQueueOrchHeartbeatDetectionThreshold { get; set; } = DefaultControlQueueOrchHeartbeatDetectionThreshold; | ||
|
||
/// <summary> |
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.
why do these all have the same description?
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.
updated.
/// <summary> | ||
/// The orchestration instance for control-queue is stuck. | ||
/// </summary> | ||
OrchestrationInstanceStuck, |
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.
nit - a note for myself. I'd rather not include the word "stuck" in these states, because a heartbeat cannot definitely conclude that the orchestration is stuck: the problem could be something else. I'm not sure what the right term should be though, so I'll follow up on this thread later with some suggestions.
InvalidInput, | ||
InputContextMismatch |
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.
Can you please tell me a bit more about how would enters these states?
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.
added comments.
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.
usually it happens if someone updates the partition-count.
// Ensuring this section doesn't run again. | ||
// This queues the user provided callback without waiting for it to finish. | ||
// This is to keep heartbeat orchestrator thin and fast. | ||
if (!context.IsReplaying) | ||
{ | ||
// No wait to complete provided delegate. The current orchestrator need to be very thin and quick to run. | ||
bool isQueued = ThreadPool.QueueUserWorkItem(async (_) => | ||
{ | ||
await this.callBack(context.OrchestrationInstance, controlQueueHeartbeatTaskContextInput, controlQueueHeartbeatTaskContextInit, this.cancellationTokenSrc.Token); | ||
}); | ||
} |
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.
I realize this was on @cgillum's suggestion, but I still think it's worth calling out in a comment where why we're not following the DF orchestrator coding constraints of not having threading in orchestrators.
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.
updated.
/// <summary> | ||
/// Control-queue heartbeat orchestrator. | ||
/// This is supposed to be initialized with ControlQueueHeartbeatTaskContext informing orchestrator about configuration of taskhubworker and heartbeat interval. | ||
/// </summary> | ||
internal class ControlQueueHeartbeatTaskOrchestrator : TaskOrchestration<ControlQueueHeartbeatTaskResult, ControlQueueHeartbeatTaskInputContext> | ||
{ | ||
public const string OrchestrationName = "ControlQueueHeartbeatTaskOrchestrator"; | ||
|
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.
Given that this orchestrator is rather simple to write, my intuition is that customers wouldn't mind writing these themselves so long as they have the right utilities to let them schedule it every partition.
With that in mind, my recommendation would be to make this orchestrator part of our samples, and to instead prioritize merging the work done to help users schedule an orchestrator in a given partitionID. I think this latter utility function (create an instanceID that is guaranteed to land on a given partition ID) has value beyond this queue-monitoring scenario, so it's easier to justify building that into the framework. Ideally, it would also be less code to maintain as well :-)
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 reason for keeping it with the DurableTask.AzureStorage was:
- Not giving user the choice of choosing their orchestrators as they might have gaps like when to continue as new vs complete.
- The instance-ids are dedicated in such a way it helps reverse engineer the control-queue and instance id to identify which control-queue is stuck.
- The owner-id is information is not publicly available which is required for detection.
Though it is possible to allow orchestration of arbitrary type or as just samples, but it will increase the possibility of false positives if user creates faulty orchestrators.
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.
I agree with @davidmrdavid here. Focusing this work to just a feature of manual control of what partition an orchestration goes to is something I am open to accepting.
As for the heartbeat orchestration, I'd have to think more on if we even want it as a sample. Even in samples we could have issues opened on us regarding it. Is that something we want to take ownership of? Or could you host the sample yourself on github? Or even package it up into your own nuget?
I love the idea of monitoring partition queue processing, but I don't think via an orchestration is the right way to do this. This is a health check after all, and there is a health check ecosystem in .NET. We should evaluate leveraging that. Metrics (#785) may also be a good avenue for this feature. https://www.nuget.org/packages/Microsoft.Extensions.Diagnostics.HealthChecks/9.0.0-preview.2.24128.4 |
Thanks jviau. The reason for using orchestration was to keep the detection as independent from control-queue processing system as possible. This helps detect if control-queue is stuck for any reason including if taskhubworker is just absent or some control-queue just missed to be owned by any worker. |
Motivation:
Issue: Unpredictable time to detect (TTD) for any orchestration being stuck in control-queue.
Motivation: motivation was to reduce the TTD for finding if orchestration can be stuck/waiting-forever in a control-queue irrespective of the cause.
Issue: Manual efforts in identifying the impacted worker and mitigation steps.
Motivation: motivation was to make detection of impacted worker and perform mitigation steps automatically.
Proposals:
Adding control-queue monitor with dedicated orchestrator to each control-queue.
This change consists of 2 main portions: