Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Close resource and update provider status #65

Merged
merged 1 commit into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import io.github.lavenderses.aws_app_config_openfeature_provider.parser.StringAttributeParser;
import io.github.lavenderses.aws_app_config_openfeature_provider.proxy.AwsAppConfigProxy;
import io.github.lavenderses.aws_app_config_openfeature_provider.proxy.AwsAppConfigProxyBuilder;
import jakarta.annotation.PostConstruct;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand All @@ -34,7 +35,7 @@
/**
* Service layer class for AWS AppConfig.
*/
final class AwsAppConfigClientService {
final class AwsAppConfigClientService implements AutoCloseable {

private static final Logger log = LoggerFactory.getLogger(AwsAppConfigClientService.class);

Expand Down Expand Up @@ -114,6 +115,20 @@ final class AwsAppConfigClientService {
objectAttributeParser = new ObjectAttributeParser();
}

@Override
public void close() throws Exception {
appConfigState.set(AwsAppConfigState.SHUTTING_DOWN);

awsAppConfigProxy.close();

appConfigState.set(AwsAppConfigState.SHUT_DOWNED);
}

void initialize() {
appConfigState.set(AwsAppConfigState.PREPARING);
appConfigState.set(AwsAppConfigState.READY);
}

@NotNull
AwsAppConfigState state() {
return appConfigState.get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.List;

import io.github.lavenderses.aws_app_config_openfeature_provider.evaluation_value.EvaluationValue;
import io.github.lavenderses.aws_app_config_openfeature_provider.exception.ProviderCloseException;
import io.github.lavenderses.aws_app_config_openfeature_provider.meta.Normative;
import io.github.lavenderses.aws_app_config_openfeature_provider.meta.Requirements;
import org.jetbrains.annotations.NotNull;
Expand All @@ -26,6 +27,8 @@
)
public final class AwsAppConfigFeatureProvider implements FeatureProvider {

private static final String META_NAME = "AwsAppConfigFeatureProvider";

@NotNull
private final AwsAppConfigClientService awsAppConfigClientService;

Expand All @@ -49,8 +52,21 @@ public AwsAppConfigFeatureProvider(@Nullable final AwsAppConfigClientOptions opt
);
}

@Override
public void initialize(EvaluationContext evaluationContext) throws Exception {
FeatureProvider.super.initialize(evaluationContext);

awsAppConfigClientService.initialize();
}

@Override
public void shutdown() {
try {
awsAppConfigClientService.close();
} catch (final Exception e) {
throw new ProviderCloseException("failed to close client service", e);
}

FeatureProvider.super.shutdown();
}

Expand All @@ -60,16 +76,15 @@ public ProviderState getState() {
return awsAppConfigClientService.state().asProviderState();
}

@Requirements(
number = "2.2.1",
kind = Normative.MUST,
by = META_NAME
)
@NotNull
@Override
public Metadata getMetadata() {
// TODO
return new Metadata() {
@Override
public String getName() {
return "";
}
};
return () -> META_NAME;
}

@NotNull
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.github.lavenderses.aws_app_config_openfeature_provider.exception;

import org.jetbrains.annotations.Nullable;

public class AwsAppConfigProviderException extends RuntimeException {

public AwsAppConfigProviderException(@Nullable final String message, @Nullable final Exception e) {
super(message, e);
}

public AwsAppConfigProviderException(@Nullable final String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.github.lavenderses.aws_app_config_openfeature_provider.exception;

import org.jetbrains.annotations.Nullable;

public final class ProviderCloseException extends AwsAppConfigProviderException {

public ProviderCloseException(@Nullable final String message, @Nullable final Exception e) {
super(message, e);
}

public ProviderCloseException(@Nullable final String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.github.lavenderses.aws_app_config_openfeature_provider.exception;

import org.jetbrains.annotations.Nullable;

public class ScheduledTaskExecutorCloseException extends AwsAppConfigProviderException {

public ScheduledTaskExecutorCloseException(@Nullable final String message, @Nullable final Exception e) {
super(message, e);
}

public ScheduledTaskExecutorCloseException(@Nullable final String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ FeatureFlagCache newCache(
scheduledTaskExecutor = new ScheduledTaskExecutor(
/* option = */ ScheduledTaskOption.builder()
.delay(config.getPollingDelay())
.taskName("cachedFeatureFlagUpdateTask")
.build()
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.github.lavenderses.aws_app_config_openfeature_provider.task;

import io.github.lavenderses.aws_app_config_openfeature_provider.exception.ScheduledTaskExecutorCloseException;
import jakarta.annotation.PreDestroy;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.VisibleForTesting;
Expand Down Expand Up @@ -63,23 +64,36 @@ public void start(
@PreDestroy
@Override
public void close() throws InterruptedException {
log.info("Start termination of cache update scheduled task for {} second", TERMINATION_WAIT_SECOND);
final String taskName = option.getTaskName();
log.info("Start termination of task[{}] for {} second", TERMINATION_WAIT_SECOND, taskName);
executorService.shutdown();

final boolean terminated = executorService.awaitTermination(
boolean terminated = executorService.awaitTermination(
/* timeout = */ TERMINATION_WAIT_SECOND,
/* unit = */ TimeUnit.SECONDS
);

if (terminated) {
log.info("Terminated of cache update scheduled task");
log.info("Terminated of task[{}]", taskName);
} else {
log.error(
"Timed out {} second for termination of cache update scheduled task. Start force termination",
TERMINATION_WAIT_SECOND
"Timed out {} second for termination of task[{}]. Start force termination",
TERMINATION_WAIT_SECOND,
taskName
);

executorService.shutdownNow();

terminated = executorService.awaitTermination(
/* timeout = */ TERMINATION_WAIT_SECOND,
/* unit = */ TimeUnit.SECONDS
);

if (terminated) {
log.warn("Terminated of task[{}] with force shutdown", taskName);
} else {
throw new ScheduledTaskExecutorCloseException("Failed to terminate task[%s]".formatted(taskName));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ public final class ScheduledTaskOption {
.delay(Duration.ZERO)
.build();

@NotNull
@NonNull
private final String taskName;

/**
* Fixed delay of the task({@link ScheduledTask}) interval.
*/
Expand Down
Loading