Skip to content
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

Add a task scheduler for background indexing and preparation #1208

Merged
merged 1 commit into from May 2, 2024

Conversation

ahoppen
Copy link
Collaborator

@ahoppen ahoppen commented Apr 26, 2024

The scheduler isn’t actually being used yet but it’s complex and generic enough that it’s possible to review it by itself.

@ahoppen
Copy link
Collaborator Author

ahoppen commented Apr 26, 2024

@swift-ci Please test

case suspendDependency(TaskDescription)
}

public protocol TaskDescriptionProtocol: Identifiable, Sendable, CustomLogStringConvertible {
Copy link
Member

@ktoso ktoso May 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd love for you to file an issue on https://github.com/apple/swift so we can enable making such a thing as TaskExecutor, rather than having to resort to trickery and unstructured tasks like this. I believe we could allow such things but today are missing pieces in the custom executors infra I think -- like querying a job for its details etc, like priority, maybe some hooks to know a job "finished" etc.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed apple/swift#73372. It’s a little vague, feel free to refine it with the things that you actually think are relevant and doable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's good, thank you -- I'll fill in the bits, and we'll figure out what is actionable :)

///
/// Suspension might not do anything if the task has already finished, ie. even though `suspend` was called, the
/// task might still
func suspend() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider renaming the entire "suspend" wording in here; suspending is "step 1 ... ... step 2" and implies that we'll come back to a task, but this isn't that; it is "cancel and run again", like a re-schedule maybe

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. Changed to cancelToBeRescheduled.

logger.debug(
"Elevating priority of \(self.description.forLogging) from \(self.priority.rawValue) to \(targetPriority.rawValue)"
)
Task.detached(priority: targetPriority) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably doesn't need to detach -- plain task with priority should be fine -- and get task locals copied then

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I remember dispatch behavior this will not necessarily be 100% reliable... even if you passed highest priority it may decide to use lower I think... but the general idea is okey I suppose.

Please file an issue about an API for __priorityBoost(task, priority) even if underscored I think we should offer this API.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@ktoso ktoso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I don't have big concerns here, let's start with that and see how it works out in practice. I'm going to give it another proper read though, and we can keep polishing if we find anything.

self.suspendableTaskCreatedContinuation = suspendableTaskCreatedContinuation

self.resultTask = Task.detached(priority: priority) {
await withTaskGroup(of: Void.self) { taskGroup in
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider using a discarding task group? in that the group will automatically await and since you're ignoring all failures (there's no failures) and results, the discarding group will be more efficient -- it discards tasks as soon as they complete

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t think that works because I need to cancel the first task in the task group (the one that is updating self.priority) when the second task in the task group (the one that runs tasks from executionTaskCreatedStream) finishes.

@ahoppen
Copy link
Collaborator Author

ahoppen commented May 1, 2024

@swift-ci Please test

@ahoppen
Copy link
Collaborator Author

ahoppen commented May 1, 2024

@swift-ci Please test Windows

The scheduler isn’t actually being used yet but it’s complex and generic enough that it’s possible to review it by itself.
@ahoppen
Copy link
Collaborator Author

ahoppen commented May 1, 2024

@swift-ci Please test

@ahoppen
Copy link
Collaborator Author

ahoppen commented May 1, 2024

@swift-ci Please test Windows

Copy link
Contributor

@bnbarham bnbarham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh, I was always imagining just having separate queues (and pausing when there's high priority work + not caring if there's still low priority running at the same time). But this does give us more control. May not need that much in the end, we shall see.

}
},
validate: { (recordings: [Set<TaskID>]) in
// Check that all high-priority tasks get executed before the low-priority tasks
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could be executing some high priority and low priority at the same time in the actual check (eg. 2 high -> high + low -> low + low would/should pass).

@ahoppen ahoppen merged commit bfe4e70 into apple:main May 2, 2024
3 checks passed
@ahoppen ahoppen deleted the task-scheduler branch May 2, 2024 14:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants