Distributed Datastore integration with config subsystem
[controller.git] / opendaylight / md-sal / statistics-manager / src / main / java / org / opendaylight / controller / md / statistics / manager / StatisticsRequestScheduler.java
1 /*
2  * Copyright IBM Corporation, 2013.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.md.statistics.manager;
9
10 import java.util.Collections;
11 import java.util.Iterator;
12 import java.util.LinkedHashMap;
13 import java.util.Map;
14 import java.util.Timer;
15 import java.util.TimerTask;
16 import java.util.concurrent.TimeUnit;
17
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;
24
25 /**
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
30  *
31  */
32 @SuppressWarnings("rawtypes")
33 public class StatisticsRequestScheduler implements DataTransactionListener {
34
35     private static final Logger srsLogger = LoggerFactory.getLogger(StatisticsRequestScheduler.class);
36     private final Timer timer = new Timer("request-monitor", true);
37
38     // We need ordered retrieval, and O(1) contains operation
39     private final Map<AbstractStatsTracker,Integer> requestQueue =
40             Collections.synchronizedMap(new LinkedHashMap<AbstractStatsTracker,Integer>());
41
42     private Long PendingTransactions;
43
44     private long lastRequestTime = System.nanoTime();
45
46     private static final long REQUEST_MONITOR_INTERVAL = 1000;
47
48     private final TimerTask task = new TimerTask() {
49         @Override
50         public void run() {
51             long now = System.nanoTime();
52             if(now > lastRequestTime+TimeUnit.MILLISECONDS.toNanos(REQUEST_MONITOR_INTERVAL)){
53                 requestStatistics();
54             }
55         }
56     };
57
58     public StatisticsRequestScheduler(){
59         PendingTransactions = (long) 0;
60     }
61
62     public void addRequestToSchedulerQueue(AbstractStatsTracker statsRequest){
63         requestQueue.put(statsRequest, null);
64     }
65
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)){
73                     nodesItr.remove();
74                 }
75             }
76         }
77
78     }
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());
87                 nodesItr.remove();
88                 return stats;
89             }
90         }
91         return stats;
92     }
93
94     private void requestStatistics(){
95         AbstractStatsTracker stats = this.getNextRequestFromSchedulerQueue();
96         sendStatsRequest(stats);
97     }
98     @Override
99     public void onStatusUpdated(DataModificationTransaction transaction, TransactionStatus status) {
100
101         AbstractStatsTracker stats = null;
102         synchronized(PendingTransactions){
103             switch(status){
104             case SUBMITED:
105                 this.PendingTransactions++;
106                 break;
107             case COMMITED:
108             case FAILED:
109                 this.PendingTransactions--;
110                 if(PendingTransactions == 0){
111                     lastRequestTime = System.nanoTime();
112                     stats = this.getNextRequestFromSchedulerQueue();
113                 }
114                 srsLogger.debug("Pending MD-SAL transactions : {} & Scheduler queue size : {}",this.PendingTransactions,this.requestQueue.size());
115                 break;
116             default:
117                 break;
118             }
119         }
120         sendStatsRequest(stats);
121     }
122
123     private void sendStatsRequest(AbstractStatsTracker stats){
124         if(stats != null){
125             try{
126                 stats.request();
127                 stats.increaseRequestCounter();
128             }catch(Exception e){
129                 srsLogger.warn("Statistics request was not sent successfully. Reason : {}",e.getMessage());
130             }
131         }
132     }
133     public void start(){
134         timer.schedule(task, 0, REQUEST_MONITOR_INTERVAL);
135     }
136 }