Skip to content

stream auto trimming , no need for dedicated thread#88

Merged
sanjomo merged 2 commits intomainfrom
redis-stream-auto-trim
Dec 17, 2025
Merged

stream auto trimming , no need for dedicated thread#88
sanjomo merged 2 commits intomainfrom
redis-stream-auto-trim

Conversation

@sanjomo
Copy link
Member

@sanjomo sanjomo commented Dec 15, 2025

Description

No trimming logic needed

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Code refactoring
  • Test improvements
  • Build/tooling changes

Related Issue

Closes #(issue number)

Changes Made

Testing

  • All existing tests pass
  • New tests added for new functionality
  • Tests pass locally with mvn test
  • Integration tests pass (if applicable)

Checklist

  • Code follows project coding standards
  • Self-review completed
  • Code is commented where necessary
  • Documentation updated (if needed)
  • Commit messages follow conventional format
  • No merge conflicts
  • [] All CI checks pass

Additional Notes

Any additional information, screenshots, or context that reviewers should know.

Summary by CodeRabbit

  • Refactor
    • Removed scheduled trimming logic; stream length is now enforced at publish time.
    • Simplified constructor and builder interfaces by dropping the trimming interval parameter.
    • Cleaned up shutdown behavior by removing trimmed-executor shutdown handling.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 15, 2025

Walkthrough

Removed scheduled Redis stream trimming from RedisStreamEventStore; trimming is now applied during publish calls via .trimNonStrict().maxLen(streamMaxLength).noLimit(). Constructor and Builder signatures were simplified to drop the trimEvery parameter and related fields.

Changes

Cohort / File(s) Summary
RedisStreamEventStore & Builder
netty-socketio-core/src/main/java/com/socketio4j/socketio/store/redis_stream/RedisStreamEventStore.java
Eliminated scheduled trimming: removed trimEvery field, trimExecutor, initTrimmer, trimAll, trimOne, and related imports. Constructor no longer accepts trimEvery. publish0 now uses .trimNonStrict().maxLen(streamMaxLength).noLimit() when adding to streams. Builder dropped trimEvery field and its setter; build() passes only streamMaxLength. Shutdown no longer attempts to stop a trim executor.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Verify all callsites and tests updated for the changed constructor signature.
  • Ensure no resource leak remains (confirm no hidden executor references).
  • Review publish path to confirm trimming semantics match intended behavior.

Possibly related PRs

  • redis-stream-adapter #78 — Modifies the same RedisStreamEventStore and Builder; adds trimming fields/logic that this change removes or replaces.

Poem

I hopped to the stream with a grin so merry,
No scheduler pounding — I trim as I carry,
Fewer gears to wind,
Just lean publish-kind,
A rabbit-approved change — swift and airy! 🐇✂️

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ⚠️ Warning The PR description is incomplete. While it identifies the change as code refactoring and marks some checklist items, critical sections lack detail. Add specific details to the 'Changes Made' section explaining what was refactored and why. Provide a concrete issue number in the 'Related Issue' field or remove it if not applicable.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: removing the dedicated trimming thread by using Redis stream's built-in auto-trimming feature.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch redis-stream-auto-trim

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@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 (1)
netty-socketio-core/src/main/java/com/socketio4j/socketio/store/redis_stream/RedisStreamEventStore.java (1)

384-392: Clean up leftover trimEvery in Builder

The constructor and build() no longer accept a trim interval, but Builder still declares a Duration trimEvery field that is never set or used; consider removing it (and any related comments/docs) so the builder surface matches the actual configuration options.

Also applies to: 440-448

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a005618 and ae56c8c.

