Skip to content

Commit

Permalink
Keep a reference to the full interceptor chain to call restart (#1205)
Browse files Browse the repository at this point in the history
  • Loading branch information
radcortez authored Jul 31, 2024
1 parent 1550541 commit 7b3f279
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 40 deletions.
38 changes: 19 additions & 19 deletions implementation/src/main/java/io/smallrye/config/SmallRyeConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@

import io.smallrye.common.annotation.Experimental;
import io.smallrye.config.SmallRyeConfigBuilder.InterceptorWithPriority;
import io.smallrye.config.SmallRyeConfigSourceInterceptorContext.InterceptorChain;
import io.smallrye.config._private.ConfigLogging;
import io.smallrye.config._private.ConfigMessages;
import io.smallrye.config.common.utils.StringUtil;
Expand Down Expand Up @@ -763,10 +764,6 @@ public List<String> getProfiles() {
return configSources.getProfiles();
}

ConfigSourceInterceptorContext interceptorChain() {
return configSources.interceptorChain;
}

private static class ConfigSources implements Serializable {
private static final long serialVersionUID = 3483018375584151712L;

Expand Down Expand Up @@ -796,21 +793,23 @@ private static class ConfigSources implements Serializable {
List<InterceptorWithPriority> interceptorWithPriorities = buildInterceptors(builder);

// Create the initial chain with initial sources and all interceptors
SmallRyeConfigSourceInterceptorContext current = new SmallRyeConfigSourceInterceptorContext(EMPTY, null, config);
current = new SmallRyeConfigSourceInterceptorContext(negativeSources, current, config);
InterceptorChain chain = new InterceptorChain();
SmallRyeConfigSourceInterceptorContext current = new SmallRyeConfigSourceInterceptorContext(EMPTY, null, chain);

current = new SmallRyeConfigSourceInterceptorContext(negativeSources, current, chain);
for (InterceptorWithPriority interceptorWithPriority : interceptorWithPriorities) {
if (interceptorWithPriority.getPriority() < 0) {
ConfigSourceInterceptor interceptor = interceptorWithPriority.getInterceptor(current);
negativeInterceptors.add(interceptor);
current = new SmallRyeConfigSourceInterceptorContext(interceptor, current, config);
current = new SmallRyeConfigSourceInterceptorContext(interceptor, current, chain);
}
}
current = new SmallRyeConfigSourceInterceptorContext(positiveSources, current, config);
current = new SmallRyeConfigSourceInterceptorContext(positiveSources, current, chain);
for (InterceptorWithPriority interceptorWithPriority : interceptorWithPriorities) {
if (interceptorWithPriority.getPriority() >= 0) {
ConfigSourceInterceptor interceptor = interceptorWithPriority.getInterceptor(current);
positiveInterceptors.add(interceptor);
current = new SmallRyeConfigSourceInterceptorContext(interceptor, current, config);
current = new SmallRyeConfigSourceInterceptorContext(interceptor, current, chain);
}
}

Expand All @@ -823,16 +822,16 @@ private static class ConfigSources implements Serializable {
// Rebuild the chain with the late sources and new instances of the interceptors
// The new instance will ensure that we get rid of references to factories and other stuff and keep only
// the resolved final source or interceptor to use.
current = new SmallRyeConfigSourceInterceptorContext(EMPTY, null, config);
current = new SmallRyeConfigSourceInterceptorContext(EMPTY, null, chain);
current = new SmallRyeConfigSourceInterceptorContext(new SmallRyeConfigSources(sourcesWithPriorities, true),
current, config);
current, chain);
for (ConfigSourceInterceptor interceptor : negativeInterceptors) {
current = new SmallRyeConfigSourceInterceptorContext(interceptor, current, config);
current = new SmallRyeConfigSourceInterceptorContext(interceptor, current, chain);
}
current = new SmallRyeConfigSourceInterceptorContext(new SmallRyeConfigSources(sourcesWithPriorities, false),
current, config);
current, chain);
for (ConfigSourceInterceptor interceptor : positiveInterceptors) {
current = new SmallRyeConfigSourceInterceptorContext(interceptor, current, config);
current = new SmallRyeConfigSourceInterceptorContext(interceptor, current, chain);
}

this.profiles = profiles;
Expand Down Expand Up @@ -929,16 +928,17 @@ private static List<ConfigSourceWithPriority> mapLateSources(
Collections.reverse(currentSources);

// Rebuild the chain with the profiles sources, so profiles values are also available in factories
ConfigSourceInterceptorContext context = new SmallRyeConfigSourceInterceptorContext(EMPTY, null, config);
InterceptorChain chain = new InterceptorChain();
ConfigSourceInterceptorContext context = new SmallRyeConfigSourceInterceptorContext(EMPTY, null, chain);
context = new SmallRyeConfigSourceInterceptorContext(new SmallRyeConfigSources(currentSources, true), context,
config);
chain);
for (ConfigSourceInterceptor interceptor : negativeInterceptors) {
context = new SmallRyeConfigSourceInterceptorContext(interceptor, context, config);
context = new SmallRyeConfigSourceInterceptorContext(interceptor, context, chain);
}
context = new SmallRyeConfigSourceInterceptorContext(new SmallRyeConfigSources(currentSources, false), context,
config);
chain);
for (ConfigSourceInterceptor interceptor : positiveInterceptors) {
context = new SmallRyeConfigSourceInterceptorContext(interceptor, context, config);
context = new SmallRyeConfigSourceInterceptorContext(interceptor, context, chain);
}

// Init remaining sources, coming from SmallRyeConfig
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
package io.smallrye.config;

import java.io.Serializable;
import java.util.Iterator;
import java.util.function.Supplier;

class SmallRyeConfigSourceInterceptorContext implements ConfigSourceInterceptorContext {
private static final long serialVersionUID = 6654406739008729337L;

private final ConfigSourceInterceptor interceptor;
private final ConfigSourceInterceptorContext next;
private final SmallRyeConfig config;
private final InterceptorChain chain;

private static final ThreadLocal<RecursionCount> rcHolder = ThreadLocal.withInitial(RecursionCount::new);

SmallRyeConfigSourceInterceptorContext(
final ConfigSourceInterceptor interceptor,
final ConfigSourceInterceptorContext next,
final SmallRyeConfig config) {
final InterceptorChain chain) {
this.interceptor = interceptor;
this.next = next;
this.config = config;
this.chain = chain.setChain(this);
}

@Override
Expand All @@ -30,7 +32,7 @@ public ConfigValue restart(final String name) {
RecursionCount rc = rcHolder.get();
rc.increment();
try {
return config.interceptorChain().proceed(name);
return chain.get().proceed(name);
} finally {
if (rc.decrement()) {
// avoid leaking if the thread is cached
Expand All @@ -44,6 +46,22 @@ public Iterator<String> iterateNames() {
return interceptor.iterateNames(next);
}

static class InterceptorChain implements Supplier<ConfigSourceInterceptorContext>, Serializable {
private static final long serialVersionUID = 7387475787257736307L;

private ConfigSourceInterceptorContext chain;

@Override
public ConfigSourceInterceptorContext get() {
return chain;
}

public InterceptorChain setChain(final ConfigSourceInterceptorContext chain) {
this.chain = chain;
return this;
}
}

static final class RecursionCount {
int count;

Expand Down
Loading

0 comments on commit 7b3f279

Please sign in to comment.