From 761b94e9da6c5864906f59cce0582d59f81546db Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 26 Feb 2020 14:26:39 +0100 Subject: [PATCH] #138 - Improve parallelization of issue tracker and Sagan update tasks. --- .../release/issues/IssueTrackerCommands.java | 12 ++++---- .../release/sagan/DefaultSaganClient.java | 11 +++---- .../data/release/sagan/SaganCommands.java | 5 ++-- .../data/release/sagan/SaganOperations.java | 29 +++++++++++-------- 4 files changed, 31 insertions(+), 26 deletions(-) diff --git a/release-tools/src/main/java/org/springframework/data/release/issues/IssueTrackerCommands.java b/release-tools/src/main/java/org/springframework/data/release/issues/IssueTrackerCommands.java index a2ccfae..3045775 100644 --- a/release-tools/src/main/java/org/springframework/data/release/issues/IssueTrackerCommands.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/IssueTrackerCommands.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -112,15 +112,13 @@ class IssueTrackerCommands extends TimedCommand { @CliCommand(value = "tracker create releaseversions") public void jiraCreateReleaseVersions(@CliOption(key = "", mandatory = true) TrainIteration iteration) { - iteration.forEach(this::createReleaseVersion); + run(iteration, module -> getTrackerFor(module).createReleaseVersion(module)); } @CliCommand(value = "tracker create releasetickets") public String createReleaseTickets(@CliOption(key = "", mandatory = true) TrainIteration iteration) { - iteration.stream().// - forEach(module -> getTrackerFor(module).createReleaseTicket(module)); - + run(iteration, module -> getTrackerFor(module).createReleaseTicket(module)); evict(); return releaseTickets(iteration); @@ -144,12 +142,12 @@ class IssueTrackerCommands extends TimedCommand { @CliCommand("tracker close") public void closeIteration(@CliOption(key = "", mandatory = true) TrainIteration iteration) { - iteration.forEach(module -> getTrackerFor(module).closeIteration(module)); + run(iteration, module -> getTrackerFor(module).closeIteration(module)); } @CliCommand("tracker archive") public void archiveIteration(@CliOption(key = "", mandatory = true) TrainIteration iteration) { - iteration.forEach(module -> getTrackerFor(module).archiveReleaseVersion(module)); + run(iteration, module -> getTrackerFor(module).archiveReleaseVersion(module)); } private Changelog getChangelog(ModuleIteration module) { diff --git a/release-tools/src/main/java/org/springframework/data/release/sagan/DefaultSaganClient.java b/release-tools/src/main/java/org/springframework/data/release/sagan/DefaultSaganClient.java index d028b81..875d898 100644 --- a/release-tools/src/main/java/org/springframework/data/release/sagan/DefaultSaganClient.java +++ b/release-tools/src/main/java/org/springframework/data/release/sagan/DefaultSaganClient.java @@ -33,8 +33,9 @@ import com.jayway.jsonpath.JsonPath; /** * Sagan client to interact with the Sagan instance defined through {@link SaganProperties}. - * + * * @author Oliver Gierke + * @author Mark Paluch */ @RequiredArgsConstructor @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) @@ -44,7 +45,7 @@ class DefaultSaganClient implements SaganClient { SaganProperties properties; Logger logger; - /* + /* * (non-Javadoc) * @see org.springframework.data.release.sagan.SaganClient#getProjectMetadata(org.springframework.data.release.sagan.MaintainedVersion) */ @@ -59,7 +60,7 @@ class DefaultSaganClient implements SaganClient { return operations.getForObject(resource, String.class); } - /* + /* * (non-Javadoc) * @see org.springframework.data.release.sagan.SaganClient#getProjectMetadata(org.springframework.data.release.model.Project) */ @@ -73,7 +74,7 @@ class DefaultSaganClient implements SaganClient { return operations.getForObject(resource, String.class); } - /* + /* * (non-Javadoc) * @see org.springframework.data.release.sagan.SaganClient#updateProjectMetadata(org.springframework.data.release.model.Project, java.util.List) */ @@ -93,7 +94,7 @@ class DefaultSaganClient implements SaganClient { Arrays.stream(JsonPath.compile("$..version"). read(getProjectMetadata(project)).toArray())// .map(version -> properties.getProjectMetadataResource(project, version.toString()))// .peek(uri -> logger.log(project, "Deleting existing project metadata at %s…", uri)) // - .forEach(uri -> operations.delete(uri)); + .forEach(operations::delete); logger.log(project, "Writing project metadata for versions %s!", versionsString); diff --git a/release-tools/src/main/java/org/springframework/data/release/sagan/SaganCommands.java b/release-tools/src/main/java/org/springframework/data/release/sagan/SaganCommands.java index 8feb84e..88200cb 100644 --- a/release-tools/src/main/java/org/springframework/data/release/sagan/SaganCommands.java +++ b/release-tools/src/main/java/org/springframework/data/release/sagan/SaganCommands.java @@ -31,8 +31,9 @@ import org.springframework.stereotype.Component; /** * Operations for Sagan interaction. - * + * * @author Oliver Gierke + * @author Mark Paluch */ @Component @CliComponent @@ -46,7 +47,7 @@ class SaganCommands extends TimedCommand { public void updateProjectInformation(@CliOption(key = "", mandatory = true) String trains) { sagan.updateProjectMetadata(Stream.of(trains.split(","))// - .map(train -> ReleaseTrains.getTrainByName(train)) // + .map(ReleaseTrains::getTrainByName) // .collect(Collectors.toList())); } } diff --git a/release-tools/src/main/java/org/springframework/data/release/sagan/SaganOperations.java b/release-tools/src/main/java/org/springframework/data/release/sagan/SaganOperations.java index fa2616b..147c6db 100644 --- a/release-tools/src/main/java/org/springframework/data/release/sagan/SaganOperations.java +++ b/release-tools/src/main/java/org/springframework/data/release/sagan/SaganOperations.java @@ -20,6 +20,7 @@ import lombok.RequiredArgsConstructor; import lombok.experimental.FieldDefaults; import java.util.Arrays; +import java.util.Collection; import java.util.Comparator; import java.util.List; import java.util.Map; @@ -32,12 +33,15 @@ import org.springframework.data.release.model.Project; import org.springframework.data.release.model.Projects; import org.springframework.data.release.model.Train; import org.springframework.data.release.model.Version; +import org.springframework.data.release.utils.ExecutionUtils; import org.springframework.data.release.utils.ListWrapperCollector; import org.springframework.data.release.utils.Logger; +import org.springframework.data.util.Streamable; import org.springframework.util.Assert; /** * @author Oliver Gierke + * @author Mark Paluch */ @RequiredArgsConstructor @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) @@ -66,7 +70,10 @@ class SaganOperations { Assert.notNull(trains, "Trains must not be null!"); - findVersions(trains).forEach(client::updateProjectMetadata); + Map versions = findVersions(trains); + + ExecutionUtils.run(Streamable.of(versions.entrySet()), + entry -> client.updateProjectMetadata(entry.getKey(), entry.getValue())); } /** @@ -86,13 +93,13 @@ class SaganOperations { Assert.notNull(trains, "Trains must not be null!"); - return trains.stream() // - .flatMap(train -> train.stream()// - .filter(module -> !TO_FILTER.contains(module.getProject())) // - .map(module -> getLatestVersion(module, train)) // - .flatMap(MaintainedVersion::all)) // - .collect( - Collectors.groupingBy(it -> it.getProject(), ListWrapperCollector.collectInto(MaintainedVersions::of))); + return ExecutionUtils.runAndReturn(Streamable.of(trains), train -> { + return ExecutionUtils.runAndReturn( + Streamable.of(() -> train.stream().filter(module -> !TO_FILTER.contains(module.getProject()))), module -> { + return getLatestVersion(module, train); + }); + }).stream().flatMap(Collection::stream).collect( + Collectors.groupingBy(MaintainedVersion::getProject, ListWrapperCollector.collectInto(MaintainedVersions::of))); } private MaintainedVersion getLatestVersion(Module module, Train train) { @@ -100,10 +107,8 @@ class SaganOperations { Project project = module.getProject(); MaintainedVersion version = git.getTags(project).stream()// - .filter(tag -> matches(tag, module.getVersion())) // - .sorted(Comparator.reverseOrder()) // - .findFirst() // - .flatMap(tag -> tag.toArtifactVersion()) // + .filter(tag -> matches(tag, module.getVersion())).max(Comparator.naturalOrder()) // + .flatMap(Tag::toArtifactVersion) // .map(it -> MaintainedVersion.of(module.getProject(), it, train)) // .orElseGet(() -> MaintainedVersion.snapshot(module, train));