Skip to content

Instantly share code, notes, and snippets.

@minwoox
Created January 10, 2020 10:07
Show Gist options
  • Save minwoox/bc725fd0c4c9b6a567f3f3fb7391f32d to your computer and use it in GitHub Desktop.
Save minwoox/bc725fd0c4c9b6a567f3f3fb7391f32d to your computer and use it in GitHub Desktop.
/*
* Copyright 2019 LINE Corporation
*
* LINE Corporation licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.linecorp.armeria.client.consul;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import com.linecorp.armeria.client.ClientFactory;
import com.linecorp.armeria.client.Endpoint;
import com.linecorp.armeria.client.endpoint.DynamicEndpointGroup;
import com.linecorp.armeria.client.endpoint.EndpointGroup;
import com.linecorp.armeria.client.retry.Backoff;
import com.linecorp.armeria.common.consul.ConsulClient;
import com.linecorp.armeria.internal.consul.CachedConsulClient;
import io.netty.util.concurrent.ScheduledFuture;
public final class ConsulEndpointGroup extends DynamicEndpointGroup {
private final ConsulClient client;
private final ClientFactory clientFactory;
private final String serviceName;
private final Backoff retryBackoff;
@Nullable
private volatile ScheduledFuture<?> scheduledFuture;
private volatile boolean closed;
ConsulEndpointGroup(ConsulClient client, ClientFactory clientFactory,
String serviceName, Backoff retryBackoff) {
this.client = client;
this.clientFactory = clientFactory;
this.serviceName = serviceName;
this.retryBackoff = retryBackoff;
start();
}
private void start() {
final CompletableFuture<List<Endpoint>> future = client.healthyEndpoints(serviceName);
future.handle((endpoints, cause) -> {
if (closed) {
return null;
}
if (cause != null) {
// Stop here or continue?
}
setEndpoints(endpoints);
final long nextDelayMillis = nextDelayMillis();
scheduledFuture = clientFactory.eventLoopGroup().schedule(this::start,
nextDelayMillis,
TimeUnit.MILLISECONDS);
return null;
});
}
private long nextDelayMillis() {
final long delayMillis = retryBackoff.nextDelayMillis(1);
if (delayMillis < 0) {
throw new IllegalStateException(
"retryBackoff.nextDelayMillis(1) returned a negative value: " + delayMillis);
}
return delayMillis;
}
@Override
public void close() {
closed = true;
final ScheduledFuture<?> future = scheduledFuture;
if (future != null) {
future.cancel(true);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment