Skip to content

Refreshable beans not being invalidated in function environment #433

@Sh1tH4pp3ns

Description

@Sh1tH4pp3ns

Expected Behavior

As per documentation: https://github.com/micronaut-projects/micronaut-crac/blob/2.7.x/src/main/docs/guide/refresh.adoc?plain=1#L1
I expect all beans which are annotated with @Refreshable to be invalidated when reaching a checkpoint.

Possible use case would be AWS Lambda with SnapStart.

Actual Behaviour

In tests this is working, due to environment test also being active.
However this will not work in production when using environment function.

Reason being these lines in RefreshScopeCondition: https://github.com/micronaut-projects/micronaut-core/blame/4.10.x/context/src/main/java/io/micronaut/runtime/context/scope/refresh/RefreshScopeCondition.java#L45-L48

Steps To Reproduce

import io.micronaut.context.ApplicationContext;
import io.micronaut.runtime.context.scope.refresh.RefreshScope;
import java.util.Optional;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

class RefreshScopePresentTest {

  @Test
  void refreshScopePresentInFunctionAndTest() {
    refreshScopePresent("function", "test");
  }

  @Test
  void refreshScopePresentInFunction() {
    refreshScopePresent("function");
  }

  void refreshScopePresent(String... environments) {
    try (ApplicationContext applicationContext = ApplicationContext.run(environments)) {
      Optional<RefreshScope> refreshScope = applicationContext.findBean(RefreshScope.class);
      Assertions.assertTrue(refreshScope.isPresent());
    }
  }
}

Since RefreshScope isn't present with only environment function, there will be no refresh happening.
Arguably a topic for the core repository, but since CRaC is heavily implying a use case where this becomes a problem, I thought this would be the better place to report.

Ugly workaround to get rid of RefreshScopeCondition:

import io.micronaut.context.BeanContext;
import io.micronaut.context.annotation.Replaces;
import io.micronaut.runtime.context.scope.refresh.RefreshScope;
import jakarta.inject.Singleton;

@Singleton
@Replaces(RefreshScope.class)
public class RefreshReplacement extends RefreshScope {

  public RefreshReplacement(BeanContext beanContext) {
    super(beanContext);
  }
}

Environment Information

implementation("io.micronaut.crac:micronaut-crac:2.7.0")

Example Application

No response

Version

4.9.1

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions