This is an automated email from the ASF dual-hosted git repository. apkhmv pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push: new 281a00fa34 IGNITE-22333 Fix memory leak (#3818) 281a00fa34 is described below commit 281a00fa34169be8f915e2833bc2617e0dbcd28b Author: Vadim Pakhnushev <8614891+valep...@users.noreply.github.com> AuthorDate: Mon May 27 14:51:46 2024 +0300 IGNITE-22333 Fix memory leak (#3818) --- .../rest/{RestFactory.java => ResourceHolder.java} | 17 +++++++++-------- .../org/apache/ignite/internal/rest/RestFactory.java | 13 +------------ ...RestFactoriesDestroyer.java => ResourceCleaner.java} | 12 ++++++------ .../authentication/IgniteAuthenticationProvider.java | 10 ++++++++-- 4 files changed, 24 insertions(+), 28 deletions(-) diff --git a/modules/rest-api/src/main/java/org/apache/ignite/internal/rest/RestFactory.java b/modules/rest-api/src/main/java/org/apache/ignite/internal/rest/ResourceHolder.java similarity index 54% copy from modules/rest-api/src/main/java/org/apache/ignite/internal/rest/RestFactory.java copy to modules/rest-api/src/main/java/org/apache/ignite/internal/rest/ResourceHolder.java index 6926a2e093..0730bb439f 100644 --- a/modules/rest-api/src/main/java/org/apache/ignite/internal/rest/RestFactory.java +++ b/modules/rest-api/src/main/java/org/apache/ignite/internal/rest/ResourceHolder.java @@ -20,16 +20,17 @@ package org.apache.ignite.internal.rest; import io.micronaut.runtime.Micronaut; /** - * Factory that produces all beans that is necessary for the controller class. + * A resource holder. Implement this interface in the bean class if it has a chain of references to the {@link org.apache.ignite.Ignite} + * instance. */ -public interface RestFactory { +public interface ResourceHolder { /** - * Destroy method. All resources of the factory implementation must be cleaned and all fields must be set to {@code null}. - * The reason of these requirements is Micronaut design. - * {@link Micronaut#start()} store shutdown hook and capture a pointer - * to the embedded application {@link io.micronaut.http.server.netty.NettyEmbeddedServer} and as a result - * {@link io.micronaut.context.ApplicationContext} will never be collected by the GC. - * All rest factories stored in the application context should be cleaned to prevent memory leak. + * This method will be called when the bean is destroyed. All resources of the resource holder must be cleaned and all fields must be + * set to {@code null}. The reason of these requirements is Micronaut design. {@link Micronaut#start()} stores shutdown hook and + * captures a pointer to the embedded application {@code io.micronaut.http.server.netty.NettyEmbeddedServer} and as a result + * {@link io.micronaut.context.ApplicationContext} will never be collected by the GC. All beans stored in the application context should + * be cleaned to prevent memory leak. */ + void cleanResources(); } diff --git a/modules/rest-api/src/main/java/org/apache/ignite/internal/rest/RestFactory.java b/modules/rest-api/src/main/java/org/apache/ignite/internal/rest/RestFactory.java index 6926a2e093..31b854ba90 100644 --- a/modules/rest-api/src/main/java/org/apache/ignite/internal/rest/RestFactory.java +++ b/modules/rest-api/src/main/java/org/apache/ignite/internal/rest/RestFactory.java @@ -17,19 +17,8 @@ package org.apache.ignite.internal.rest; -import io.micronaut.runtime.Micronaut; - /** * Factory that produces all beans that is necessary for the controller class. */ -public interface RestFactory { - /** - * Destroy method. All resources of the factory implementation must be cleaned and all fields must be set to {@code null}. - * The reason of these requirements is Micronaut design. - * {@link Micronaut#start()} store shutdown hook and capture a pointer - * to the embedded application {@link io.micronaut.http.server.netty.NettyEmbeddedServer} and as a result - * {@link io.micronaut.context.ApplicationContext} will never be collected by the GC. - * All rest factories stored in the application context should be cleaned to prevent memory leak. - */ - void cleanResources(); +public interface RestFactory extends ResourceHolder { } diff --git a/modules/rest/src/main/java/org/apache/ignite/internal/rest/RestFactoriesDestroyer.java b/modules/rest/src/main/java/org/apache/ignite/internal/rest/ResourceCleaner.java similarity index 79% rename from modules/rest/src/main/java/org/apache/ignite/internal/rest/RestFactoriesDestroyer.java rename to modules/rest/src/main/java/org/apache/ignite/internal/rest/ResourceCleaner.java index 58051f6ccb..ddb0f8b40d 100644 --- a/modules/rest/src/main/java/org/apache/ignite/internal/rest/RestFactoriesDestroyer.java +++ b/modules/rest/src/main/java/org/apache/ignite/internal/rest/ResourceCleaner.java @@ -24,17 +24,17 @@ import org.apache.ignite.internal.logger.IgniteLogger; import org.apache.ignite.internal.logger.Loggers; /** - * Destroyer of any rest factory {@link RestFactory}. + * Cleans up resources of destroyed beans. */ @Singleton -public class RestFactoriesDestroyer implements BeanDestroyedEventListener<RestFactory> { - private static final IgniteLogger LOG = Loggers.forClass(RestFactoriesDestroyer.class); +public class ResourceCleaner implements BeanDestroyedEventListener<ResourceHolder> { + private static final IgniteLogger LOG = Loggers.forClass(ResourceCleaner.class); @Override - public void onDestroyed(BeanDestroyedEvent<RestFactory> event) { - RestFactory bean = event.getBean(); + public void onDestroyed(BeanDestroyedEvent<ResourceHolder> event) { + ResourceHolder bean = event.getBean(); if (bean != null) { - LOG.debug("Destroy rest factory " + bean); + LOG.debug("Cleaning bean {}", bean); bean.cleanResources(); } } diff --git a/modules/rest/src/main/java/org/apache/ignite/internal/rest/authentication/IgniteAuthenticationProvider.java b/modules/rest/src/main/java/org/apache/ignite/internal/rest/authentication/IgniteAuthenticationProvider.java index c229d420ba..1f57b1acc6 100644 --- a/modules/rest/src/main/java/org/apache/ignite/internal/rest/authentication/IgniteAuthenticationProvider.java +++ b/modules/rest/src/main/java/org/apache/ignite/internal/rest/authentication/IgniteAuthenticationProvider.java @@ -22,6 +22,7 @@ import io.micronaut.security.authentication.AuthenticationProvider; import io.micronaut.security.authentication.AuthenticationRequest; import io.micronaut.security.authentication.AuthenticationResponse; import io.micronaut.security.authentication.UsernamePasswordCredentials; +import org.apache.ignite.internal.rest.ResourceHolder; import org.apache.ignite.internal.security.authentication.AuthenticationManager; import org.apache.ignite.internal.security.authentication.UserDetails; import org.apache.ignite.internal.security.authentication.UsernamePasswordRequest; @@ -33,8 +34,8 @@ import reactor.core.publisher.FluxSink; /** * Implementation of {@link AuthenticationProvider}. Delegates authentication to {@link AuthenticationManager}. */ -public class IgniteAuthenticationProvider implements AuthenticationProvider { - private final AuthenticationManager authenticationManager; +public class IgniteAuthenticationProvider implements AuthenticationProvider, ResourceHolder { + private AuthenticationManager authenticationManager; IgniteAuthenticationProvider(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; @@ -69,4 +70,9 @@ public class IgniteAuthenticationProvider implements AuthenticationProvider { throw new IllegalArgumentException("Unsupported authentication request type: " + authenticationRequest.getClass()); } } + + @Override + public void cleanResources() { + authenticationManager = null; + } }