📒 Files selected for processing (1)
  • netty-socketio-core/src/main/java/com/socketio4j/socketio/store/redis_stream/RedisStreamEventStore.java (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: build (21) / build
  • GitHub Check: build (17) / build
  • GitHub Check: build (25) / build
  • GitHub Check: qodana
  • GitHub Check: Analyze (java-kotlin)
  • GitHub Check: Analyze (java-kotlin)
🔇 Additional comments (2)
netty-socketio-core/src/main/java/com/socketio4j/socketio/store/redis_stream/RedisStreamEventStore.java (2)

98-136: Constructor defaulting for streamMaxLength looks good

Using a nullable Integer and normalizing null/non-positive values to DEFAULT_MAX_LEN with a warning keeps direct construction and the builder behavior aligned; no correctness issues stand out.


180-188: Inline stream trimming on publish changes retention/perf behavior

Moving trimming into .add(StreamAddArgs.entry(...).trimNonStrict().maxLen(streamMaxLength).noLimit()) means every publish now enforces streamMaxLength and may trim immediately; please confirm this matches your intended retention policy and doesn’t introduce unwanted latency at high write rates.

@github-actions
Copy link

github-actions bot commented Dec 15, 2025

Qodana for JVM

45 new problems were found

Inspection name Severity Problems
Vulnerable declared dependency 🔶 Warning 8
Pointless arithmetic expression 🔶 Warning 7
Comparison of 'short' and 'char' values 🔶 Warning 2
Result of method call ignored 🔶 Warning 2
Busy wait 🔶 Warning 1
Injection point with ambiguous dependencies 🔶 Warning 1
Constant values 🔶 Warning 1
Number of placeholders does not match number of arguments in logging call 🔶 Warning 1
Unnecessary 'null' check before method call 🔶 Warning 1
Wrapper type may be primitive 🔶 Warning 1
Non-distinguishable logging calls ◽️ Notice 11
Vulnerable declared dependency ◽️ Notice 9

☁️ View the detailed Qodana report

Detected 123 dependencies

Third-party software list

This page lists the third-party software dependencies used in project

Dependency Version Licenses
aesh 2.8.2 Apache-2.0
annotations 26.0.2-1 Apache-2.0
arc-processor 3.30.1 Apache-2.0
arc 3.30.1 Apache-2.0
asm-analysis 9.9 BSD-3-Clause
asm-commons 9.9 BSD-3-Clause
asm-tree 9.9 BSD-3-Clause
asm-util 9.9 BSD-3-Clause
asm 9.9 BSD-3-Clause
byte-buddy 1.17.7 Apache-2.0
cache-api 1.1.1 Apache-2.0
commons-codec 1.20.0 Apache-2.0
commons-compress 1.28.0 Apache-2.0
commons-io 2.21.0 Apache-2.0
commons-logging-jboss-logging 1.0.0.final Apache-2.0
commons-logging 1.3.5 Apache-2.0
crac 1.5.0 BSD-2-Clause
gizmo 1.9.0 Apache-2.0
gizmo2 2.0.0.beta10 Apache-2.0
hazelcast 5.2.5 MIT
jackson-annotations 2.20 Apache-2.0
jackson-core 2.20.1 Apache-2.0
jackson-databind 2.20.1 Apache-2.0
jackson-dataformat-yaml 2.20.0 AML
jackson-datatype-jsr310 2.20.0 Apache-2.0
jakarta.annotation-api 2.1.1 Classpath-exception-2.0
EPL-2.0
GPL-2.0-only
jakarta.annotation-api 3.0.0 Classpath-exception-2.0
EPL-2.0
GPL-2.0-only
jakarta.el-api 6.0.1 Classpath-exception-2.0
EPL-2.0
GPL-2.0-only
jakarta.enterprise.cdi-api 4.1.0 Apache-2.0
jakarta.enterprise.lang-model 4.1.0 Apache-2.0
jakarta.inject-api 2.0.1 Apache-2.0
jakarta.interceptor-api 2.2.0 Classpath-exception-2.0
EPL-2.0
GPL-2.0-only
jakarta.json-api 2.1.3 Classpath-exception-2.0
EPL-2.0
GPL-2.0-only
jakarta.transaction-api 2.0.1 Classpath-exception-2.0
EPL-2.0
GPL-2.0-only
jandex-gizmo2 3.5.2 Apache-2.0
jandex 3.5.2 Apache-2.0
jansi 2.4.0 Apache-2.0
jboss-logging 3.6.1.final Apache-2.0
jboss-logmanager 3.1.2.final Apache-2.0
jboss-threads 3.9.1 Apache-2.0
jctools-core 4.0.5 Apache-2.0
jdk-classfile-backport 25.1 GPL-2.0-only
jodd-util 6.3.0 BSD-2-Clause
jspecify 1.0.0 Apache-2.0
jul-to-slf4j 2.0.17 MIT
kryo 5.6.2 BSD-3-Clause
log4j-api 2.25.2 Apache-2.0
log4j-to-slf4j 2.25.2 Apache-2.0
micrometer-commons 1.16.0 Apache-2.0
micrometer-observation 1.16.0 Apache-2.0
micronaut-aop 4.10.2 Apache-2.0
micronaut-context-propagation 4.10.2 Apache-2.0
micronaut-context 4.10.2 Apache-2.0
micronaut-core-reactive 4.10.2 Apache-2.0
micronaut-core 4.10.2 Apache-2.0
micronaut-discovery-core 4.10.2 Apache-2.0
micronaut-http-server 4.10.2 Apache-2.0
micronaut-http 4.10.2 Apache-2.0
micronaut-inject 4.10.2 Apache-2.0
micronaut-retry 4.10.2 Apache-2.0
micronaut-router 4.10.2 Apache-2.0
micronaut-runtime 4.10.2 Apache-2.0
microprofile-config-api 3.1 Apache-2.0
microprofile-context-propagation-api 1.3 Apache-2.0
minlog 1.3.1 BSD-3-Clause
mutiny 3.0.1 Apache-2.0
nativeimage 23.1.2 UPL-1.0
netty-common 4.2.7.final Apache-2.0
parsson 1.1.7 Classpath-exception-2.0
EPL-2.0
GPL-2.0-only
quarkus-arc-deployment 3.30.1 Apache-2.0
quarkus-arc-dev 3.30.1 Apache-2.0
quarkus-arc 3.30.1 Apache-2.0
quarkus-bootstrap-app-model 3.30.1 Apache-2.0
quarkus-bootstrap-core 3.30.1 Apache-2.0
quarkus-bootstrap-runner 3.30.1 Apache-2.0
quarkus-builder 3.30.1 Apache-2.0
quarkus-class-change-agent 3.30.1 Apache-2.0
quarkus-classloader-commons 3.30.1 Apache-2.0
quarkus-core-deployment 3.30.1 Apache-2.0
quarkus-core 3.30.1 Apache-2.0
quarkus-development-mode-spi 3.30.1 Apache-2.0
quarkus-devui-deployment-spi 3.30.1 Apache-2.0
quarkus-fs-util 1.2.0 Apache-2.0
quarkus-hibernate-validator-spi 3.30.1 Apache-2.0
quarkus-ide-launcher 3.30.1 Apache-2.0
quarkus-smallrye-context-propagation-spi 3.30.1 Apache-2.0
reactive-streams 1.0.4 MIT-0
reactor-core 3.6.2 Apache-2.0
reactor-core 3.7.9 Apache-2.0
readline 2.6 Apache-2.0
redisson 3.52.0 Apache-2.0
reflectasm 1.11.9 BSD-3-Clause
rxjava 3.1.8 Apache-2.0
slf4j-api 2.0.17 MIT
slf4j-jboss-logmanager 2.0.2.final Apache-2.0
smallrye-common-annotation 2.14.0 Apache-2.0
smallrye-common-classloader 2.14.0 Apache-2.0
smallrye-common-constraint 2.14.0 Apache-2.0
smallrye-common-cpu 2.14.0 Apache-2.0
smallrye-common-expression 2.14.0 Apache-2.0
smallrye-common-function 2.14.0 Apache-2.0
smallrye-common-io 2.14.0 Apache-2.0
smallrye-common-net 2.14.0 Apache-2.0
smallrye-common-os 2.14.0 Apache-2.0
smallrye-common-process 2.14.0 Apache-2.0
smallrye-common-ref 2.14.0 Apache-2.0
smallrye-common-resource 2.14.0 Apache-2.0
smallrye-config-common 3.14.1 Apache-2.0
smallrye-config-core 3.14.1 Apache-2.0
smallrye-config 3.14.1 Apache-2.0
snakeyaml 2.4 Apache-2.0
snakeyaml 2.5 Apache-2.0
spring-aop 7.0.1 Apache-2.0
spring-beans 7.0.1 Apache-2.0
spring-boot-autoconfigure 4.0.0 Apache-2.0
spring-boot-starter-logging 4.0.0 Apache-2.0
spring-boot-starter 4.0.0 Apache-2.0
spring-boot 4.0.0 Apache-2.0
spring-context 7.0.1 Apache-2.0
spring-core 7.0.1 Apache-2.0
spring-expression 7.0.1 Apache-2.0
wildfly-common 2.0.1 Apache-2.0
word 23.1.2 UPL-1.0
Contact Qodana team

Contact us at qodana-support@jetbrains.com

Copy link
Contributor

@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 (1)
netty-socketio-core/src/main/java/com/socketio4j/socketio/store/redis_stream/RedisStreamEventStore.java (1)

239-281: Lifecycle of running flag may prevent reuse after all listeners unsubscribe

pollLoop exits early when running is false (Line 241), and unsubscribe0 sets running to false once listeners becomes empty (Lines 328‑330). There is no corresponding reset of running to true when new subscribers are added, so if the store is reused after all listeners are removed, newly created pollers will immediately exit and never resume reading.

If reuse after “all unsubscribed” is a valid scenario in this project, consider:

  • Either not flipping running to false in unsubscribe0, and relying solely on shutdown0 to stop the store, or
  • Explicitly setting running back to true in subscribe0 before (or when) ensurePoller is called.

Also applies to: 318-331

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ae56c8c and b89c3d9.

📒 Files selected for processing (1)
  • netty-socketio-core/src/main/java/com/socketio4j/socketio/store/redis_stream/RedisStreamEventStore.java (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: build (17) / build
  • GitHub Check: build (21) / build
  • GitHub Check: build (25) / build
  • GitHub Check: qodana
  • GitHub Check: Analyze (java-kotlin)
  • GitHub Check: Analyze (java-kotlin)
🔇 Additional comments (3)
netty-socketio-core/src/main/java/com/socketio4j/socketio/store/redis_stream/RedisStreamEventStore.java (3)

97-138: Constructor defaulting for streamMaxLength is consistent and safe

The updated constructor cleanly drops the trim interval and keeps streamMaxLength as the single trimming knob, with sensible defaulting when null/≤0 and clear WARN logs. No correctness issues spotted; callers using the Builder will still get the same defaulting behavior.


439-447: Builder wiring to new constructor signature is coherent

The Builder’s build() now forwards streamMaxLen as the last argument to the trimmed constructor, which aligns with the new signature and keeps the defaulting behavior in the constructor. No issues here; call sites using the Builder should compile cleanly and continue to get defaults when streamMaxLen is not set.


179-187: Implementation correctly uses Redisson 3.52.0 stream trimming API

The StreamAddArgs.entry(...).trimNonStrict().maxLen(streamMaxLength).noLimit() pattern is fully supported in Redisson 3.52.0. This correctly maps to Redis XADD ... MAXLEN ~ streamMaxLength, trimming oldest entries approximately on each publish. The API, behavior, and version constraint are all verified as sound.

The non-strict (approximate) trimming trade-off is acceptable for bounded stream management without a dedicated trim thread. If strict enforcement becomes necessary, switching to trimStrict() is straightforward.

@sanjomo sanjomo merged commit 530f5b6 into main Dec 17, 2025
10 checks passed
@sanjomo sanjomo deleted the redis-stream-auto-trim branch December 17, 2025 07:11
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.

1 participant