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

Programming exercises: Fix an issue with missing schedules to combine template commits #10215

Open
wants to merge 11 commits into
base: develop
Choose a base branch
from

Conversation

krusche
Copy link
Member

@krusche krusche commented Jan 26, 2025

Checklist

General

Server

  • Important: I implemented the changes with a very good performance and prevented too many (unnecessary) and too complex database calls.
  • I strictly followed the principle of data economy for all database calls.
  • I strictly followed the server coding and design guidelines.
  • I added multiple integration tests (Spring) related to the features (with a high test coverage).
  • I added pre-authorization annotations according to the guidelines and checked the course groups for all new REST Calls (security).
  • I documented the Java code using JavaDoc style.

Motivation and Context

The scheduled task "combine template commits" currently does not work

Description

The issue was an overlap of two scheduled tasks during the release of an exercise. I separated those and did some additional changes:

  • Less scheduled tasks for LocalVC because they are not required (e.g. lock and unlock repos)
  • Better logging which scheduled tasks are currently running
  • Automatic cleanup of non running scheduled tasks
  • New REST endpoint for admins to retrieve the currently running scheduled tasks for exercises

NOTE: in the future, we want to avoid combining template commits at all and rather create only one commit when creating the student repo, however until we have this functionality, we need this bugfix

Steps for Testing

