2 * Copyright (c) 2016 Brocade Communications Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.ovsdb.southbound.reconciliation;
10 import com.google.common.util.concurrent.ThreadFactoryBuilder;
11 import java.util.concurrent.ExecutorService;
12 import java.util.concurrent.Executors;
13 import java.util.concurrent.ScheduledExecutorService;
14 import java.util.concurrent.ThreadFactory;
15 import java.util.concurrent.TimeUnit;
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.yangtools.util.concurrent.SpecialExecutors;
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
22 * This class provides the implementation of ovsdb southbound plugins
23 * configuration reconciliation engine. This engine provide interfaces
24 * to enqueue (one time retry)/ enqueueForRetry(periodic retry)/ dequeue
25 * (remove from retry queue) reconciliation task. Reconciliation task can
26 * be a connection reconciliation or configuration reconciliation of any
27 * ovsdb managed resource like bridge, termination point etc. This engine
28 * execute all the reconciliation task through a fixed size thread pool.
29 * If submitted task need to be retry after a periodic interval they are
30 * submitted to a single thread executor to periodically wake up and check
31 * if task is ready for execution.
32 * Ideally, addition of any type of reconciliation task should not require
33 * any change in this reconciliation manager execution engine.
36 * Reconciliation manager is agnostic of whether it's running in single
37 * node cluster or 3-node cluster. It's a responsibility of the task
38 * submitter to make sure that it submit the task for reconciliation only
39 * if it's an owner of that device EXCEPT controller initiated Connection.
40 * Reconciliation of controller initiated connection should be done by all
41 * the 3-nodes in the cluster, because connection to individual controller
42 * can be interrupted for various reason.
45 public class ReconciliationManager implements AutoCloseable {
46 private static final Logger LOG = LoggerFactory.getLogger(ReconciliationManager.class);
48 private static final int NO_OF_RECONCILER = 10;
49 private static final int RECON_TASK_QUEUE_SIZE = 5000;
51 private final DataBroker db;
52 private final ExecutorService reconcilers;
53 private final ScheduledExecutorService taskTriager;
55 private final ReconciliationTaskManager reconTaskManager = new ReconciliationTaskManager();
57 public ReconciliationManager(final DataBroker db) {
59 reconcilers = SpecialExecutors.newBoundedCachedThreadPool(NO_OF_RECONCILER, RECON_TASK_QUEUE_SIZE,
62 ThreadFactory threadFact = new ThreadFactoryBuilder()
63 .setNameFormat("ovsdb-recon-task-triager-%d").build();
64 taskTriager = Executors.newSingleThreadScheduledExecutor(threadFact);
67 public boolean isEnqueued(final ReconciliationTask task) {
68 return reconTaskManager.isTaskQueued(task);
71 public void enqueue(final ReconciliationTask task) {
72 LOG.trace("Reconciliation task submitted for execution {}",task);
73 reconTaskManager.cacheTask(task, reconcilers.submit(task));
76 public void enqueueForRetry(final ReconciliationTask task) {
77 LOG.trace("Reconciliation task re-queued for re-execution {}",task);
78 reconTaskManager.cacheTask(task, taskTriager.schedule(
82 task.checkReadinessAndProcess();
84 }, task.retryDelayInMills(), TimeUnit.MILLISECONDS
89 public void dequeue(final ReconciliationTask task) {
90 reconTaskManager.cancelTask(task);
93 public DataBroker getDb() {
98 public void close() throws Exception {
99 if (this.reconcilers != null) {
100 this.reconcilers.shutdownNow();
103 if (this.taskTriager != null) {
104 this.taskTriager.shutdownNow();