feat(audit): wire async-queue-capacity property to a bounded executor#22
Merged
Conversation
Follow-up #4/5 to the contract-gap series. #18 exposed `devslab.kit.audit.async-queue-capacity` on the Settings endpoint but the property wasn't actually wired to anything — the audit publisher was synchronous. This PR makes it real. Property -------- - DevslabKitProperties.Audit gains asyncQueueCapacity (default 1024). Settings endpoint already surfaces this value, so the number admins see on the Settings page is now the number the runtime actually uses. Executor -------- - AuditAutoConfiguration registers a ThreadPoolTaskExecutor bean named "devslabKitAuditPersistenceExecutor": * core=1 / max=1 — audit writes are tiny, one worker is enough and avoids starving the main pool. * bounded LinkedBlockingQueue sized from devslab.kit.audit.async-queue-capacity. * CallerRunsPolicy on rejection: when the queue saturates, the request thread runs the write inline. Slow request, but no audit row is ever lost. * waitForTasksToCompleteOnShutdown=true with a 10s grace, so in-flight events flush during graceful shutdown. Publisher --------- - DefaultAuditEventPublisher now takes an Executor in its constructor: * persistence write (AuditLogService.record) runs on the executor — request thread returns without the DB round-trip. * Spring ApplicationEventPublisher fanout stays synchronous so @eventlistener handlers on the request thread (e.g. metrics counters) still see the event before the request returns. Backward compatibility ---------------------- - DefaultAuditEventPublisher constructor signature changed (added Executor). The only call-site is AuditAutoConfiguration which is updated in the same PR. No consumer code outside this repo constructs DefaultAuditEventPublisher directly today.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up #4/5. #18 exposed
devslab.kit.audit.async-queue-capacityon the Settings endpoint but the property wasn't actually wired to anything — the audit publisher was synchronous. This PR makes it real.Property
DevslabKitProperties.Audit.asyncQueueCapacity(default1024). The Settings endpoint already surfaces this value, so the number admins see on the page is now the number the runtime actually uses.Executor
AuditAutoConfigurationregisters aThreadPoolTaskExecutorbean nameddevslabKitAuditPersistenceExecutor:core=1/max=1— audit writes are tiny; one worker is enough and avoids starving the main pool.LinkedBlockingQueuesized fromdevslab.kit.audit.async-queue-capacity.CallerRunsPolicyon rejection: when the queue saturates, the request thread runs the write inline. Slow request, but no audit row is ever lost.waitForTasksToCompleteOnShutdown=truewith a 10s grace, so in-flight events flush during graceful shutdown.Publisher
DefaultAuditEventPublisherconstructor now takes anExecutor:AuditLogService.record) runs on the executor — request thread returns without the DB round-trip.ApplicationEventPublisherfanout stays synchronous so@EventListenerhandlers on the request thread (e.g. metrics counters) still see the event before the request returns.Backward compatibility
DefaultAuditEventPublisherconstructor signature changed (addedExecutor). The only call-site isAuditAutoConfiguration, updated in this same PR. No consumer code outside this repo constructsDefaultAuditEventPublisherdirectly today.Test plan
./gradlew buildgreen (55 tasks; sample-app context loads and runs the smoke test using the new async publisher)platform_audit_log