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() {
51 long now = System.nanoTime();
52 if(now > lastRequestTime+TimeUnit.MILLISECONDS.toNanos(REQUEST_MONITOR_INTERVAL)){
58 public StatisticsRequestScheduler(){
59 PendingTransactions = (long) 0;
62 public void addRequestToSchedulerQueue(AbstractStatsTracker statsRequest){
63 requestQueue.put(statsRequest, null);
66 public void removeRequestsFromSchedulerQueue(NodeRef node){
67 AbstractStatsTracker stats = null;
68 synchronized(requestQueue){
69 Iterator<Map.Entry<AbstractStatsTracker, Integer>> nodesItr = requestQueue.entrySet().iterator();
70 while(nodesItr.hasNext()){
71 stats = nodesItr.next().getKey();
72 if(stats.getNodeRef().equals(node)){
79 public AbstractStatsTracker getNextRequestFromSchedulerQueue(){
80 //Remove first element
81 AbstractStatsTracker stats = null;
82 synchronized(requestQueue){
83 Iterator<Map.Entry<AbstractStatsTracker, Integer>> nodesItr = requestQueue.entrySet().iterator();
84 if(nodesItr.hasNext()){
85 stats = nodesItr.next().getKey();
86 srsLogger.debug("{} chosen up for execution",stats.getNodeRef());
94 private void requestStatistics(){
95 AbstractStatsTracker stats = this.getNextRequestFromSchedulerQueue();
96 sendStatsRequest(stats);
99 public void onStatusUpdated(DataModificationTransaction transaction, TransactionStatus status) {
101 AbstractStatsTracker stats = null;
102 synchronized(PendingTransactions){
105 this.PendingTransactions++;
109 this.PendingTransactions--;
110 if(PendingTransactions == 0){
111 lastRequestTime = System.nanoTime();
112 stats = this.getNextRequestFromSchedulerQueue();
114 srsLogger.debug("Pending MD-SAL transactions : {} & Scheduler queue size : {}",this.PendingTransactions,this.requestQueue.size());
120 sendStatsRequest(stats);
123 private void sendStatsRequest(AbstractStatsTracker stats){
127 stats.increaseRequestCounter();
129 srsLogger.warn("Statistics request was not sent successfully. Reason : {}",e.getMessage());
134 timer.schedule(task, 0, REQUEST_MONITOR_INTERVAL);