2 * Copyright IBM Corporation, 2013. 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.controller.md.statistics.manager;
10 import java.util.Collections;
11 import java.util.Iterator;
12 import java.util.LinkedHashMap;
14 import java.util.Timer;
15 import java.util.TimerTask;
16 import java.util.concurrent.TimeUnit;
18 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
19 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
20 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction.DataTransactionListener;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
26 * Main responsibility of the class is to check the MD-SAL data store read/write
27 * transaction accumulation level and send statistics request if number of pending
28 * read/write transactions are zero.
29 * @author avishnoi@in.ibm.com
32 @SuppressWarnings("rawtypes")
33 public class StatisticsRequestScheduler implements DataTransactionListener {
35 private static final Logger srsLogger = LoggerFactory.getLogger(StatisticsRequestScheduler.class);
36 private final Timer timer = new Timer("request-monitor", true);
38 // We need ordered retrieval, and O(1) contains operation
39 private final Map<AbstractStatsTracker,Integer> requestQueue =
40 Collections.synchronizedMap(new LinkedHashMap<AbstractStatsTracker,Integer>());
42 private Long PendingTransactions;
44 private long lastRequestTime = System.nanoTime();
46 private static final long REQUEST_MONITOR_INTERVAL = 1000;
48 private final TimerTask task = new TimerTask() {
52 long now = System.nanoTime();
53 if(now > lastRequestTime+TimeUnit.MILLISECONDS.toNanos(REQUEST_MONITOR_INTERVAL)){
56 }catch (IllegalArgumentException | IllegalStateException | NullPointerException e){
57 srsLogger.warn("Exception occured while sending statistics request : {}",e);
62 public StatisticsRequestScheduler(){
63 PendingTransactions = (long) 0;
66 public void addRequestToSchedulerQueue(AbstractStatsTracker statsRequest){
67 requestQueue.put(statsRequest, null);
70 public void removeRequestsFromSchedulerQueue(NodeRef node){
71 AbstractStatsTracker stats = null;
72 synchronized(requestQueue){
73 Iterator<Map.Entry<AbstractStatsTracker, Integer>> nodesItr = requestQueue.entrySet().iterator();
74 while(nodesItr.hasNext()){
75 stats = nodesItr.next().getKey();
76 if(stats.getNodeRef().equals(node)){
83 public AbstractStatsTracker getNextRequestFromSchedulerQueue(){
84 //Remove first element
85 AbstractStatsTracker stats = null;
86 synchronized(requestQueue){
87 Iterator<Map.Entry<AbstractStatsTracker, Integer>> nodesItr = requestQueue.entrySet().iterator();
88 if(nodesItr.hasNext()){
89 stats = nodesItr.next().getKey();
90 srsLogger.debug("{} chosen up for execution",stats.getNodeRef());
98 private void requestStatistics(){
99 AbstractStatsTracker stats = this.getNextRequestFromSchedulerQueue();
100 sendStatsRequest(stats);
103 public void onStatusUpdated(DataModificationTransaction transaction, TransactionStatus status) {
105 AbstractStatsTracker stats = null;
106 synchronized(PendingTransactions){
109 this.PendingTransactions++;
113 this.PendingTransactions--;
114 if(PendingTransactions == 0){
115 lastRequestTime = System.nanoTime();
116 stats = this.getNextRequestFromSchedulerQueue();
118 srsLogger.debug("Pending MD-SAL transactions : {} & Scheduler queue size : {}",this.PendingTransactions,this.requestQueue.size());
124 sendStatsRequest(stats);
127 private void sendStatsRequest(AbstractStatsTracker stats){
131 stats.increaseRequestCounter();
133 srsLogger.warn("Statistics request was not sent successfully. Reason : {}",e.getMessage());
138 timer.schedule(task, 0, REQUEST_MONITOR_INTERVAL);