smallrye / smallrye-stork

SmallRye Stork is a service discovery and client side-load balancing framework.

Home Page:http://smallrye.io/smallrye-stork/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Allows CacheServiceInstance to customize the cache invalidation

cescoffier opened this issue · comments

(This is the first step of #299)

At the moment, the service discovery providers using the cache support (extending io.smallrye.stork.impl.CachingServiceDiscovery) are limited to a time-based cache. This issue is about allowing more advanced strategies such as background invalidation.

Design idea:

Add a method to CachingServiceDiscovery that allows customizing the "memorize" part of the pipeline:

// ...
    public CachingServiceDiscovery(String refreshPeriod) {
        try {
            this.refreshPeriod = DurationUtils.parseDuration(refreshPeriod, REFRESH_PERIOD);
        } catch (DateTimeParseException e) {
            throw new IllegalArgumentException(REFRESH_PERIOD + " for service discovery should be a number, got: " +
                    refreshPeriod,
                    e);
        }

        this.lastResults = Collections.emptyList();
        uni<ServiceInstance> list = Uni.createFrom().deferred(() -> fetchNewServiceInstances(this.lastResults)
                .invoke(l -> this.lastResults = l)
                .onFailure().invoke(this::handleFetchError)
                .onFailure().recoverWithItem(this.lastResults));
         this.instances = cache(list);
    }

// Overridable by the provider
public Uni<ServiceInstance> cache(Uni<ServiceInstance> uni) {
       return uni.memoize().atLeast(this.refreshPeriod);
}

To implement background invalidation, the provider would do something like:

AtomicBoolean invalidated = new AtomicBoolean();
@Override
public Uni<ServiceInstance> cache(Uni<ServiceInstance> uni) {
       return uni.memoize().unil(() -> invalidated.get())
                    .invoke(() -> invalidated.set(false));
}

public void invalidate() {
   invalidated.set(true);
}