/* * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.controller.clustering.it.provider.impl; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration; import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class FlappingSingletonService implements ClusterSingletonService { private static final Logger LOG = LoggerFactory.getLogger(FlappingSingletonService.class); private static final ServiceGroupIdentifier SERVICE_GROUP_IDENTIFIER = ServiceGroupIdentifier.create("flapping-singleton-service"); private final ClusterSingletonServiceProvider singletonServiceProvider; private final AtomicBoolean active = new AtomicBoolean(true); private final AtomicLong flapCount = new AtomicLong(); private volatile ClusterSingletonServiceRegistration registration; public FlappingSingletonService(final ClusterSingletonServiceProvider singletonServiceProvider) { LOG.debug("Registering flapping-singleton-service."); this.singletonServiceProvider = singletonServiceProvider; registration = singletonServiceProvider.registerClusterSingletonService(this); } @Override @SuppressWarnings("checkstyle:IllegalCatch") public void instantiateServiceInstance() { LOG.debug("Instantiating flapping-singleton-service."); try { registration.close(); registration = null; } catch (Exception e) { LOG.warn("There was a problem closing flapping singleton service.", e); setInactive(); final long count = flapCount.get(); flapCount.compareAndSet(count, -count); } } @Override @SuppressWarnings("checkstyle:IllegalCatch") public ListenableFuture closeServiceInstance() { LOG.debug("Closing flapping-singleton-service, flapCount: {}", flapCount); flapCount.incrementAndGet(); if (active.get()) { LOG.debug("Running re-registration"); try { registration = singletonServiceProvider.registerClusterSingletonService(this); } catch (RuntimeException e) { LOG.warn("There was a problem re-registering flapping singleton service.", e); setInactive(); final long count = flapCount.get(); flapCount.compareAndSet(count, -count - 1); } } return Futures.immediateFuture(null); } @Override public ServiceGroupIdentifier getIdentifier() { return SERVICE_GROUP_IDENTIFIER; } public long setInactive() { LOG.debug("Setting flapping-singleton-service to inactive, flap-count: {}", flapCount); active.set(false); return flapCount.get(); } }