Skip to content

Commit

Permalink
refactor(infrastructure): Update code to convert from mutiny to VThre…
Browse files Browse the repository at this point in the history
…ads (#1103)
  • Loading branch information
MartinWitt authored Sep 26, 2023
1 parent ac5db22 commit 69f2747
Show file tree
Hide file tree
Showing 13 changed files with 90 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.github.martinwitt.spoon_analyzer.SpoonAnalyzer;
import java.nio.file.Path;
import java.util.List;
import java.util.Optional;

public class SpoonBasedAnalyzer {

Expand All @@ -14,8 +15,8 @@ public List<AnalyzerResult> analyze(Path sourceRoot) {
List<BadSmell> analyze = analyzer.analyze(sourceRoot.toAbsolutePath().toString());
return analyze.stream()
.map(analyzerResultVisitor::toAnalyzerResult)
.filter(v -> v.isPresent())
.map(v -> v.get())
.filter(Optional::isPresent)
.map(Optional::get)
.toList();
}
}
1 change: 1 addition & 0 deletions github-bot/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ plugins {
}

dependencies {
implementation 'io.quarkiverse.jgit:quarkus-jgit:3.0.5'
implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
implementation 'io.quarkiverse.githubapi:quarkus-github-api:1.316.0'
implementation 'io.quarkiverse.githubapp:quarkus-github-app:2.1.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import io.github.martinwitt.laughing_train.persistence.repository.ProjectRepository;
import io.github.martinwitt.laughing_train.summary.GetFixableBadSmells;
import io.github.martinwitt.spoon_analyzer.badsmells.SpoonRules;
import io.smallrye.common.annotation.RunOnVirtualThread;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Inject;
import java.util.Arrays;
Expand All @@ -18,6 +19,7 @@

@GraphQLApi
@RequestScoped
@RunOnVirtualThread
public class BadSmellGraphQL {

@Inject BadSmellRepository badSmellRepository;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import io.github.martinwitt.laughing_train.persistence.repository.ProjectRepository;
import io.github.martinwitt.laughing_train.services.ProjectConfigService;
import io.quarkus.security.Authenticated;
import io.vertx.core.Vertx;
import io.smallrye.common.annotation.RunOnVirtualThread;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Inject;
import java.util.List;
Expand All @@ -24,12 +24,11 @@

@GraphQLApi
@RequestScoped
@RunOnVirtualThread
public class ProjectGraphQL {

private static final FluentLogger logger = FluentLogger.forEnclosingClass();

@Inject Vertx vertx;

@Inject ProjectConfigService projectConfigService;

@Inject ProjectRepository projectRepository;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import io.github.martinwitt.laughing_train.persistence.repository.BadSmellRepository;
import io.github.martinwitt.laughing_train.services.RefactorService;
import io.quarkus.security.Authenticated;
import io.smallrye.common.annotation.RunOnVirtualThread;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Inject;
import java.util.Arrays;
Expand All @@ -22,6 +23,7 @@

@GraphQLApi
@RequestScoped
@RunOnVirtualThread
public class RefactorGraphQL {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import java.io.Serializable;

public sealed interface ProjectResult extends Serializable {
public sealed interface ProjectResult extends Serializable
permits ProjectResult.Success, ProjectResult.Error {

record Success(Project project) implements ProjectResult {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
import java.io.Serializable;
import java.util.List;

public interface CodeAnalyzerResult extends Serializable {
public sealed interface CodeAnalyzerResult extends Serializable
permits CodeAnalyzerResult.Success, CodeAnalyzerResult.Failure {

record Success(List<AnalyzerResult> results, Project project) implements CodeAnalyzerResult {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@ void supplyProject(Message<GetProject> getProject) {
}
}

public ProjectResult supplyProject() {
try {
RemoteProject project = getRandomProject();
ProjectResult checkoutProject = checkoutProject(project);
Log.info("Project %s checked out".formatted(project.getProjectUrl()));
return checkoutProject;
} catch (IOException e) {
return new ProjectResult.Error(e.getMessage());
}
}

private ProjectResult checkoutProject(RemoteProject project) throws IOException {
return projectService.handleProjectRequest(new ProjectRequest.WithUrl(project.getProjectUrl()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,18 @@
import io.github.martinwitt.laughing_train.data.ProjectResult.Success;
import io.github.martinwitt.laughing_train.data.request.AnalyzerRequest;
import io.github.martinwitt.laughing_train.data.result.CodeAnalyzerResult;
import io.github.martinwitt.laughing_train.mining.requests.GetProject;
import io.github.martinwitt.laughing_train.mining.requests.MineNextProject;
import io.github.martinwitt.laughing_train.mining.requests.StoreResults;
import io.github.martinwitt.laughing_train.services.SpoonAnalyzerService;
import io.quarkus.arc.Unremovable;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;
import io.vertx.core.Vertx;
import io.vertx.core.eventbus.DeliveryOptions;
import io.vertx.core.eventbus.Message;
import jakarta.enterprise.context.ApplicationScoped;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import org.apache.commons.io.FileUtils;

@Unremovable
Expand All @@ -28,10 +27,13 @@ public class SpoonPeriodicMiner extends AbstractVerticle {
public static final String ANALYZER_NAME = "spoon-analyzer";
final Vertx vertx;
final SpoonAnalyzerService spoonAnalyzerService;
final ProjectSupplier projectSupplier;

public SpoonPeriodicMiner(Vertx vertx, SpoonAnalyzerService spoonAnalyzerService) {
public SpoonPeriodicMiner(
Vertx vertx, SpoonAnalyzerService spoonAnalyzerService, ProjectSupplier projectSupplier) {
this.vertx = vertx;
this.spoonAnalyzerService = spoonAnalyzerService;
this.projectSupplier = projectSupplier;
}

private CodeAnalyzerResult analyzeProjectWithSpoon(Success success) {
Expand Down Expand Up @@ -60,34 +62,26 @@ void mineWithSpoon(MineNextProject event) {
return;
}
logger.atInfo().log("Start mining with spoon");
Future<Message<ProjectResult>> request =
vertx
.eventBus()
.request(
ProjectSupplier.SERVICE_NAME,
new GetProject(ANALYZER_NAME),
new DeliveryOptions().setSendTimeout(TimeUnit.MINUTES.toMillis(5)));
request
.onSuccess(
v -> {
if (v.body() instanceof ProjectResult.Success success) {
var spoonResult = analyzeProjectWithSpoon(success);
if (spoonResult instanceof CodeAnalyzerResult.Success spoonSuccess) {
storeSuccess(success, spoonSuccess);
} else {
if (spoonResult instanceof CodeAnalyzerResult.Failure error) {
storeFailure(success, error);
}
}
FileUtils.deleteQuietly(success.project().folder());
}
})
.onComplete(v -> vertx.eventBus().publish("miner", new MineNextProject(ANALYZER_NAME)));
request.onFailure(
v -> {
logger.atWarning().withCause(v).log("Failed to get project");
vertx.eventBus().publish("miner", new MineNextProject(ANALYZER_NAME));
});
ProjectResult projectResult = projectSupplier.supplyProject();
switch (projectResult) {
case Success success -> {
CodeAnalyzerResult analyzerResult = analyzeProjectWithSpoon(success);
switch (analyzerResult) {
case CodeAnalyzerResult.Success spoonSuccess -> storeSuccess(success, spoonSuccess);
case CodeAnalyzerResult.Failure error -> storeFailure(success, error);
}
try (var dirStream = Files.walk(success.project().folder().toPath())) {
dirStream.map(Path::toFile).sorted(Comparator.reverseOrder()).forEach(File::delete);
} catch (IOException e) {
logger.atWarning().log("Failed to delete project " + success.project().folder());
}
FileUtils.deleteQuietly(success.project().folder());
}
case ProjectResult.Error error -> {
logger.atWarning().log("Failed to get project %s", error.message());
}
}
vertx.eventBus().publish("miner", new MineNextProject(ANALYZER_NAME));
}

private void storeFailure(ProjectResult.Success success, CodeAnalyzerResult.Failure error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,26 +37,14 @@ void persistResults(QodanaResult result) {
}
}

void persistResults(CodeAnalyzerResult result) {
if (result instanceof CodeAnalyzerResult.Success success) {
logger.atInfo().log(
"Persisting %s results for project %s",
success.results().size(), success.project().name());
Project project = success.project();
Multi.createFrom()
.iterable(success.results())
.map(
badSmell ->
new BadSmell(badSmell, project.name(), project.url(), project.commitHash()))
.filter(v -> badSmellRepository.findByIdentifier(v.getIdentifier()).isEmpty())
.map(badSmellRepository::save)
.collect()
.with(Collectors.counting())
.subscribe()
.with(
badSmell ->
logger.atInfo().log(
"Persisted %d bad smells for project %s", badSmell, project.name()));
}
void persistResults(CodeAnalyzerResult.Success success) {
logger.atInfo().log(
"Persisting %s results for project %s", success.results().size(), success.project().name());
Project project = success.project();
success.results().stream()
.map(
badSmell -> new BadSmell(badSmell, project.name(), project.url(), project.commitHash()))
.filter(it -> badSmellRepository.findByIdentifier(it.getIdentifier()).isEmpty())
.forEach(badSmellRepository::save);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,26 @@ public class SpoonAnalyzerService {
public CodeAnalyzerResult analyze(AnalyzerRequest request) {
logger.atInfo().log("Received request %s", request);
try {
if (request instanceof AnalyzerRequest.WithProject project) {
File folder = project.project().folder();
SpoonBasedAnalyzer analyzer = new SpoonBasedAnalyzer();
List<AnalyzerResult> analyze = analyzer.analyze(folder.toPath());
logger.atInfo().log(
"Spoon found %s results with the following rules: %s",
analyze.size(),
analyze.stream()
.map(v -> v.ruleID().toString())
.distinct()
.collect(Collectors.joining(",")));
CodeAnalyzerResult.Success success =
new CodeAnalyzerResult.Success(analyze, project.project());
analyzerResultPersistenceService.persistResults(success);
return success;
} else {
return new CodeAnalyzerResult.Failure("Unknown request type");
switch (request) {
case AnalyzerRequest.WithProject project -> {
File folder = project.project().folder();
SpoonBasedAnalyzer analyzer = new SpoonBasedAnalyzer();
List<AnalyzerResult> analyze = analyzer.analyze(folder.toPath());
logger.atFine().log(
"Spoon found %s results with the following rules: %s",
analyze.size(),
analyze.stream()
.map(v -> v.ruleID().toString())
.distinct()
.collect(Collectors.joining(",")));
CodeAnalyzerResult.Success success =
new CodeAnalyzerResult.Success(analyze, project.project());
analyzerResultPersistenceService.persistResults(success);
return success;
}
default -> {
return new CodeAnalyzerResult.Failure("Unknown request type");
}
}
} catch (Throwable e) {
logger.atSevere().log("Error while analyzing code analyzer %s", e.getMessage());
Expand Down
12 changes: 5 additions & 7 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
org.gradle.jvmargs=--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
org.gradle.parallel=true
#Gradle properties
#Sat Sep 23 17:47:13 CEST 2023
org.gradle.caching=true
org.gradle.vfs.watch=true
org.gradle.jvmargs=--add-exports jdk.compiler/com.sun.tools.javac.api\=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.file\=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.parser\=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.tree\=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.util\=ALL-UNNAMED
org.gradle.parallel=true
org.gradle.vfs.watch=true
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import spoon.Launcher;
import spoon.reflect.declaration.CtType;

Expand Down Expand Up @@ -42,10 +43,8 @@ public SpoonAnalyzer() {
public List<BadSmell> analyze(String path) {

List<BadSmell> badSmells = new ArrayList<>();
try {
List<Path> files = Files.walk(Path.of(path)).filter(v -> Files.isDirectory(v)).toList();
files = PathUtils.filterResourcePaths(files);

try (Stream<Path> walk = Files.walk(Path.of(path))) {
List<Path> files = PathUtils.filterResourcePaths(walk.filter(Files::isDirectory).toList());
Launcher launcher = new Launcher();
for (Path p : files) {
launcher.addInputResource(p.toString());
Expand Down

0 comments on commit 69f2747

Please sign in to comment.