mirror of
https://github.com/opennetworkinglab/onos.git
synced 2025-10-18 19:01:06 +02:00
Add link eviction to gRPC Link SB.
- Now assumes (remote) LinkProvider to periodically report existing Link. - Note: This eviction mechanism can be removed, once gRPC Link SB service was remodelled using streaming RPC. Change-Id: I98f05f849b876cff9bbdb648e7ac79f900f4bfcb
This commit is contained in:
parent
25a98e7045
commit
4c7c90a54d
@ -16,6 +16,7 @@
|
|||||||
package org.onosproject.incubator.rpc.grpc;
|
package org.onosproject.incubator.rpc.grpc;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static java.util.concurrent.Executors.newScheduledThreadPool;
|
||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.toList;
|
||||||
import static org.onosproject.incubator.protobuf.net.ProtobufUtils.translate;
|
import static org.onosproject.incubator.protobuf.net.ProtobufUtils.translate;
|
||||||
import static org.onosproject.net.DeviceId.deviceId;
|
import static org.onosproject.net.DeviceId.deviceId;
|
||||||
@ -25,6 +26,7 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
@ -36,6 +38,7 @@ import org.apache.felix.scr.annotations.Modified;
|
|||||||
import org.apache.felix.scr.annotations.Property;
|
import org.apache.felix.scr.annotations.Property;
|
||||||
import org.apache.felix.scr.annotations.Reference;
|
import org.apache.felix.scr.annotations.Reference;
|
||||||
import org.apache.felix.scr.annotations.ReferenceCardinality;
|
import org.apache.felix.scr.annotations.ReferenceCardinality;
|
||||||
|
import org.onlab.util.Tools;
|
||||||
import org.onosproject.grpc.net.device.DeviceProviderRegistryRpcGrpc;
|
import org.onosproject.grpc.net.device.DeviceProviderRegistryRpcGrpc;
|
||||||
import org.onosproject.grpc.net.device.DeviceProviderRegistryRpcGrpc.DeviceProviderRegistryRpc;
|
import org.onosproject.grpc.net.device.DeviceProviderRegistryRpcGrpc.DeviceProviderRegistryRpc;
|
||||||
import org.onosproject.grpc.net.device.DeviceService.DeviceConnected;
|
import org.onosproject.grpc.net.device.DeviceService.DeviceConnected;
|
||||||
@ -110,8 +113,11 @@ public class GrpcRemoteServiceServer {
|
|||||||
private final Map<String, LinkProviderService> linkProviderServices = Maps.newConcurrentMap();
|
private final Map<String, LinkProviderService> linkProviderServices = Maps.newConcurrentMap();
|
||||||
private final Map<String, LinkProvider> linkProviders = Maps.newConcurrentMap();
|
private final Map<String, LinkProvider> linkProviders = Maps.newConcurrentMap();
|
||||||
|
|
||||||
|
private ScheduledExecutorService executor;
|
||||||
|
|
||||||
@Activate
|
@Activate
|
||||||
protected void activate(ComponentContext context) throws IOException {
|
protected void activate(ComponentContext context) throws IOException {
|
||||||
|
executor = newScheduledThreadPool(1, Tools.groupedThreads("grpc", "%d", log));
|
||||||
modified(context);
|
modified(context);
|
||||||
|
|
||||||
log.debug("Server starting on {}", listenPort);
|
log.debug("Server starting on {}", listenPort);
|
||||||
@ -130,6 +136,12 @@ public class GrpcRemoteServiceServer {
|
|||||||
|
|
||||||
@Deactivate
|
@Deactivate
|
||||||
protected void deactivate() {
|
protected void deactivate() {
|
||||||
|
executor.shutdown();
|
||||||
|
try {
|
||||||
|
executor.awaitTermination(5, TimeUnit.SECONDS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
registeredProviders.stream()
|
registeredProviders.stream()
|
||||||
.forEach(deviceProviderRegistry::unregister);
|
.forEach(deviceProviderRegistry::unregister);
|
||||||
@ -182,6 +194,10 @@ public class GrpcRemoteServiceServer {
|
|||||||
return linkProviderServices.computeIfAbsent(scheme, this::registerStubLinkProvider);
|
return linkProviderServices.computeIfAbsent(scheme, this::registerStubLinkProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected ScheduledExecutorService getSharedExecutor() {
|
||||||
|
return executor;
|
||||||
|
}
|
||||||
|
|
||||||
// RPC Server-side code
|
// RPC Server-side code
|
||||||
// RPC session Factory
|
// RPC session Factory
|
||||||
/**
|
/**
|
||||||
|
@ -17,8 +17,14 @@ package org.onosproject.incubator.rpc.grpc;
|
|||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.common.cache.RemovalListeners.asynchronous;
|
||||||
import static org.onosproject.net.DeviceId.deviceId;
|
import static org.onosproject.net.DeviceId.deviceId;
|
||||||
|
import static org.onosproject.net.LinkKey.linkKey;
|
||||||
|
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.onosproject.grpc.net.Link.ConnectPoint.ElementIdCase;
|
import org.onosproject.grpc.net.Link.ConnectPoint.ElementIdCase;
|
||||||
import org.onosproject.grpc.net.Link.LinkType;
|
import org.onosproject.grpc.net.Link.LinkType;
|
||||||
import org.onosproject.grpc.net.link.LinkProviderServiceRpcGrpc.LinkProviderServiceRpc;
|
import org.onosproject.grpc.net.link.LinkProviderServiceRpcGrpc.LinkProviderServiceRpc;
|
||||||
@ -29,6 +35,7 @@ import org.onosproject.incubator.protobuf.net.ProtobufUtils;
|
|||||||
import org.onosproject.net.ConnectPoint;
|
import org.onosproject.net.ConnectPoint;
|
||||||
import org.onosproject.net.DeviceId;
|
import org.onosproject.net.DeviceId;
|
||||||
import org.onosproject.net.Link;
|
import org.onosproject.net.Link;
|
||||||
|
import org.onosproject.net.LinkKey;
|
||||||
import org.onosproject.net.PortNumber;
|
import org.onosproject.net.PortNumber;
|
||||||
import org.onosproject.net.SparseAnnotations;
|
import org.onosproject.net.SparseAnnotations;
|
||||||
import org.onosproject.net.link.DefaultLinkDescription;
|
import org.onosproject.net.link.DefaultLinkDescription;
|
||||||
@ -38,9 +45,13 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.google.api.client.repackaged.com.google.common.annotations.Beta;
|
import com.google.api.client.repackaged.com.google.common.annotations.Beta;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.RemovalNotification;
|
||||||
|
|
||||||
import io.grpc.stub.StreamObserver;
|
import io.grpc.stub.StreamObserver;
|
||||||
|
|
||||||
|
// Only single instance will be created and bound to gRPC LinkProviderService
|
||||||
/**
|
/**
|
||||||
* Server-side implementation of gRPC version of LinkProviderService.
|
* Server-side implementation of gRPC version of LinkProviderService.
|
||||||
*/
|
*/
|
||||||
@ -48,15 +59,39 @@ import io.grpc.stub.StreamObserver;
|
|||||||
final class LinkProviderServiceServerProxy
|
final class LinkProviderServiceServerProxy
|
||||||
implements LinkProviderServiceRpc {
|
implements LinkProviderServiceRpc {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Silence time in seconds, until link gets treated as vanished.
|
||||||
|
*/
|
||||||
|
private static final int EVICT_LIMIT = 3 * 3;
|
||||||
|
|
||||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
private final GrpcRemoteServiceServer server;
|
private final GrpcRemoteServiceServer server;
|
||||||
|
|
||||||
// TODO implement aging mechanism to automatically remove
|
// TODO implement aging mechanism to automatically remove
|
||||||
// stale links reported by dead client, etc.
|
// stale links reported by dead client, etc.
|
||||||
|
/**
|
||||||
|
* Evicting Cache to track last seen time.
|
||||||
|
*/
|
||||||
|
private final Cache<Pair<String, LinkKey>, LinkDescription> lastSeen;
|
||||||
|
|
||||||
LinkProviderServiceServerProxy(GrpcRemoteServiceServer server) {
|
LinkProviderServiceServerProxy(GrpcRemoteServiceServer server) {
|
||||||
this.server = checkNotNull(server);
|
this.server = checkNotNull(server);
|
||||||
|
ScheduledExecutorService executor = server.getSharedExecutor();
|
||||||
|
lastSeen = CacheBuilder.newBuilder()
|
||||||
|
.expireAfterWrite(EVICT_LIMIT, TimeUnit.SECONDS)
|
||||||
|
.removalListener(asynchronous(this::onRemove, executor))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
executor.scheduleWithFixedDelay(lastSeen::cleanUp,
|
||||||
|
EVICT_LIMIT, EVICT_LIMIT, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onRemove(RemovalNotification<Pair<String, LinkKey>, LinkDescription> n) {
|
||||||
|
if (n.wasEvicted()) {
|
||||||
|
getLinkProviderServiceFor(n.getKey().getLeft())
|
||||||
|
.linkVanished(n.getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,6 +127,7 @@ final class LinkProviderServiceServerProxy
|
|||||||
|
|
||||||
LinkDescription linkDescription = translate(request.getLinkDescription());
|
LinkDescription linkDescription = translate(request.getLinkDescription());
|
||||||
linkProviderService.linkDetected(linkDescription);
|
linkProviderService.linkDetected(linkDescription);
|
||||||
|
lastSeen.put(Pair.of(scheme, linkKey(linkDescription)), linkDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -123,6 +159,7 @@ final class LinkProviderServiceServerProxy
|
|||||||
case LINK_DESCRIPTION:
|
case LINK_DESCRIPTION:
|
||||||
LinkDescription desc = translate(request.getLinkDescription());
|
LinkDescription desc = translate(request.getLinkDescription());
|
||||||
getLinkProviderServiceFor(scheme).linkVanished(desc);
|
getLinkProviderServiceFor(scheme).linkVanished(desc);
|
||||||
|
lastSeen.invalidate(Pair.of(scheme, linkKey(desc)));
|
||||||
break;
|
break;
|
||||||
case SUBJECT_NOT_SET:
|
case SUBJECT_NOT_SET:
|
||||||
default:
|
default:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user