Skip to content

Conversation

yitingb
Copy link
Member

@yitingb yitingb commented Jun 17, 2025

Issue #, if available:

Description of changes:
Buffer:
Added configurable buffer interval seconds via the bufferIntervalSec configuration parameter. The buffer accumulates log processing state updates and flushes them to config.tlog periodically.

Implementation of Buffer:
PeriodicBuffer class uses ScheduledExecutorService to control the periodic flush action.

Implementation of Buffer on LogManager:
The buffer in LogManager is a duplication Map of both lastComponentUploadedLogFileInstantMap and processingFilesInformation, the buffer is initialized from the constructor, taking the default value periodicUploadIntervalSec. When upload logs finished, the buffer copies the value from updated maps, which stores the Log information for each component. When the times up, then flush the current buffers to config.tlog

Why is this change necessary:
This change improves system performance by allowing customers to control how frequently log processing state is persisted to disk. By setting appropriate buffer intervals, customers can reduce disk I/O operations while ensuring log processing state is preserved at reasonable intervals.

How was this change tested:

Any additional information or context required to review the change:

Checklist:

  • Updated the README if applicable
  • Updated or added new unit tests
  • Updated or added new integration tests
  • Updated or added new end-to-end tests

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

buffer.clear();

logger.atDebug().log("Successfully flushed buffer '{}'", bufferName);
} catch (Exception e) {
Copy link
Member

Choose a reason for hiding this comment

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

Recommendation generated by Amazon CodeGuru Reviewer. Leave feedback on this recommendation by replying to the comment or by reacting to the comment using emoji.

It appears that your code handles a broad swath of exceptions in the catch block, potentially trapping dissimilar issues or problems that should not be dealt with at this point in the program.

Learn more

}

// Shutdown the scheduler
scheduler.shutdownNow();
Copy link
Member

Choose a reason for hiding this comment

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

Recommendation generated by Amazon CodeGuru Reviewer. Leave feedback on this recommendation by replying to the comment or by reacting to the comment using emoji.

Using shutdownNow() causes abrupt termination of thread pool tasks, which can lead to resource leaks, data corruption, and incomplete operations as threads are forcefully interrupted mid-execution. To avoid these risks, first call shutdown() to reject new tasks, then use awaitTermination() with a timeout to allow existing tasks to complete. Check awaitTermination()'s return value and only use shutdownNow() as a last resort if graceful shutdown fails. See the following diffs on GitHub that make this code change: diff1, diff2

Learn more: ExecutorService in the Java Platform, Standard Edition 8 API Specification

}

// Configure with short intervals for faster testing
Map<String, Object> additionalConfig = new HashMap<>();

Check failure

Code scanning / CodeQL

Container contents are never accessed Error

The contents of this container are never accessed.

Copilot Autofix

AI 4 months ago

To fix the issue, we need to ensure that the additionalConfig map is either removed if it is genuinely unnecessary or its contents are accessed explicitly. If the setupKernel method uses the map, we should update the code to make this usage clear. For example, we can pass additionalConfig as an argument to setupKernel and verify its usage within the method.

Suggested changeset 1
src/integrationtests/java/com/aws/greengrass/integrationtests/logmanager/LogManagerPeriodicBufferIntegrationTest.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/integrationtests/java/com/aws/greengrass/integrationtests/logmanager/LogManagerPeriodicBufferIntegrationTest.java b/src/integrationtests/java/com/aws/greengrass/integrationtests/logmanager/LogManagerPeriodicBufferIntegrationTest.java
--- a/src/integrationtests/java/com/aws/greengrass/integrationtests/logmanager/LogManagerPeriodicBufferIntegrationTest.java
+++ b/src/integrationtests/java/com/aws/greengrass/integrationtests/logmanager/LogManagerPeriodicBufferIntegrationTest.java
@@ -310,3 +310,3 @@
 
-        setupKernel(tempDirectoryPath, "smallPeriodicIntervalUserComponentConfig.yaml");
+        setupKernel(tempDirectoryPath, "smallPeriodicIntervalUserComponentConfig.yaml", additionalConfig);
 
EOF
@@ -310,3 +310,3 @@

setupKernel(tempDirectoryPath, "smallPeriodicIntervalUserComponentConfig.yaml");
setupKernel(tempDirectoryPath, "smallPeriodicIntervalUserComponentConfig.yaml", additionalConfig);

Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
// Shutdown the scheduler
scheduler.shutdown();
try {
if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {
Copy link
Member

Choose a reason for hiding this comment

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

Recommendation generated by Amazon CodeGuru Reviewer. Leave feedback on this recommendation by replying to the comment or by reacting to the comment using emoji.

These configs are flagged under GS-Tech Static config campaign and is considered to be a violation. Please migrate these configs


logger.atInfo().log("Initializing config update buffers with interval: {} seconds", bufferIntervalSeconds);

// Buffer for processing files information
Copy link
Member

Choose a reason for hiding this comment

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

do we need separate buffers?

// Create a named thread factory for better debugging
ThreadFactory namedThreadFactory = runnable -> {
Thread thread = new Thread(runnable, "PeriodicBuffer-" + bufferName + "-Flusher");
thread.setDaemon(true);
Copy link
Member

Choose a reason for hiding this comment

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

why this?

return thread;
};

this.scheduler = Executors.newSingleThreadScheduledExecutor(namedThreadFactory);
Copy link
Member

Choose a reason for hiding this comment

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

don't we have a ScheduledExecutorService in nucleus?

@yitingb yitingb closed this Jun 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants