Skip to content

Commit

Permalink
431 - Sort array values in state cache to mitigate erroneous "state h…
Browse files Browse the repository at this point in the history
…as changed" messages and slow test startup
  • Loading branch information
tom-wozniakowski-tw committed Dec 13, 2024
1 parent bd02999 commit d6e3fb4
Showing 1 changed file with 17 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,9 @@ abstract class ComposeUp extends DefaultTask {
}
}

private static final VOLATILE_STATE_KEYS = ['RunningFor']
private static final UNSTABLE_ARRAY_STATE_KEYS = ['Mounts', 'Ports', 'Networks', 'Labels', 'Publishers']

@Internal
protected def getStateForCache() {
String processesAsString = composeExecutor.get().execute('ps', '--format', 'json')
Expand All @@ -224,8 +227,8 @@ abstract class ComposeUp extends DefaultTask {
List<Object> transformed = processes.collect {
// Status field contains something like "Up 8 seconds", so we have to strip the duration.
if (it.containsKey('Status') && it.Status.startsWith('Up ')) it.Status = 'Up'
it.remove('RunningFor') // It also contains a duration information.
it.remove('Labels') // The order of labels is not stable.
VOLATILE_STATE_KEYS.each { key -> it.remove(key) }
UNSTABLE_ARRAY_STATE_KEYS.each { key -> it[key] = parseAndSortStateArray(it[key]) }
it
}
processesState = transformed.join('\t')
Expand All @@ -235,6 +238,18 @@ abstract class ComposeUp extends DefaultTask {
processesState + composeExecutor.get().execute('config') + startedServices.get().join(',')
}

protected Object parseAndSortStateArray(Object list) {
if (list instanceof List) {
//Already provided as a List, no pre-parsing needed
return list.sort { (first, second) -> first.toString() <=> second.toString() }
} else if (list instanceof String && list.contains(",")) {
//Not already a list, but a comma separated string
return list.split(',').collect { it.trim() }.sort()
} else {
return list
}
}

protected Iterable<ServiceInfo> loadServicesInfo(Iterable<String> servicesNames) {
// this code is little bit complicated - the aim is to execute `docker inspect` just once (for all the containers)
Map<String, Iterable<String>> serviceToContainersIds = composeExecutor.get().getContainerIds(servicesNames)
Expand Down

0 comments on commit d6e3fb4

Please sign in to comment.