Skip to content

Commit 3602369

Browse files
Merge branch 'BTreeSyncWaveOrderV2' of github.com:SebastienFelix/gitops-engine into BTreeSyncWaveOrderV2
2 parents 12d9d0b + 7bd1bdd commit 3602369

File tree

10 files changed

+250
-227
lines changed

10 files changed

+250
-227
lines changed

pkg/sync/common/types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const (
1313
// AnnotationSyncWave indicates which wave of the sync the resource or hook should be in
1414
AnnotationSyncWave = "argocd.argoproj.io/sync-wave"
1515
// AnnotationKeyHook contains the hook type of a resource
16-
AnnotationSyncWaveOrder = "argocd.argoproj.io/sync-wave-order"
16+
AnnotationUseBinaryTreeWaveOrdering = "argocd.argoproj.io/use-binary-tree-wave-ordering"
1717
// AnnotationKeyHook contains the hook type of a resource
1818
AnnotationKeyHook = "argocd.argoproj.io/hook"
1919
// AnnotationKeyHookDeletePolicy is the policy of deleting a hook

pkg/sync/doc.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Package implements Kubernetes resources synchronization and provides the followi
44
- resource pruning
55
- resource hooks
66
- sync waves
7-
- sync waves ordering
7+
- sync waves binary tree ordering
88
- sync options
99
1010
# Basic Syncing
@@ -76,29 +76,30 @@ that runs before all other resources. The `argocd.argoproj.io/sync-wave` annotat
7676
annotations:
7777
argocd.argoproj.io/sync-wave: "5"
7878
79-
# Sync Waves Ordering
79+
# Sync Waves Binary Tree Ordering
8080
81-
The wave ordering feature allows to run parallel waves of synchronisation where the sync-wave values correspond to a complete
82-
binary tree with root's label equal to 1. A sync-wave value X would be considered less than Y if and only if there exists
83-
integers N and M such that :
81+
The wave ordering using a binary tree feature allows to run parallel waves of synchronisation where the sync-wave values
82+
correspond to a complete binary tree with root's label equal to 1. A sync-wave value X would be considered less than Y
83+
when using binary tree ordering if and only if there exists integers N and M such that :
8484
Y = X * 2**N + M where 0 <= M < N.
8585
86-
The `argocd.argoproj.io/sync-wave-order` annotation define the type of wave's ordering used for a resource's wave:
86+
The `argocd.argoproj.io/use-binary-tree-wave-ordering` annotation define the type of wave's ordering used for a resource's wave:
8787
8888
metadata:
8989
annotations:
9090
argocd.argoproj.io/sync-wave: "5"
91-
argocd.argoproj.io/sync-wave-order: "BTree"
91+
argocd.argoproj.io/use-binary-tree-wave-ordering: "true"
9292
93-
example of sync-waves ordering using BTree:
93+
example of waves ordering using binary tree:
9494
9595
1 -----> 2 -----> 4
9696
\ \----> 5
9797
\---> 3 -----> 6
9898
\----> 7
9999
100-
Note that a resource using a BTree ordering will always be synced after all resources using a Normal ordering.
101-
Note also that all resources using a BTree ordering with a syncWave < 1 will behave like resources having a Normal ordering.
100+
Note that a resource using a binary tree ordering for sync waves will always be synced after all resources using a normal ordering.
101+
Note also that all resources using a binary tree ordering and having a sync wave value inferior to 1 will behave like resources using
102+
a normal wave ordering.
102103
103104
# Sync Options
104105

pkg/sync/sync_context.go

Lines changed: 64 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7-
"math"
87
"reflect"
98
"slices"
109
"sort"
@@ -565,9 +564,9 @@ func (sc *syncContext) Sync() {
565564

566565
// remove any tasks not in this wave
567566
phase := tasks.phase()
568-
waves, wavesOrdering := tasks.waves()
569-
lastWaves, lastWavesOrdering := tasks.lastWaves()
570-
finalWaves := phase == tasks.lastPhase() && reflect.DeepEqual(waves, lastWaves) && wavesOrdering == lastWavesOrdering
567+
waves, wavesUseBinaryTreeOrdering := tasks.waves()
568+
lastWaves, lastWavesUseBinaryTreeOrdering := tasks.lastWaves()
569+
finalWaves := phase == tasks.lastPhase() && reflect.DeepEqual(waves, lastWaves) && wavesUseBinaryTreeOrdering == lastWavesUseBinaryTreeOrdering
571570

572571
// if it is the last phase/wave and the only remaining tasks are non-hooks, the we are successful
573572
// EVEN if those objects subsequently degraded
@@ -576,7 +575,7 @@ func (sc *syncContext) Sync() {
576575

577576
sc.log.WithValues("phase", phase, "wave", waves, "tasks", tasks, "syncFailTasks", syncFailTasks).V(1).Info("Filtering tasks in correct phase and wave")
578577
tasks = tasks.Filter(func(t *syncTask) bool {
579-
return t.phase == phase && slices.Contains(waves, t.wave()) && t.waveOrdering() == wavesOrdering
578+
return t.phase == phase && slices.Contains(waves, t.wave()) && t.waveUseBinaryTreeOrdering() == wavesUseBinaryTreeOrdering
580579
})
581580

582581
sc.setOperationPhase(common.OperationRunning, "one or more tasks are running")
@@ -906,104 +905,105 @@ func (sc *syncContext) getSyncTasks() (_ syncTasks, successful bool) {
906905
}
907906

908907
// for prune tasks, modify the waves for proper cleanup i.e reverse of sync wave (creation order)
909-
// if all prune tasks have a normal syncWaveOrdering, use the legacy method. Otherwise, change the
910-
// syncWaveOrdering of all prune tasks to BTree and modify the waves to decreasing power of 2.
911-
// For prune tasks which already had a BTree syncWaveOrdering, set an identical syncWave to tasks which
908+
// if all prune tasks have a normal syncWaveUseBinaryTreeOrdering, use the legacy method. Otherwise, change the
909+
// syncWaveUseBinaryTreeOrdering of all prune tasks to BTree and modify the waves to decreasing power of 2.
910+
// For prune tasks which already had a BTree syncWaveUseBinaryTreeOrdering, set an identical syncWave to tasks which
912911
// have the same level in a complete binary tree rooted at 1 where each node n has 2*n and 2*n+1 as children.
913912

914-
normalPruneTasks := make(map[int][]*syncTask)
913+
pruntTasksUsingNormalOrdering := make(map[int][]*syncTask)
915914
for _, task := range tasks {
916-
if task.isPrune() && task.waveOrdering() == "Normal" {
917-
normalPruneTasks[task.wave()] = append(normalPruneTasks[task.wave()], task)
915+
if task.isPrune() && task.waveUseBinaryTreeOrdering() == "false" {
916+
pruntTasksUsingNormalOrdering[task.wave()] = append(pruntTasksUsingNormalOrdering[task.wave()], task)
918917
}
919918
}
920-
var uniqueNormalPruneWaves []int
921-
for k := range normalPruneTasks {
922-
uniqueNormalPruneWaves = append(uniqueNormalPruneWaves, k)
919+
var uniquePruneWavesUsingNormalOrdering []int
920+
for k := range pruntTasksUsingNormalOrdering {
921+
uniquePruneWavesUsingNormalOrdering = append(uniquePruneWavesUsingNormalOrdering, k)
923922
}
924923

925-
sort.Ints(uniqueNormalPruneWaves)
926-
bTreePruneTasks := make(map[int][]*syncTask)
924+
sort.Ints(uniquePruneWavesUsingNormalOrdering)
925+
pruneTasksUsingBinaryTreeOrdering := make(map[int][]*syncTask)
927926
for _, task := range tasks {
928-
if task.isPrune() && task.waveOrdering() == "BTree" {
929-
bTreePruneTasks[task.wave()] = append(bTreePruneTasks[task.wave()], task)
927+
if task.isPrune() && task.waveUseBinaryTreeOrdering() == "true" {
928+
pruneTasksUsingBinaryTreeOrdering[task.wave()] = append(pruneTasksUsingBinaryTreeOrdering[task.wave()], task)
930929
}
931930
}
932931

933-
if len(bTreePruneTasks) > 0 {
934-
var uniqueBTreePruneWaves []int
935-
for k := range bTreePruneTasks {
936-
uniqueBTreePruneWaves = append(uniqueBTreePruneWaves, k)
932+
if len(pruneTasksUsingBinaryTreeOrdering) > 0 {
933+
var uniquePruneWavesUsingBinaryTreeOrdering []int
934+
for k := range pruneTasksUsingBinaryTreeOrdering {
935+
uniquePruneWavesUsingBinaryTreeOrdering = append(uniquePruneWavesUsingBinaryTreeOrdering, k)
937936
}
938-
sort.Ints(uniqueBTreePruneWaves)
937+
sort.Ints(uniquePruneWavesUsingBinaryTreeOrdering)
939938

940-
pruneWaves := []int{0}
941-
for i := 1; i < len(uniqueNormalPruneWaves); i++ {
942-
pruneWaves = append(pruneWaves, i)
939+
pruneTasksWavesValues := []int{0}
940+
for i := 1; i < len(uniquePruneWavesUsingNormalOrdering); i++ {
941+
pruneTasksWavesValues = append(pruneTasksWavesValues, i)
943942
}
944-
nextPotentialWave := len(uniqueNormalPruneWaves)
945-
if len(uniqueNormalPruneWaves) != 0 {
946-
pruneWaves = append(pruneWaves, nextPotentialWave)
943+
nextPotentialWaveValue := len(uniquePruneWavesUsingNormalOrdering)
944+
if len(uniquePruneWavesUsingNormalOrdering) != 0 {
945+
pruneTasksWavesValues = append(pruneTasksWavesValues, nextPotentialWaveValue)
947946
}
948-
for i := 1; i < len(uniqueBTreePruneWaves); i++ {
949-
currentBTreeWaveLevel := biggestPowerOf2InferiorThan(uniqueBTreePruneWaves[i])
950-
previousBTreeWaveLevel := biggestPowerOf2InferiorThan(uniqueBTreePruneWaves[i-1])
947+
for i := 1; i < len(uniquePruneWavesUsingBinaryTreeOrdering); i++ {
948+
currentBTreeWaveLevel := biggestPowerOf2InferiorThan(uniquePruneWavesUsingBinaryTreeOrdering[i])
949+
previousBTreeWaveLevel := biggestPowerOf2InferiorThan(uniquePruneWavesUsingBinaryTreeOrdering[i-1])
951950
if currentBTreeWaveLevel == previousBTreeWaveLevel {
952-
pruneWaves = append(pruneWaves, nextPotentialWave)
951+
pruneTasksWavesValues = append(pruneTasksWavesValues, nextPotentialWaveValue)
953952
} else {
954-
nextPotentialWave++
955-
pruneWaves = append(pruneWaves, nextPotentialWave)
953+
nextPotentialWaveValue++
954+
pruneTasksWavesValues = append(pruneTasksWavesValues, nextPotentialWaveValue)
956955
}
957956
}
958957

959-
bTreeWave := int(math.Pow(2, float64(pruneWaves[len(pruneWaves)-1])))
960-
newPruneWaves := []int{bTreeWave}
961-
n := len(pruneWaves)
962-
for i := 1; i < len(pruneWaves); i++ {
963-
if pruneWaves[n-i-1] == pruneWaves[n-i] {
964-
newPruneWaves = append(newPruneWaves, bTreeWave)
958+
pruneTasksWavesNewValues := PowInt(2, pruneTasksWavesValues[len(pruneTasksWavesValues)-1])
959+
newPruneWaves := []int{pruneTasksWavesNewValues}
960+
n := len(pruneTasksWavesValues)
961+
for i := 1; i < len(pruneTasksWavesValues); i++ {
962+
if pruneTasksWavesValues[n-i-1] == pruneTasksWavesValues[n-i] {
963+
newPruneWaves = append(newPruneWaves, pruneTasksWavesNewValues)
965964
} else {
966-
bTreeWave = bTreeWave / 2
967-
newPruneWaves = append(newPruneWaves, bTreeWave)
965+
pruneTasksWavesNewValues /= 2
966+
newPruneWaves = append(newPruneWaves, pruneTasksWavesNewValues)
968967
}
969968
}
970969

971-
bTreeWaveOrdering := "BTree"
970+
bTreeWaveUseBinaryTreeOrdering := "true"
972971

973-
for i := 0; i < len(uniqueNormalPruneWaves); i++ {
972+
for i := range uniquePruneWavesUsingNormalOrdering {
974973
// Normal waves to reorder
975-
iWave := uniqueNormalPruneWaves[i]
974+
iWave := uniquePruneWavesUsingNormalOrdering[i]
976975

977-
for _, task := range normalPruneTasks[iWave] {
976+
for _, task := range pruntTasksUsingNormalOrdering[iWave] {
978977
task.waveOverride = &newPruneWaves[i]
979-
task.waveOrderingOverride = &bTreeWaveOrdering
978+
task.waveUseBinaryTreeOrderingOverride = &bTreeWaveUseBinaryTreeOrdering
980979
}
981980
}
982981

983-
for i := len(uniqueNormalPruneWaves); i < len(uniqueNormalPruneWaves)+len(uniqueBTreePruneWaves); i++ {
982+
n = len(uniquePruneWavesUsingNormalOrdering)
983+
for i := range uniquePruneWavesUsingBinaryTreeOrdering {
984984
// BTree waves to reorder
985-
iWave := uniqueBTreePruneWaves[i-len(uniqueNormalPruneWaves)]
985+
iWave := uniquePruneWavesUsingBinaryTreeOrdering[i]
986986

987-
for _, task := range bTreePruneTasks[iWave] {
988-
task.waveOverride = &(newPruneWaves[i])
989-
task.waveOrderingOverride = &bTreeWaveOrdering
987+
for _, task := range pruneTasksUsingBinaryTreeOrdering[iWave] {
988+
task.waveOverride = &(newPruneWaves[n+i])
989+
task.waveUseBinaryTreeOrderingOverride = &bTreeWaveUseBinaryTreeOrdering
990990
}
991991
}
992992

993993
} else {
994994

995995
// reorder waves for pruning tasks using symmetric swap on prune waves
996-
n := len(uniqueNormalPruneWaves)
996+
n := len(uniquePruneWavesUsingNormalOrdering)
997997
for i := 0; i < n/2; i++ {
998998
// waves to swap
999-
startWave := uniqueNormalPruneWaves[i]
1000-
endWave := uniqueNormalPruneWaves[n-1-i]
999+
startWave := uniquePruneWavesUsingNormalOrdering[i]
1000+
endWave := uniquePruneWavesUsingNormalOrdering[n-1-i]
10011001

1002-
for _, task := range normalPruneTasks[startWave] {
1002+
for _, task := range pruntTasksUsingNormalOrdering[startWave] {
10031003
task.waveOverride = &endWave
10041004
}
10051005

1006-
for _, task := range normalPruneTasks[endWave] {
1006+
for _, task := range pruntTasksUsingNormalOrdering[endWave] {
10071007
task.waveOverride = &startWave
10081008
}
10091009
}
@@ -1012,28 +1012,28 @@ func (sc *syncContext) getSyncTasks() (_ syncTasks, successful bool) {
10121012
// for pruneLast tasks, modify the wave to sync phase last wave of tasks + 1
10131013
// to ensure proper cleanup, syncPhaseLastWave should also consider prune tasks to determine last wave
10141014
syncPhaseLastWave := 0
1015-
syncPhaseLastWaveOrdering := "Normal"
1015+
syncPhaseLastWaveUseBinaryTreeOrdering := "false"
10161016
for _, task := range tasks {
10171017
if task.phase == common.SyncPhaseSync {
10181018
if task.wave() > syncPhaseLastWave {
10191019
syncPhaseLastWave = task.wave()
1020-
syncPhaseLastWaveOrdering = task.waveOrdering()
1020+
syncPhaseLastWaveUseBinaryTreeOrdering = task.waveUseBinaryTreeOrdering()
10211021
}
10221022
}
10231023
}
10241024

10251025
// if prune tasks contain BTree ordering syncWaves, then set the tasks with PruneLast
1026-
if syncPhaseLastWaveOrdering == "Normal" {
1027-
syncPhaseLastWave = syncPhaseLastWave + 1
1026+
if syncPhaseLastWaveUseBinaryTreeOrdering == "false" {
1027+
syncPhaseLastWave += 1
10281028
} else {
1029-
syncPhaseLastWave = syncPhaseLastWave * 2
1029+
syncPhaseLastWave *= 2
10301030
}
10311031

10321032
for _, task := range tasks {
10331033
if task.isPrune() &&
10341034
(sc.pruneLast || resourceutil.HasAnnotationOption(task.liveObj, common.AnnotationSyncOptions, common.SyncOptionPruneLast)) {
10351035
task.waveOverride = &syncPhaseLastWave
1036-
task.waveOrderingOverride = &syncPhaseLastWaveOrdering
1036+
task.waveUseBinaryTreeOrderingOverride = &syncPhaseLastWaveUseBinaryTreeOrdering
10371037
}
10381038
}
10391039

0 commit comments

Comments
 (0)