Closed vttranlina closed 1 year ago
MyIDE
I guess it relates to io.lettuce.core.resource.ClientResources
, which has not been closed correctly
So I tried to modify org.apache.james.rate.limiter.redis.RedisRateLimiterFactory
is bellow
but I can't get better
class RedisRateLimiterFactory @Inject()(redisConfiguration: RedisRateLimiterConfiguration) extends RateLimiterFactory {
var resources: ClientResources = _
val rateLimitjFactory: AbstractRequestRateLimiterFactory[RedisSlidingWindowRequestRateLimiter] =
if (redisConfiguration.isCluster) {
val resourceBuilder = ClientResources.builder()
.threadFactoryProvider(poolName => NamedThreadFactory.withName(s"redis-driver-$poolName"))
redisConfiguration.ioThreads.foreach(value => resourceBuilder.ioThreadPoolSize(value))
redisConfiguration.workerThreads.foreach(value =>resourceBuilder.computationThreadPoolSize(value))
new RedisClusterRateLimiterFactory(RedisClusterClient.create(resourceBuilder.build(),
redisConfiguration.redisURI.value.asJava))
} else {
val resourceBuilder = ClientResources.builder()
.threadFactoryProvider(poolName => NamedThreadFactory.withName(s"redis-driver-$poolName"))
redisConfiguration.ioThreads.foreach(value => resourceBuilder.ioThreadPoolSize(value))
redisConfiguration.workerThreads.foreach(value => resourceBuilder.computationThreadPoolSize(value))
resources = resourceBuilder.build();
new RedisSingleInstanceRateLimitjFactory(RedisClient.create(resources, redisConfiguration.redisURI.value.last))
}
def preDestroy(): Unit = {
resources.shutdown()
}
May help to get some insights from the heap dump: https://heaphero.io/heap-report-wc.jsp?p=RThCZ0lOakJ3K2dCd3FiSEc4VEhscytQdnNlRUVoSExkWjdwdlY1T01IUzlVR1JsaGU4dFpzUGtZc1BFdE5vSnQ0SXNuNkNaMzhOdWM2N2hzdVBTZFE9PQ==
5,094 instances of "io.netty.buffer.PoolThreadCache", loaded by "jdk.internal.loader.ClassLoaders$AppClassLoader @ 0xc0b26618" occupy 705,688,952 (66.28%) bytes
My guess: We initiate multiple times the lettuce driver in tests, and in somehow the driver is not freed after each test.
@BeforeEach
redisRateLimiterFactory = new RedisRateLimiterFactory(RedisRateLimiterConfiguration.from(redis.redisURI().toString, isCluster = false))
Not a big deal in tests IMO.
But in production RedisRateLimiterFactory
should be in SINGLETON scope IMO.
local issue
Description of the bug
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "lettuce-eventExecutorLoop***
Reproduction Steps
Run repeat until failure
EnforceRateLimitingPlanTest
(with my PC, it will throw when tests passed repeat at 2xx)Additional information
Memory Heap dump file: https://tdrive.linagora.com/shared/111111114AxHLNjGvEGJpA/drive/2rCqjwQPJJivJWemudbsoj/t/26373379ca85b4a6ffdb71a425ad6dd3243c2bba
Test run log test-run.log
Another log:
Redis log: (0 clients connected)
The Default IDE setting when run Junit: xms=512Mb xmx=1024Mb