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

feat(plugin): Add new task-batching plugin. #495

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

DrRebus
Copy link
Contributor

@DrRebus DrRebus commented Nov 30, 2023

  • What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
    A new feature: a task batching plugin.

  • What is the current behavior? (You can also link to an open issue here)
    The only way of batching tasks so far is to use a subtask plugin with the foreach feature, which dynamically adds a new step per subtask. This approach isn't efficient DB-wise, because everytime a step is updated, the whole step tree (a JSON formatted string) gets updated, triggering an UPDATE in the database. These UPDATEs create new bigger-and-bigger rows and delete the previous ones, bloating the DB and requiring a stronger VACUUM.

  • What is the new behavior (if this is a feature change)?
    The task-batching plugin spawns child tasks as independent tasks that wake the parent once completed. Since the parent task no longer embed its children, no hard link exists between them, but they're linked via:

  • the ParentTaskID tag, the public ID of the parent task, allowing the child to wake its parent.
  • the BatchID property, the public ID of the batch the task belongs two.
  • Does this PR introduce a breaking change? (What changes might users need to make in their application due to this PR?)
    Nope.

  • Other information:
    This plugin doesn't yet aggregate results of the children tasks. It'll come in a subsequent version.
    Contrary to what's been discussed, when using sub batches (sub_batch_size > 0), children tasks don't always wake their parent when they're done. Instead, the last task in the sub batch will wake the parent. That way, we limit even more the amount of UPDATEs made. The downside is that we have to wait for the whole sub batch to be done before spawning more tasks in the batch.

@DrRebus DrRebus changed the title feat(plugin): Added new task-batching plugin. feat(plugin): Add new task-batching plugin. Nov 30, 2023
@DrRebus DrRebus force-pushed the dev/rtordjma/task-batch-plugin branch 2 times, most recently from d7f70c1 to 9b076b1 Compare December 6, 2023 09:34
@DrRebus DrRebus force-pushed the dev/rtordjma/task-batch-plugin branch from fa28ad3 to 08c3af2 Compare December 12, 2023 16:49
@@ -524,7 +525,8 @@ forLoop:
if mapStatus[status] {
if status == resolution.StateWaiting && recheckWaiting {
for name, s := range res.Steps {
if s.State == step.StateWaiting {
// Steps using the batch plugin shouldn't be run again when WAITING
if s.State == step.StateWaiting && s.Action.Type != pluginbatch.Plugin.PluginName() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure why steps are run once again when they reach the WAITING state, but it creates a race condition with the batch plugin. If the last task of the a sub-batch tries to resume its parent, but said parent is being run a second time by the engine, preventing the child task from resuming it.

Added a task-batching plugin that creates X tasks of the same template and waits until all of them are in a final state.
Moved batch-creation code to the engine package and made the POST batch handler use it.
Exposed final tasks' states to be used by the batch plugin.

Signed-off-by: Ruben Tordjman <ruben.tordjman.ext@ovhcloud.com>
Signed-off-by: Ruben Tordjman <ruben.tordjman.ext@ovhcloud.com>
Signed-off-by: Ruben Tordjman <ruben.tordjman.ext@ovhcloud.com>
…when the task belongs to a batch where other tasks are still running.

Added a way of getting the amount of tasks still running in a batch (moved from the batch plugin).

Signed-off-by: Ruben Tordjman <ruben.tordjman.ext@ovhcloud.com>
Simplified output formatting.

Signed-off-by: Ruben Tordjman <ruben.tordjman.ext@ovhcloud.com>
Added a Readme.

Signed-off-by: Ruben Tordjman <ruben.tordjman.ext@ovhcloud.com>
Signed-off-by: Ruben Tordjman <ruben.tordjman.ext@ovhcloud.com>
@DrRebus DrRebus force-pushed the dev/rtordjma/task-batch-plugin branch from e980730 to ddfde5b Compare December 21, 2023 09:31
floriancazals
floriancazals previously approved these changes Dec 23, 2023
pkg/batch/batch.go Show resolved Hide resolved
pkg/plugins/builtin/batch/README.md Outdated Show resolved Hide resolved
pkg/plugins/builtin/batch/README.md Show resolved Hide resolved
pkg/plugins/builtin/batch/README.md Outdated Show resolved Hide resolved
pkg/plugins/builtin/batch/README.md Outdated Show resolved Hide resolved
pkg/plugins/builtin/batch/batch.go Outdated Show resolved Hide resolved

// increaseRunMax increases the maximum amount of runs of the resolution matching the given parentTaskID by the run
// count of the given batchStepName.
// Since child tasks wake their parent up when they're done, the resolution's RunCount gets incremented everytime. We
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// Since child tasks wake their parent up when they're done, the resolution's RunCount gets incremented everytime. We
// Since child tasks wake up their paren when they're done, the resolution's RunCount gets incremented everytime. We

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm pretty sure "waking [someone / something] up" is correct. 🙃
Though, both seem fine: https://dictionary.cambridge.org/fr/dictionnaire/anglais/wake-up

pkg/taskutils/taskutils.go Outdated Show resolved Hide resolved
query, params, err := sqlgenerator.PGsql.
Select("count (*)").
From("task t").
Join("batch b on b.id = t.id_batch").
Copy link
Contributor

Choose a reason for hiding this comment

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

id_batch should be batch_id to be coherent with the rest of the code, and it reads better.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I couldn't agree more, but id_batch is the column's name in the database, I have no power over it sadly. 🥲
https://github.com/ovh/utask/blob/master/sql/schema.sql#L44

return taskIDs, nil
}

func conjMap(common, particular map[string]interface{}) (map[string]interface{}, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

The name of this function does not clearly reflect its usage.
It does a merge/union of two map while checking that common keys are not overriden => btw, I'm skeptical of the check line 71/72. It seems legitimate to want to define a "default/common" value for all tasks, while still overriding it for some tasks, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This function used to sit elsewhere (https://github.com/ovh/utask/blob/master/api/handler/batch.go#L80), I simply moved it and kept the exact same behaviour. Changing its name (something like mergeMaps seems adequate) won't have any side effect, but I'm not sure changing its behaviour is 100% safe.
That being said, allowing each task to override the default value is a good idea and seems like a valid use case.

Increased the clarity of some variables, functions and the Readme.

Signed-off-by: Ruben Tordjman <ruben.tordjman.ext@ovhcloud.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants