rickfast / consul-client

Java Client for Consul HTTP API
Other
570 stars 241 forks source link

Watch on service list #380

Open ezra-chu opened 5 years ago

ezra-chu commented 5 years ago

Have a requirement for watching list of services /v1/catalog/services. Trying to put together a PR, running into an issue. This is what I'm trying to do:

public class ServiceListCache extends ConsulCache<String, Map<String, List<String>>> {

    private ServiceListCache(Function<Map<String, List<String>>, String> keyConversion,
                             CallbackConsumer<Map<String, List<String>>> callbackConsumer,
                             CacheConfig cacheConfig,
                             ClientEventHandler eventHandler,
                             CacheDescriptor cacheDescriptor) {
        super(keyConversion, callbackConsumer, cacheConfig, eventHandler, cacheDescriptor);
    }

    public static ServiceListCache newCache(
        final CatalogClient catalogClient,
        final QueryOptions queryOptions,
        final int watchSeconds) {

        final CallbackConsumer<Map<String, List<String>>> callbackConsumer = (index, callback) ->
            catalogClient.getServices(watchParams(index, watchSeconds, queryOptions), callback);

        CacheDescriptor cacheDescriptor = new CacheDescriptor("catalog.services");
        return new ServiceListCache(serviceList -> "allservices",
            callbackConsumer,
            catalogClient.getConfig().getCacheConfig(),
            catalogClient.getEventHandler(),
            cacheDescriptor);
    }

    public static ServiceListCache newCache(final CatalogClient catalogClient) {
        CacheConfig cacheConfig = catalogClient.getConfig().getCacheConfig();
        int watchSeconds = Ints.checkedCast(cacheConfig.getWatchDuration().getSeconds());
        return newCache(catalogClient, QueryOptions.BLANK, watchSeconds);
    }
}

I need CallbackConsumer to be able to handle this case as a single object, not as a list. Thinking about expanding to an abstract class like so:

    protected abstract class CallbackConsumer<V> {
        abstract void consume(BigInteger index, ConsulResponseCallback<List<V>> callback);

        abstract void consumeSingle(BigInteger index, ConsulResponseCallback<V> callback);

    }

Blundering through the codebase and probably missing a lot here, would love some feedback and direction on how best to accomplish this.

Thanks in advance, and thanks for the great lib!

rickfast commented 5 years ago

not sure i understand what you're trying to do. consul is always going to return all of the services when something changes (not just the one(s) that changed), so i'm not sure why it matters if you get the callback with a list or not?