Prerequisites:

  • 1 Instructor
  • 1 Programming Exercise with a release date
  1. Create the exercises with a release date 2 min in the future
  2. Add a few commits into the template repo before the release date
  3. Verify that 15s before the release date, all template repo commits are combined into one (e.g. by cloning / pulling the repo or by looking into the commit history in the Artemis user interface

Also check, if this works when you import an exercise (either directly or via zip file) and when you edit an exercise shortly before the release date.

Note: the exam mode should not be affected, but testing whether combine template commits here would be nice as well

Testserver States

Note

These badges show the state of the test servers.
Green = Currently available, Red = Currently locked
Click on the badges to get to the test servers.







Review Progress

Code Review

  • Code Review 1
  • Code Review 2

Manual Tests

  • Test 1
  • Test 2

Summary by CodeRabbit

Release Notes

  • New Features

    • Added a new admin endpoint for retrieving scheduled exercise events with pagination support.
    • Introduced a new enum constant SHORTLY_BEFORE_RELEASE in ExerciseLifecycle.
  • Improvements

    • Enhanced task scheduling with more descriptive task names.
    • Updated method names for improved clarity (e.g., listFilesgetFiles).
    • Improved virtual thread support in task scheduling configuration.
    • Refined scheduling logic with more explicit record types.
  • Technical Updates

    • Updated method signatures across multiple services to include task descriptions.
    • Replaced Environment with ProfileService in some configuration methods.
    • Improved serialization support for Tuple record.
  • Performance

    • Enabled virtual threads for task scheduler.
    • Refined logging levels from debug to info in scheduling services.

These changes primarily focus on improving code clarity, scheduling mechanisms, and overall system configuration.

@krusche krusche requested a review from a team as a code owner January 26, 2025 19:42
@krusche krusche added this to the 7.9.1 milestone Jan 26, 2025
@github-actions github-actions bot added tests server Pull requests that update Java code. (Added Automatically!) communication Pull requests that affect the corresponding module core Pull requests that affect the corresponding module exercise Pull requests that affect the corresponding module modeling Pull requests that affect the corresponding module programming Pull requests that affect the corresponding module quiz Pull requests that affect the corresponding module labels Jan 26, 2025
Copy link

coderabbitai bot commented Jan 26, 2025

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 PMD (7.8.0)
src/main/java/de/tum/cit/aet/artemis/exercise/service/ExerciseLifecycleService.java

[ERROR] Error at ruleset.xml:58:5
56|
57|
58|
^^^^^ Unable to find referenced rule BooleanInstantiation; perhaps the rule name is misspelled?

59|
60|
[WARN] Warning at ruleset.xml:66:5
64|
65|
66|
^^^^^ Use Rule name category/java/bestpractices.xml/DefaultLabelNotLastInSwitch instead of the deprecated Rule name category/java/bestpractices.xml/DefaultLabelNotLastInSwitchStmt. PMD 8.0.0 will remove support for this deprecated Rule name usage.

67|
68|
[ERROR] Error at ruleset.xml:71:5
69|
70|
71|
^^^^^ Unable to find referenced rule DontImportJavaLang; perhaps the rule name is misspelled?

72|
73|
[ERROR] Error at ruleset.xml:75:5
73|
74|
75|
^^^^^ Unable to find referenced rule DuplicateImports; perhaps the rule name is misspelled?

76|
77|
[ERROR] Error at ruleset.xml:78:5
76|
77|
78|
^^^^^ Unable to find referenced rule EmptyFinallyBlock; perhaps the rule name is misspelled?

79|
80|
[ERROR] Error at ruleset.xml:79:5
77|
78|
79|
^^^^^ Unable to find referenced rule EmptyIfStmt; perhaps the rule name is misspelled?

80|
81|
[ERROR] Error at ruleset.xml:81:5
79|
80|
81|
^^^^^ Unable to find referenced rule EmptyInitializer; perhaps the rule name is misspelled?

82|
83|
[ERROR] Error at ruleset.xml:82:5
80|
81|
82|
^^^^^ Unable to find referenced rule EmptyStatementBlock; perhaps the rule name is misspelled?

83|
84|
[ERROR] Error at ruleset.xml:83:5
81|
82|
83|
^^^^^ Unable to find referenced rule EmptyStatementNotInLoop; perhaps the rule name is misspelled?

84|
85|
[ERROR] Error at ruleset.xml:84:5
82|
83|
84|
^^^^^ Unable to find referenced rule EmptySwitchStatements; perhaps the rule name is misspelled?

85|
86|
[ERROR] Error at ruleset.xml:85:5
83|
84|
85|
^^^^^ Unable to find referenced rule EmptySynchronizedBlock; perhaps the rule name is misspelled?

86|
87|
[ERROR] Error at ruleset.xml:86:5
84|
85|
86|
^^^^^ Unable to find referenced rule EmptyTryBlock; perhaps the rule name is misspelled?

87|
88|
[ERROR] Error at ruleset.xml:87:5
85|
86|
87|
^^^^^ Unable to find referenced rule EmptyWhileStmt; perhaps the rule name is misspelled?

88|
89|
[ERROR] Error at ruleset.xml:90:5
88|
89|
90|
^^^^^ Unable to find referenced rule ExcessiveClassLength; perhaps the rule name is misspelled?

91|
92|
[ERROR] Error at ruleset.xml:91:5
89|
90|
91|
^^^^^ Unable to find referenced rule ExcessiveMethodLength; perhaps the rule name is misspelled?

92|
93|
[ERROR] Error at ruleset.xml:106:5
104|
105|
106|
^^^^^ Unable to find referenced rule ImportFromSamePackage; perhaps the rule name is misspelled?

107|
108|
[ERROR] Error at ruleset.xml:119:5
117|
118|
119|
^^^^^ Unable to find referenced rule MissingBreakInSwitch; perhaps the rule name is misspelled?

120|
121|
[WARN] Warning at ruleset.xml:124:5
122|
123|
124|
^^^^^ Use Rule name category/java/errorprone.xml/NonCaseLabelInSwitch instead of the deprecated Rule name category/java/errorprone.xml/NonCaseLabelInSwitchStatement. PMD 8.0.0 will remove support for this deprecated Rule name usage.

125|
126|
[ERROR] Error at ruleset.xml:134:9
132|
133| // It's okay to use short variable names in DTOs, e.g. "id" or "name"
134| ./de/tum/in/www1/artemis/web/rest/dto/.
^^^^^^^^^^^^^^^^ Unexpected element 'exclude-pattern' in rule ShortVariable

135|
136|
[ERROR] Error at ruleset.xml:137:5
135|
136|
137|
^^^^^ Unable to find referenced rule SimplifyBooleanAssertion; perhaps the rule name is misspelled?

138|
139|
[WARN] Warning at ruleset.xml:184:5
182|
183|
184|
^^^^^ Use Rule name category/ecmascript/errorprone.xml/InaccurateNumericLiteral instead of the deprecated Rule name category/ecmascript/errorprone.xml/InnaccurateNumericLiteral. PMD 8.0.0 will remove support for this deprecated Rule name usage.

185|
186|
[ERROR] Cannot load ruleset category/vm/bestpractices.xml: Cannot resolve rule/ruleset reference 'category/vm/bestpractices.xml'. Make sure the resource is a valid file or URL and is on the CLASSPATH. Use --debug (or a fine log level) to see the current classpath.
[WARN] Progressbar rendering conflicts with reporting to STDOUT. No progressbar will be shown. Try running with argument -r to output the report to a file instead.

src/main/java/de/tum/cit/aet/artemis/core/service/ScheduleService.java

[ERROR] Error at ruleset.xml:58:5
56|
57|
58|
^^^^^ Unable to find referenced rule BooleanInstantiation; perhaps the rule name is misspelled?

59|
60|
[WARN] Warning at ruleset.xml:66:5
64|
65|
66|
^^^^^ Use Rule name category/java/bestpractices.xml/DefaultLabelNotLastInSwitch instead of the deprecated Rule name category/java/bestpractices.xml/DefaultLabelNotLastInSwitchStmt. PMD 8.0.0 will remove support for this deprecated Rule name usage.

67|
68|
[ERROR] Error at ruleset.xml:71:5
69|
70|
71|
^^^^^ Unable to find referenced rule DontImportJavaLang; perhaps the rule name is misspelled?

72|
73|
[ERROR] Error at ruleset.xml:75:5
73|
74|
75|
^^^^^ Unable to find referenced rule DuplicateImports; perhaps the rule name is misspelled?

76|
77|
[ERROR] Error at ruleset.xml:78:5
76|
77|
78|
^^^^^ Unable to find referenced rule EmptyFinallyBlock; perhaps the rule name is misspelled?

79|
80|
[ERROR] Error at ruleset.xml:79:5
77|
78|
79|
^^^^^ Unable to find referenced rule EmptyIfStmt; perhaps the rule name is misspelled?

80|
81|
[ERROR] Error at ruleset.xml:81:5
79|
80|
81|
^^^^^ Unable to find referenced rule EmptyInitializer; perhaps the rule name is misspelled?

82|
83|
[ERROR] Error at ruleset.xml:82:5
80|
81|
82|
^^^^^ Unable to find referenced rule EmptyStatementBlock; perhaps the rule name is misspelled?

83|
84|
[ERROR] Error at ruleset.xml:83:5
81|
82|
83|
^^^^^ Unable to find referenced rule EmptyStatementNotInLoop; perhaps the rule name is misspelled?

84|
85|
[ERROR] Error at ruleset.xml:84:5
82|
83|
84|
^^^^^ Unable to find referenced rule EmptySwitchStatements; perhaps the rule name is misspelled?

85|
86|
[ERROR] Error at ruleset.xml:85:5
83|
84|
85|
^^^^^ Unable to find referenced rule EmptySynchronizedBlock; perhaps the rule name is misspelled?

86|
87|
[ERROR] Error at ruleset.xml:86:5
84|
85|
86|
^^^^^ Unable to find referenced rule EmptyTryBlock; perhaps the rule name is misspelled?

87|
88|
[ERROR] Error at ruleset.xml:87:5
85|
86|
87|
^^^^^ Unable to find referenced rule EmptyWhileStmt; perhaps the rule name is misspelled?

88|
89|
[ERROR] Error at ruleset.xml:90:5
88|
89|
90|
^^^^^ Unable to find referenced rule ExcessiveClassLength; perhaps the rule name is misspelled?

91|
92|
[ERROR] Error at ruleset.xml:91:5
89|
90|
91|
^^^^^ Unable to find referenced rule ExcessiveMethodLength; perhaps the rule name is misspelled?

92|
93|
[ERROR] Error at ruleset.xml:106:5
104|
105|
106|
^^^^^ Unable to find referenced rule ImportFromSamePackage; perhaps the rule name is misspelled?

107|
108|
[ERROR] Error at ruleset.xml:119:5
117|
118|
119|
^^^^^ Unable to find referenced rule MissingBreakInSwitch; perhaps the rule name is misspelled?

120|
121|
[WARN] Warning at ruleset.xml:124:5
122|
123|
124|
^^^^^ Use Rule name category/java/errorprone.xml/NonCaseLabelInSwitch instead of the deprecated Rule name category/java/errorprone.xml/NonCaseLabelInSwitchStatement. PMD 8.0.0 will remove support for this deprecated Rule name usage.

125|
126|
[ERROR] Error at ruleset.xml:134:9
132|
133| // It's okay to use short variable names in DTOs, e.g. "id" or "name"
134| ./de/tum/in/www1/artemis/web/rest/dto/.
^^^^^^^^^^^^^^^^ Unexpected element 'exclude-pattern' in rule ShortVariable

135|
136|
[ERROR] Error at ruleset.xml:137:5
135|
136|
137|
^^^^^ Unable to find referenced rule SimplifyBooleanAssertion; perhaps the rule name is misspelled?

138|
139|
[WARN] Warning at ruleset.xml:184:5
182|
183|
184|
^^^^^ Use Rule name category/ecmascript/errorprone.xml/InaccurateNumericLiteral instead of the deprecated Rule name category/ecmascript/errorprone.xml/InnaccurateNumericLiteral. PMD 8.0.0 will remove support for this deprecated Rule name usage.

185|
186|
[ERROR] Cannot load ruleset category/vm/bestpractices.xml: Cannot resolve rule/ruleset reference 'category/vm/bestpractices.xml'. Make sure the resource is a valid file or URL and is on the CLASSPATH. Use --debug (or a fine log level) to see the current classpath.
[WARN] Progressbar rendering conflicts with reporting to STDOUT. No progressbar will be shown. Try running with argument -r to output the report to a file instead.

src/main/java/de/tum/cit/aet/artemis/core/config/TaskSchedulingConfiguration.java

[ERROR] Error at ruleset.xml:58:5
56|
57|
58|
^^^^^ Unable to find referenced rule BooleanInstantiation; perhaps the rule name is misspelled?

59|
60|
[WARN] Warning at ruleset.xml:66:5
64|
65|
66|
^^^^^ Use Rule name category/java/bestpractices.xml/DefaultLabelNotLastInSwitch instead of the deprecated Rule name category/java/bestpractices.xml/DefaultLabelNotLastInSwitchStmt. PMD 8.0.0 will remove support for this deprecated Rule name usage.

67|
68|
[ERROR] Error at ruleset.xml:71:5
69|
70|
71|
^^^^^ Unable to find referenced rule DontImportJavaLang; perhaps the rule name is misspelled?

72|
73|
[ERROR] Error at ruleset.xml:75:5
73|
74|
75|
^^^^^ Unable to find referenced rule DuplicateImports; perhaps the rule name is misspelled?

76|
77|
[ERROR] Error at ruleset.xml:78:5
76|
77|
78|
^^^^^ Unable to find referenced rule EmptyFinallyBlock; perhaps the rule name is misspelled?

79|
80|
[ERROR] Error at ruleset.xml:79:5
77|
78|
79|
^^^^^ Unable to find referenced rule EmptyIfStmt; perhaps the rule name is misspelled?

80|
81|
[ERROR] Error at ruleset.xml:81:5
79|
80|
81|
^^^^^ Unable to find referenced rule EmptyInitializer; perhaps the rule name is misspelled?

82|
83|
[ERROR] Error at ruleset.xml:82:5
80|
81|
82|
^^^^^ Unable to find referenced rule EmptyStatementBlock; perhaps the rule name is misspelled?

83|
84|
[ERROR] Error at ruleset.xml:83:5
81|
82|
83|
^^^^^ Unable to find referenced rule EmptyStatementNotInLoop; perhaps the rule name is misspelled?

84|
85|
[ERROR] Error at ruleset.xml:84:5
82|
83|
84|
^^^^^ Unable to find referenced rule EmptySwitchStatements; perhaps the rule name is misspelled?

85|
86|
[ERROR] Error at ruleset.xml:85:5
83|
84|
85|
^^^^^ Unable to find referenced rule EmptySynchronizedBlock; perhaps the rule name is misspelled?

86|
87|
[ERROR] Error at ruleset.xml:86:5
84|
85|
86|
^^^^^ Unable to find referenced rule EmptyTryBlock; perhaps the rule name is misspelled?

87|
88|
[ERROR] Error at ruleset.xml:87:5
85|
86|
87|
^^^^^ Unable to find referenced rule EmptyWhileStmt; perhaps the rule name is misspelled?

88|
89|
[ERROR] Error at ruleset.xml:90:5
88|
89|
90|
^^^^^ Unable to find referenced rule ExcessiveClassLength; perhaps the rule name is misspelled?

91|
92|
[ERROR] Error at ruleset.xml:91:5
89|
90|
91|
^^^^^ Unable to find referenced rule ExcessiveMethodLength; perhaps the rule name is misspelled?

92|
93|
[ERROR] Error at ruleset.xml:106:5
104|
105|
106|
^^^^^ Unable to find referenced rule ImportFromSamePackage; perhaps the rule name is misspelled?

107|
108|
[ERROR] Error at ruleset.xml:119:5
117|
118|
119|
^^^^^ Unable to find referenced rule MissingBreakInSwitch; perhaps the rule name is misspelled?

120|
121|
[WARN] Warning at ruleset.xml:124:5
122|
123|
124|
^^^^^ Use Rule name category/java/errorprone.xml/NonCaseLabelInSwitch instead of the deprecated Rule name category/java/errorprone.xml/NonCaseLabelInSwitchStatement. PMD 8.0.0 will remove support for this deprecated Rule name usage.

125|
126|
[ERROR] Error at ruleset.xml:134:9
132|
133| // It's okay to use short variable names in DTOs, e.g. "id" or "name"
134| ./de/tum/in/www1/artemis/web/rest/dto/.
^^^^^^^^^^^^^^^^ Unexpected element 'exclude-pattern' in rule ShortVariable

135|
136|
[ERROR] Error at ruleset.xml:137:5
135|
136|
137|
^^^^^ Unable to find referenced rule SimplifyBooleanAssertion; perhaps the rule name is misspelled?

138|
139|
[WARN] Warning at ruleset.xml:184:5
182|
183|
184|
^^^^^ Use Rule name category/ecmascript/errorprone.xml/InaccurateNumericLiteral instead of the deprecated Rule name category/ecmascript/errorprone.xml/InnaccurateNumericLiteral. PMD 8.0.0 will remove support for this deprecated Rule name usage.

185|
186|
[ERROR] Cannot load ruleset category/vm/bestpractices.xml: Cannot resolve rule/ruleset reference 'category/vm/bestpractices.xml'. Make sure the resource is a valid file or URL and is on the CLASSPATH. Use --debug (or a fine log level) to see the current classpath.
[WARN] Progressbar rendering conflicts with reporting to STDOUT. No progressbar will be shown. Try running with argument -r to output the report to a file instead.

  • 1 others

Walkthrough

This pull request introduces several significant changes across multiple services and components in the Artemis project. The primary focus is on enhancing task scheduling, improving method naming conventions, and refining repository and service interactions. Key modifications include updating method signatures in scheduling services, introducing new record types for task management, renaming methods in the GitService for clarity, and adding a new admin schedule resource. The changes aim to improve code readability, type safety, and provide more descriptive task scheduling mechanisms.

Changes

File Change Summary
build.gradle Updated comment in dependencies block
core/config/TaskSchedulingConfiguration.java Added virtual thread support and explicit scheduler initialization
core/service/ScheduleService.java Introduced new record types for task management, updated scheduling methods
core/util/Tuple.java Renamed tuple parameters, added Serializable interface
core/web/admin/AdminScheduleResource.java New REST controller for fetching scheduled exercise events
exercise/domain/ExerciseLifecycle.java Added new enum constant SHORTLY_BEFORE_RELEASE
exercise/service/ExerciseLifecycleService.java Updated logging statements and variable references
exercise/web/ParticipationResource.java Updated comment for scheduling tasks
quiz/service/QuizScheduleService.java Replaced scheduleTask with scheduleExerciseTask, added descriptive task names
programming/service/GitService.java Renamed listFiles/listFilesAndFolders to getFiles/getFilesAndFolders
programming/service/JavaTemplateUpgradeService.java Updated method calls to reflect new GitService method names
programming/service/ProgrammingExerciseRepositoryService.java Updated method calls to reflect new GitService method names
programming/service/ProgrammingExerciseScheduleService.java Integrated new ProfileService, modified scheduling logic
programming/service/RepositoryService.java Updated method calls to reflect new GitService method names
programming/service/vcs/AbstractVersionControlService.java Removed TODO comment in error handling
test/core/service/TitleCacheEvictionServiceTest.java Updated Tuple access methods in tests
test/programming/GitServiceTest.java Renamed test methods to reflect new GitService method names
test/programming/ProgrammingExerciseParticipationIntegrationTest.java Updated test method calls to reflect new GitService method names
test/programming/ProgrammingExerciseScheduleServiceTest.java Updated method signatures in test calls for scheduling tasks
test/programming/RepositoryIntegrationTest.java Updated method calls to reflect new GitService method names

Suggested Labels

bugfix, lock:artemis-test2

Suggested Reviewers

  • BBesrour
  • SimonEntholzer
  • Feras797
  • coolchock
  • HawKhiem
  • ItsaaaMeMario
✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (16)
src/main/java/de/tum/cit/aet/artemis/core/config/TaskSchedulingConfiguration.java (1)

26-26: Make pool size configurable via properties.

Consider making the pool size configurable through application properties to allow for environment-specific tuning.

Apply this diff to make the pool size configurable:

+    @Value("${artemis.scheduling.pool-size:4}")
+    private int poolSize;

     @Bean(name = "taskScheduler")
     public TaskScheduler taskScheduler() {
         log.debug("Creating Task Scheduler ");
         var scheduler = new ThreadPoolTaskScheduler();
-        scheduler.setPoolSize(4);
+        scheduler.setPoolSize(poolSize);

Add the following to your application.properties:

# Configure the size of the task scheduler thread pool (default: 4)
artemis.scheduling.pool-size=4
src/main/java/de/tum/cit/aet/artemis/programming/service/RepositoryService.java (2)

Line range hint 161-173: Consider simplifying the stream operations for better readability.

The current stream operation chain can be simplified by combining the filter and map operations into the collector.

-        var files = gitService.getFilesAndFolders(repository).entrySet().stream().filter(entry -> entry.getValue() == FileType.FILE).map(Map.Entry::getKey).toList();
+        var files = gitService.getFilesAndFolders(repository).entrySet().stream()
+            .filter(entry -> entry.getValue() == FileType.FILE)
+            .map(Map.Entry::getKey)
+            .toList();

265-269: Consider improving readability of stream operations.

The complex stream operations can be made more readable by breaking them into multiple lines and using meaningful variable names.

-        var repoFiles = gitService.getFilesAndFolders(repository).entrySet().stream().filter(entry -> entry.getValue() == FileType.FILE).map(Map.Entry::getKey).toList();
-
-        Map<String, File> templateRepoFiles = gitService.getFilesAndFolders(templateRepository).entrySet().stream().filter(entry -> entry.getValue() == FileType.FILE)
-                .collect(Collectors.toMap(entry -> entry.getKey().toString(), Map.Entry::getKey));
+        var repoFiles = gitService.getFilesAndFolders(repository).entrySet().stream()
+            .filter(entry -> entry.getValue() == FileType.FILE)
+            .map(Map.Entry::getKey)
+            .toList();
+
+        Map<String, File> templateRepoFiles = gitService.getFilesAndFolders(templateRepository).entrySet().stream()
+            .filter(entry -> entry.getValue() == FileType.FILE)
+            .collect(Collectors.toMap(
+                entry -> entry.getKey().toString(),
+                Map.Entry::getKey
+            ));
src/main/java/de/tum/cit/aet/artemis/modeling/service/ModelingExerciseScheduleService.java (3)

145-145: LGTM! Consider enhancing the task description.

The change to scheduleExerciseTask with a descriptive parameter improves task tracking. Consider making the description more specific by including the exercise ID: "build modeling clusters after due date for exercise #{exerciseId}".

-            scheduleService.scheduleExerciseTask(exercise, ExerciseLifecycle.DUE, () -> buildModelingClusters(exercise).run(), "build modeling clusters after due date");
+            scheduleService.scheduleExerciseTask(exercise, ExerciseLifecycle.DUE, () -> buildModelingClusters(exercise).run(), 
+                    String.format("build modeling clusters after due date for exercise #%d", exercise.getId()));

163-164: LGTM! Consider enhancing the task description for consistency.

The change to scheduleExerciseTask is good. For consistency with the previous suggestion and better tracking, consider making the description more specific.

-            scheduleService.scheduleExerciseTask(exercise, ExerciseLifecycle.BUILD_COMPASS_CLUSTERS_AFTER_EXAM, () -> buildModelingClusters(exercise).run(),
-                    "build modeling clusters after exam");
+            scheduleService.scheduleExerciseTask(exercise, ExerciseLifecycle.BUILD_COMPASS_CLUSTERS_AFTER_EXAM, () -> buildModelingClusters(exercise).run(),
+                    String.format("build modeling clusters after exam for exercise #%d", exercise.getId()));

Line range hint 191-204: Enhance error handling and logging in buildModelingClusters.

The error handling in the buildModelingClusters method could be improved to provide more context and better logging.

     private Runnable buildModelingClusters(ModelingExercise exercise) {
         Long modelingExerciseId = exercise.getId();
         return () -> {
             SecurityUtils.setAuthorizationObject();
+            log.debug("Starting to build modeling clusters for exercise #{}", modelingExerciseId);
             try {
                 Optional<ModelingExercise> modelingExercise = modelingExerciseRepository.findById(modelingExerciseId);
                 if (modelingExercise.isEmpty()) {
                     throw new EntityNotFoundException("modeling exercise not found with id " + modelingExerciseId);
                 }

                 compassService.build(modelingExercise.get());
+                log.debug("Successfully built modeling clusters for exercise #{}", modelingExerciseId);
             }
             catch (EntityNotFoundException ex) {
-                log.error("Modeling exercise with id {} is no longer available in database for use in scheduled task.", modelingExerciseId);
+                log.error("Failed to build modeling clusters: exercise #{} no longer exists", modelingExerciseId, ex);
+            }
+            catch (Exception ex) {
+                log.error("Unexpected error while building modeling clusters for exercise #{}", modelingExerciseId, ex);
             }
         };
     }
src/main/java/de/tum/cit/aet/artemis/core/service/ScheduleService.java (2)

105-153: Scheduled logging and cleanup every 15 seconds.
Continuously removing non-running tasks is beneficial to avoid stale entries. Consider reviewing 15-second intervals for potential performance overhead in high-traffic environments.


232-240: Multiple-task scheduling at different times.
Good handling of multiple Tuple<ZonedDateTime, Runnable> entries for the same lifecycle. Ensure no concurrency issues if tasks overlap in runtime.

src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseScheduleService.java (1)

348-348: Fetching participations.
Ensure large queries with .findWithSubmissionsAndTeamStudentsByExerciseId remain performant. Index usage might be beneficial.

src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminScheduleResource.java (3)

22-24: Update JavaDoc comment to match the class purpose.

The JavaDoc comment incorrectly states "REST controller for getting the audit events" but this controller is for getting scheduled events.

-* REST controller for getting the audit events.
+* REST controller for getting scheduled exercise events.

28-28: Follow REST API best practices for base URL.

The base URL should not end with a trailing slash as it can lead to double-slash issues.

-@RequestMapping("api/admin/")
+@RequestMapping("api/admin")

43-48: Consider adding response status documentation.

The endpoint implementation looks good, but could benefit from explicit documentation of possible response status codes using @ApiResponse annotations.

src/main/java/de/tum/cit/aet/artemis/exercise/domain/ExerciseLifecycle.java (1)

11-22: Extract magic number to a constant.

The 15 seconds offset is a magic number that should be extracted to a named constant for better maintainability and clarity.

+private static final int RELEASE_PREPARATION_OFFSET_SECONDS = 15;

 SHORTLY_BEFORE_RELEASE {
     @Override
     public ZonedDateTime getDateFromExercise(Exercise exercise) {
-        return exercise.getReleaseDate() != null ? exercise.getReleaseDate().minusSeconds(15) : null;
+        return exercise.getReleaseDate() != null ? exercise.getReleaseDate().minusSeconds(RELEASE_PREPARATION_OFFSET_SECONDS) : null;
     }
src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizScheduleService.java (1)

107-109: Consider extracting task name to a constant.

The task name "calculate all quiz results" could be extracted to a constant to maintain consistency and enable reuse.

+private static final String TASK_NAME_CALCULATE_RESULTS = "calculate all quiz results";

 public void scheduleCalculateAllResults(QuizExercise quizExercise) {
     if (quizExercise.getDueDate() != null && !quizExercise.isQuizEnded()) {
         scheduleService.scheduleExerciseTask(quizExercise, ExerciseLifecycle.DUE,
-                new Tuple<>(quizExercise.getDueDate().plusSeconds(5), () -> quizSubmissionService.calculateAllResults(quizExercise.getId())), "calculate all quiz results");
+                new Tuple<>(quizExercise.getDueDate().plusSeconds(5), () -> quizSubmissionService.calculateAllResults(quizExercise.getId())), TASK_NAME_CALCULATE_RESULTS);
src/test/java/de/tum/cit/aet/artemis/programming/ProgrammingExerciseScheduleServiceTest.java (2)

374-376: Improve line formatting for better readability.

Consider reformatting the method call to avoid line wrapping:

-        verify(scheduleService, timeout(TIMEOUT_MS)).scheduleParticipationTask(eq(participationIndividualDueDate), eq(ParticipationLifecycle.BUILD_AND_TEST_AFTER_DUE_DATE), any(),
-                any());
+        verify(scheduleService, timeout(TIMEOUT_MS)).scheduleParticipationTask(
+            eq(participationIndividualDueDate),
+            eq(ParticipationLifecycle.BUILD_AND_TEST_AFTER_DUE_DATE),
+            any(),
+            any()
+        );

565-566: Improve line formatting for better readability.

Consider reformatting the method call to avoid line wrapping:

-        verify(scheduleService, after(SCHEDULER_TASK_TRIGGER_DELAY_MS).never()).scheduleExerciseTask(eq(programmingExercise), eq(ExerciseLifecycle.DUE), any(Runnable.class),
-                any());
+        verify(scheduleService, after(SCHEDULER_TASK_TRIGGER_DELAY_MS).never()).scheduleExerciseTask(
+            eq(programmingExercise),
+            eq(ExerciseLifecycle.DUE),
+            any(Runnable.class),
+            any()
+        );
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6d1fae1 and 313fc52.

📒 Files selected for processing (22)
  • build.gradle (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/communication/service/NotificationScheduleService.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/core/config/TaskSchedulingConfiguration.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/core/service/ScheduleService.java (8 hunks)
  • src/main/java/de/tum/cit/aet/artemis/core/util/Tuple.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminScheduleResource.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/exercise/domain/ExerciseLifecycle.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/exercise/service/ExerciseLifecycleService.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/modeling/service/ModelingExerciseScheduleService.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/service/GitService.java (5 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/service/JavaTemplateUpgradeService.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseRepositoryService.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseScheduleService.java (16 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/service/RepositoryService.java (3 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/service/vcs/AbstractVersionControlService.java (0 hunks)
  • src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizScheduleService.java (2 hunks)
  • src/test/java/de/tum/cit/aet/artemis/core/service/TitleCacheEvictionServiceTest.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/programming/GitServiceTest.java (2 hunks)
  • src/test/java/de/tum/cit/aet/artemis/programming/ProgrammingExerciseParticipationIntegrationTest.java (2 hunks)
  • src/test/java/de/tum/cit/aet/artemis/programming/ProgrammingExerciseScheduleServiceTest.java (11 hunks)
  • src/test/java/de/tum/cit/aet/artemis/programming/RepositoryIntegrationTest.java (1 hunks)
💤 Files with no reviewable changes (1)
  • src/main/java/de/tum/cit/aet/artemis/programming/service/vcs/AbstractVersionControlService.java
✅ Files skipped from review due to trivial changes (5)
  • build.gradle
  • src/test/java/de/tum/cit/aet/artemis/core/service/TitleCacheEvictionServiceTest.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java
  • src/test/java/de/tum/cit/aet/artemis/programming/GitServiceTest.java
  • src/test/java/de/tum/cit/aet/artemis/programming/ProgrammingExerciseParticipationIntegrationTest.java
🧰 Additional context used
📓 Path-based instructions (16)
src/main/java/de/tum/cit/aet/artemis/exercise/domain/ExerciseLifecycle.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/core/util/Tuple.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/programming/service/JavaTemplateUpgradeService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseRepositoryService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/core/config/TaskSchedulingConfiguration.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/modeling/service/ModelingExerciseScheduleService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/programming/service/RepositoryService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/test/java/de/tum/cit/aet/artemis/programming/RepositoryIntegrationTest.java (1)

Pattern src/test/java/**/*.java: test_naming: descriptive; test_size: small_specific; fixed_data: true; junit5_features: true; assert_use: assertThat; assert_specificity: true; archunit_use: enforce_package_rules; db_query_count_tests: track_performance; util_service_factory_pattern: true; avoid_db_access: true; mock_strategy: static_mocks; context_restart_minimize: true

src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizScheduleService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminScheduleResource.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/exercise/service/ExerciseLifecycleService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/communication/service/NotificationScheduleService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseScheduleService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/programming/service/GitService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/test/java/de/tum/cit/aet/artemis/programming/ProgrammingExerciseScheduleServiceTest.java (1)

Pattern src/test/java/**/*.java: test_naming: descriptive; test_size: small_specific; fixed_data: true; junit5_features: true; assert_use: assertThat; assert_specificity: true; archunit_use: enforce_package_rules; db_query_count_tests: track_performance; util_service_factory_pattern: true; avoid_db_access: true; mock_strategy: static_mocks; context_restart_minimize: true

src/main/java/de/tum/cit/aet/artemis/core/service/ScheduleService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

📓 Learnings (1)
src/main/java/de/tum/cit/aet/artemis/programming/service/JavaTemplateUpgradeService.java (1)
Learnt from: magaupp
PR: ls1intum/Artemis#9074
File: src/main/java/de/tum/in/www1/artemis/service/programming/TemplateUpgradePolicyService.java:35-35
Timestamp: 2024-11-12T12:51:46.554Z
Learning: The `defaultRepositoryUpgradeService` in the `TemplateUpgradePolicyService` is used as a default for all non-JAVA languages, with specialized services added based on testing outcomes if necessary.
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: client-tests
  • GitHub Check: server-tests
  • GitHub Check: Build and Push Docker Image
  • GitHub Check: Analyse
  • GitHub Check: Build .war artifact
🔇 Additional comments (53)
src/main/java/de/tum/cit/aet/artemis/core/config/TaskSchedulingConfiguration.java (1)

27-27: LGTM!

Explicitly calling initialize() is a good practice to ensure the scheduler is properly set up before use.

src/main/java/de/tum/cit/aet/artemis/programming/service/JavaTemplateUpgradeService.java (1)

106-106: LGTM! Method name change improves clarity.

The change from listFiles to getFiles is consistent with similar updates across the codebase and better reflects the method's purpose.

src/main/java/de/tum/cit/aet/artemis/programming/service/GitService.java (3)

323-326: LGTM! Parameter name better reflects its type.

The parameter rename from targetUrl to targetUri is more accurate as it represents a VcsRepositoryUri object.


Line range hint 1018-1029: LGTM! Method name and documentation improvements.

The change from listFilesAndFolders to getFilesAndFolders better reflects the method's purpose. Documentation updates accurately describe the method's behavior, including important details about caching and symbolic link handling.


1051-1057: LGTM! Method name and documentation improvements.

The change from listFiles to getFiles is consistent with the naming pattern. Documentation clarifies that an empty list is returned for empty repositories.

src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseRepositoryService.java (2)

327-327: LGTM! Method name updated for consistency.

Updated to use the renamed getFiles method from GitService.


361-361: LGTM! Method name updated for consistency.

Updated to use the renamed getFiles method from GitService.

src/test/java/de/tum/cit/aet/artemis/programming/RepositoryIntegrationTest.java (1)

347-347: LGTM! Test mock updated to match renamed method.

Updated the mock to use the renamed getFilesAndFolders method from GitService.

src/main/java/de/tum/cit/aet/artemis/programming/service/RepositoryService.java (3)

100-100: LGTM! Method name change is consistent.

The renaming from listFilesAndFolders to getFilesAndFolders maintains the method's functionality while improving naming consistency.


161-161: LGTM! Method name change is consistent.

The renaming from listFilesAndFolders to getFilesAndFolders aligns with the codebase's naming conventions.


265-267: LGTM! Method name changes are consistent.

The renaming from listFilesAndFolders to getFilesAndFolders maintains consistency across the codebase.

src/main/java/de/tum/cit/aet/artemis/core/service/ScheduleService.java (13)

4-4: No issues with updated imports.
The newly introduced imports are specific and non-duplicative. There's no use of wildcard imports.

Also applies to: 6-7, 9-13, 18-21, 26-26, 28-33


56-67: Good use of Java records for typed keys.
Introducing dedicated records (ExerciseLifecycleKey, ParticipationLifecycleKey, ScheduledTaskName, and ScheduledExerciseEvent) increases code clarity and type safety.


68-68: ConcurrentMap usage looks appropriate.
Using ConcurrentHashMap for tracking scheduled tasks is suitable. Verify concurrency correctness for atomic removals in repeated tasks (e.g., removeIf).

Also applies to: 71-72


73-75: Initialization of TaskScheduler with virtual threads.
Using setVirtualThreads(true) is modern and can handle concurrency well, but ensure this environment supports virtual threads (Java 19+).

Also applies to: 80-88


89-103: Pagination logic for scheduled exercise events.
Flattening and sorting scheduled tasks before pagination is clear. Great approach to returning a Page.


155-157: Helper methods for adding/removing scheduled tasks.
Small, focused methods adhere to single responsibility. This is maintainable and consistent with best practices.

Also applies to: 160-161, 164-166, 169-171, 174-176


185-192: Exercise scheduling with descriptive naming.
Including String name improves traceability when diagnosing scheduled tasks.


202-210: QuizExercise scheduling.
Similar approach as standard exercises. Ensure all quiz-specific validations (e.g., batch constraints) are handled.


212-224: Single-task scheduling with time.
Clear separation of scheduling logic for a single Tuple<ZonedDateTime, Runnable>. The method is self-documenting and flexible.


249-254: Participation-specific scheduling.
This method reads well. Confirm that cancellation logic properly aligns with newly introduced schedule calls.


266-276: Lifecycle cancellation logic.
Ensuring all possible tasks for an exercise are canceled prevents extraneous scheduling. Consider concurrency if tasks complete just as they’re canceled.


289-294: Participation cancellation logic.
Matches exercise-level logic. The finer granularity is beneficial for cleanup.


314-317: Global cleanup in testing.
Clearing all maps is a pragmatic approach for test environments. Minimal risk of side effects.

src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseScheduleService.java (15)

42-42: New import for ProfileService.
No issues; consistent with the DI approach used elsewhere.


100-101: ProfileService field injection.
Adheres to constructor injection. Clear separation of environment checks from scheduling logic.


104-104: Constructor refactoring.
Replacing Environment with ProfileService clarifies the logic for environment selection, removing direct reliance on profile strings.

Also applies to: 107-107, 124-124


136-136: Skipping scheduling if dev profile is active.
This condition is reversed from the comment text (“only execute on production”), but the logic is correct: if (isDevActive()) return;.


298-300: Scheduling template commit combination.
Executes a commit combination task shortly before release date. The naming is explicit.


307-307: Due date scheduling with local VCS checks.
This diversified path for local VCS is a good approach. Validation: confirm that partial scheduling in local mode is intended.

Also applies to: 309-325


331-332: Scheduling build & test after due date.
Method named concisely. Looks consistent with the scheduling approach of other lifecycles.


359-360: Scheduling participation with individual due dates.
This is a sensible extension for custom deadlines. Good decomposition.


382-382: Locking repositories and updating student results.
This block differentiates local VCS from remote usage gracefully. The breakdown of tasks is consistent with single responsibility.

Also applies to: 384-405


420-420: Exam participation scheduling.
Ensure robust error handling for EntityNotFoundException during the exam conduction.


447-449: Unlocking exam repositories.
Checking local VCS again is consistent. The user is properly informed via logs.


456-460: Rescheduling at runtime for extended working times.
This is a helpful fallback mechanism in case of crashes. Good clarity in the logs.


467-468: Build and test after exam’s buildAndTestStudentSubmissionsAfterDueDate.
Similar approach as normal exercises. well integrated.


479-479: Combining template commits in Git.
Error handling is well-structured. The logs provide clear traceability if an exception occurs.

Also applies to: 485-485, 488-488


1021-1022: Detailed error logging in concurrency.
Providing participation ID in logs is beneficial for debugging. Ensure none of these logs leak sensitive data.

src/main/java/de/tum/cit/aet/artemis/core/util/Tuple.java (2)

3-4: Serializable import introduced.
Making Tuple serializable is beneficial for distributed systems or caching usage.


8-11: Renamed generic parameters and fields.
Switching to F/S and first/second clarifies usage. Documenting them in Javadoc is consistent with best practices.

src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminScheduleResource.java (1)

31-35: LGTM! Constructor injection is properly used.

The service dependency is marked as final and injected through constructor, following best practices.

src/main/java/de/tum/cit/aet/artemis/exercise/service/ExerciseLifecycleService.java (2)

104-107: LGTM! Tuple access methods are more readable.

The change from x()/y() to first()/second() improves code readability by using more descriptive method names.


50-50: Consider keeping debug level for frequent scheduling events.

Changing log level from debug to info might lead to log pollution as scheduling events are frequent. Consider keeping it at debug level unless there's a specific monitoring requirement.

src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizScheduleService.java (1)

92-93: LGTM! Task name parameter improves observability.

The addition of a descriptive task name "quiz start" enhances monitoring and debugging capabilities.

src/main/java/de/tum/cit/aet/artemis/communication/service/NotificationScheduleService.java (2)

117-123: LGTM! Improved task identification with descriptive parameter.

The change from scheduleTask to scheduleExerciseTask with the added descriptive parameter enhances task tracking and debugging capabilities.


158-164: LGTM! Consistent task identification pattern.

The change maintains consistency with the previous update, using a clear descriptive parameter for assessment notifications.

src/test/java/de/tum/cit/aet/artemis/programming/ProgrammingExerciseScheduleServiceTest.java (6)

345-346: LGTM! Test updated to verify new method signature.

Test correctly verifies the updated scheduleParticipationTask method with the additional parameter.


396-400: LGTM! Comprehensive test coverage.

Test effectively verifies both participation and exercise task scheduling, including negative cases.


419-423: LGTM! Consistent test verification pattern.

Test maintains consistency with previous test cases while verifying the updated method signatures.


514-518: LGTM! Thorough verification of both positive and negative cases.

Test effectively uses Mockito's never() verification to ensure certain tasks are not scheduled.


525-529: LGTM! Proper verification of multiple scheduling calls.

Test effectively uses Mockito's times() verification to ensure correct number of scheduling calls.


547-548: LGTM! Clear verification of specific scheduling scenario.

Test effectively verifies the expected scheduling behavior for individual due dates.

SimonEntholzer
SimonEntholzer previously approved these changes Jan 26, 2025
Copy link
Contributor

@SimonEntholzer SimonEntholzer left a comment

Choose a reason for hiding this comment

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

Seems to work correctly on Ts4

Before release date:
image

After release date:
image

BBesrour
BBesrour previously approved these changes Jan 26, 2025
Copy link
Member

@BBesrour BBesrour left a comment

Choose a reason for hiding this comment

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

Tested on TS4, works as described. Also in edit mode and exam mode

Copy link

@Cathy0123456789 Cathy0123456789 left a comment

Choose a reason for hiding this comment

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

Tested on TS4.
Works with creating a new exercise:
image
image
As well as importing an exercise:
image
image

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 27, 2025
sawys777
sawys777 previously approved these changes Jan 31, 2025
Copy link

@sawys777 sawys777 left a comment

Choose a reason for hiding this comment

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

Tested on TS4, everything works as expected

SindiBuklaji
SindiBuklaji previously approved these changes Jan 31, 2025
Copy link

@SindiBuklaji SindiBuklaji left a comment

Choose a reason for hiding this comment

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

Tested on Ts3 and it works as described. 👍

@krusche krusche changed the title Programming exercise: Fix an issue with missing schedules to combine template commits Programming exercises: Fix an issue with missing schedules to combine template commits Feb 1, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (5)
src/main/java/de/tum/cit/aet/artemis/core/service/ScheduleService.java (5)

73-87: Consider making the TaskScheduler configuration more configurable.

While the initialization is correct, consider extracting the pool size and virtual threads configuration to application properties for better flexibility.

+@Value("${schedule.pool-size:1}")
+private int poolSize;
+
+@Value("${schedule.virtual-threads:true}")
+private boolean useVirtualThreads;

 private final TaskScheduler taskScheduler;

 public ScheduleService(...) {
     // ...
     ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
-    scheduler.setPoolSize(1);
-    scheduler.setVirtualThreads(true);
+    scheduler.setPoolSize(poolSize);
+    scheduler.setVirtualThreads(useVirtualThreads);
     scheduler.initialize();
     this.taskScheduler = scheduler;
 }

89-179: Excellent implementation of task monitoring and cleanup!

The periodic task monitoring implementation is well-documented and effectively handles cleanup of completed tasks. The use of debug logging is appropriate for monitoring purposes.

However, consider extracting the logging interval to a configuration property for flexibility.

+@Value("${schedule.monitoring.interval-seconds:15}")
+private int monitoringIntervalSeconds;

 @EventListener(ApplicationReadyEvent.class)
 public void startup() {
-    taskScheduler.scheduleAtFixedRate(() -> {
+    taskScheduler.scheduleAtFixedRate(() -> {
         // ... existing code ...
-    }, Duration.ofSeconds(15));
+    }, Duration.ofSeconds(monitoringIntervalSeconds));
 }

218-218: Consider using Set.of for immutable set creation.

Based on the past review comments, the use of new HashSet<>(List.of(scheduledTask)) is intentional to support task removal. However, consider adding a code comment to explain this design decision.

-        addScheduledExerciseTasks(exercise, lifecycle, new HashSet<>(List.of(scheduledTask)), name);
+        // Using mutable HashSet to support task removal in cleanup operations
+        addScheduledExerciseTasks(exercise, lifecycle, new HashSet<>(List.of(scheduledTask)), name);

279-282: Consider handling empty Optional more explicitly.

The ifPresent usage could be more explicit about what happens when the Optional is empty.

-        participationLifecycleService.scheduleTask(participation, lifecycle, task)
-                .ifPresent(scheduledTask -> addScheduledParticipationTask(participation, lifecycle, new HashSet<>(List.of(scheduledTask)), name));
+        var scheduledTaskOpt = participationLifecycleService.scheduleTask(participation, lifecycle, task);
+        if (scheduledTaskOpt.isEmpty()) {
+            log.debug("Failed to schedule task {} for participation {}", name, participation.getId());
+            return;
+        }
+        addScheduledParticipationTask(participation, lifecycle, new HashSet<>(List.of(scheduledTaskOpt.get())), name);

340-345: Add test-only annotation to clearAllTasks method.

Since this method is for testing purposes only, consider adding the @VisibleForTesting annotation.

+import com.google.common.annotations.VisibleForTesting;

+@VisibleForTesting
 public void clearAllTasks() {
     // ... existing code ...
 }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8915e44 and 32a1f48.

📒 Files selected for processing (4)
  • src/main/java/de/tum/cit/aet/artemis/core/config/TaskSchedulingConfiguration.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/core/service/ScheduleService.java (8 hunks)
  • src/main/java/de/tum/cit/aet/artemis/exercise/service/ExerciseLifecycleService.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseScheduleService.java (17 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/java/de/tum/cit/aet/artemis/core/config/TaskSchedulingConfiguration.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/service/ExerciseLifecycleService.java
🧰 Additional context used
📓 Path-based instructions (2)
src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseScheduleService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/core/service/ScheduleService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

⏰ Context from checks skipped due to timeout of 90000ms (9)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: Call Build Workflow / Build and Push Docker Image
  • GitHub Check: Call Build Workflow / Build .war artifact
  • GitHub Check: client-tests
  • GitHub Check: client-style
  • GitHub Check: server-style
  • GitHub Check: server-tests
  • GitHub Check: Analyse
  • GitHub Check: Mend Security Check
🔇 Additional comments (5)
src/main/java/de/tum/cit/aet/artemis/core/service/ScheduleService.java (1)

56-67: Well-structured record declarations following Java best practices!

The introduction of records improves type safety and reduces boilerplate code. The records are appropriately scoped and follow the single responsibility principle.

src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseScheduleService.java (4)

42-42: LGTM! Clean dependency injection implementation.

The ProfileService integration follows best practices with constructor injection and immutable field declaration.

Also applies to: 100-100, 102-124


136-140: LGTM! Improved profile check using dedicated service.

The change from environment check to ProfileService improves encapsulation and maintainability.


479-480: LGTM! Enhanced logging with better context and consistency.

The logging improvements follow best practices:

  • Appropriate log levels (debug/error)
  • Consistent message format
  • Helpful context for troubleshooting

Also applies to: 488-489, 1021-1023


359-360: Add error handling for invalid individual due dates.

The method assumes individual due dates are valid. Consider adding validation and error handling for null or invalid dates.

Run this script to check for potential null date issues:

Also applies to: 361-378

✅ Verification successful

I'll run additional checks to verify if there is any error handling (e.g. null checks) for individual due dates in the affected file. Please execute the following script:

Once these results are available, we can determine whether additional error handling for invalid individual due dates is required.


The existing null check in the calling method already handles invalid individual due dates.

  • In scheduleParticipationTasks, the code verifies that both the exercise due date and participation.getIndividualDueDate() are non-null before invoking scheduleParticipationWithIndividualDueDate.
  • This pre-check effectively cancels scheduled tasks when an individual due date is absent or invalid, so no additional error handling is required in the method itself.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for potential null date handling in similar methods
rg -A 5 'getIndividualDueDate.*\b(if|assert).*null'

Length of output: 53


Script:

#!/bin/bash
# Check for any usage of getIndividualDueDate and its surrounding context in the file
echo "Context for getIndividualDueDate in ProgrammingExerciseScheduleService.java:"
rg -n -C 5 "getIndividualDueDate" src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseScheduleService.java

# Check the scheduleParticipationWithIndividualDueDate method context to see if any error handling exists
echo "Context for scheduleParticipationWithIndividualDueDate method:"
rg -n -C 5 "scheduleParticipationWithIndividualDueDate" src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseScheduleService.java

# Search for any null validation or error handling (if statements that check for null) around individual due date operations
echo "Searching for null checks near individual due date handling:"
rg -n -C 5 "if.*null" src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseScheduleService.java

Length of output: 15759

@krusche krusche modified the milestones: 7.9.1, 7.9.2 Feb 2, 2025
@krusche
Copy link
Member Author

krusche commented Feb 2, 2025

One e2e test related to locked repositories is failing, I need to look into this first, before we can merge this PR

*/
public record Tuple<X, Y>(X x, Y y) {
public record Tuple<F, S>(F first, S second) implements Serializable {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since we're already changing this i'd suggest renaming it to Pair to make it consistent with conventions of other programming languages. A pair has inherently a first and second member. Tuples should support arbitrarily many members.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
communication Pull requests that affect the corresponding module core Pull requests that affect the corresponding module exercise Pull requests that affect the corresponding module modeling Pull requests that affect the corresponding module programming Pull requests that affect the corresponding module quiz Pull requests that affect the corresponding module ready for review server Pull requests that update Java code. (Added Automatically!) tests
Projects
Status: Ready For Review
Development

Successfully merging this pull request may close these issues.