001    /**
002     * Copyright (C) 2009-2013 Barchart, Inc. <http://www.barchart.com/>
003     *
004     * All rights reserved. Licensed under the OSI BSD License.
005     *
006     * http://www.opensource.org/licenses/bsd-license.php
007     */
008    package com.barchart.udt;
009    
010    import java.lang.reflect.Field;
011    
012    import org.slf4j.Logger;
013    import org.slf4j.LoggerFactory;
014    
015    /**
016     * note: do not change field names; used by JNI
017     */
018    public class MonitorUDT {
019    
020            private static final Logger log = LoggerFactory.getLogger(MonitorUDT.class);
021    
022            protected final SocketUDT socketUDT;
023    
024            protected MonitorUDT(final SocketUDT socketUDT) {
025                    this.socketUDT = socketUDT;
026            }
027    
028            // UDT API
029    
030            // ### global measurements
031    
032            /** time since the UDT entity is started, in milliseconds. */
033            protected volatile long msTimeStamp;
034    
035            public long millisSinceStart() {
036                    return msTimeStamp;
037            }
038    
039            /**
040             * total number of sent data packets, including retransmissions
041             */
042            protected volatile long pktSentTotal;
043    
044            public long globalSentTotal() {
045                    return pktSentTotal;
046            }
047    
048            /**
049             * total number of received packets
050             */
051            protected volatile long pktRecvTotal;
052    
053            public long globalReceivedTotal() {
054                    return pktRecvTotal;
055            }
056    
057            /**
058             * total number of lost packets (sender side)
059             */
060            protected volatile int pktSndLossTotal;
061    
062            public int globalSenderLost() {
063                    return pktSndLossTotal;
064            }
065    
066            /**
067             * total number of lost packets (receiver side)
068             */
069            protected volatile int pktRcvLossTotal;
070    
071            public int globalReceiverLost() {
072                    return pktRcvLossTotal;
073            }
074    
075            /**
076             * total number of retransmitted packets
077             */
078            protected volatile int pktRetransTotal;
079    
080            public int globalRetransmittedTotal() {
081                    return pktRetransTotal;
082            }
083    
084            /**
085             * total number of sent ACK packets
086             */
087            protected volatile int pktSentACKTotal;
088    
089            public int globalSentAckTotal() {
090                    return pktSentACKTotal;
091            }
092    
093            /**
094             * total number of received ACK packets
095             */
096            protected volatile int pktRecvACKTotal;
097    
098            public int globalReceivedAckTotal() {
099                    return pktRecvACKTotal;
100            }
101    
102            /**
103             * total number of sent NAK packets
104             */
105            protected volatile int pktSentNAKTotal;
106    
107            public int globalSentNakTotal() {
108                    return pktSentNAKTotal;
109            }
110    
111            /**
112             * total number of received NAK packets
113             */
114            protected volatile int pktRecvNAKTotal;
115    
116            public int globalReceivedNakTotal() {
117                    return pktRecvNAKTotal;
118            }
119    
120            /**
121             * total time duration when UDT is sending data (idle time exclusive)
122             */
123            protected volatile long usSndDurationTotal;
124    
125            public long globalMicrosSendDurationTotal() {
126                    return usSndDurationTotal;
127            }
128    
129            // ### local measurements
130    
131            /**
132             * number of sent data packets, including retransmissions
133             */
134            protected volatile long pktSent;
135    
136            public long localPacketsSent() {
137                    return pktSent;
138            }
139    
140            /**
141             * number of received packets
142             */
143            protected volatile long pktRecv;
144    
145            public long localPacketsReceived() {
146                    return pktRecv;
147            }
148    
149            /**
150             * number of lost packets (sender side)
151             */
152            protected volatile int pktSndLoss;
153    
154            public int localSenderLost() {
155                    return pktSndLoss;
156            }
157    
158            /**
159             * number of lost packets (receiverer side)
160             */
161            protected volatile int pktRcvLoss;
162    
163            public int localReceiverLost() {
164                    return pktRcvLoss;
165            }
166    
167            /**
168             * number of retransmitted packets
169             */
170            protected volatile int pktRetrans;
171    
172            public int localRetransmitted() {
173                    return pktRetrans;
174            }
175    
176            /**
177             * number of sent ACK packets
178             */
179            protected volatile int pktSentACK;
180    
181            public int localSentAck() {
182                    return pktSentACK;
183            }
184    
185            /**
186             * number of received ACK packets
187             */
188            protected volatile int pktRecvACK;
189    
190            public int localReceivedAck() {
191                    return pktRecvACK;
192            }
193    
194            /**
195             * number of sent NAK packets
196             */
197            protected volatile int pktSentNAK;
198    
199            public int localSentNak() {
200                    return pktSentNAK;
201            }
202    
203            /**
204             * number of received NAK packets
205             */
206            protected volatile int pktRecvNAK;
207    
208            public int localReceivedNak() {
209                    return pktRecvNAK;
210            }
211    
212            /**
213             * sending rate in Mb/s
214             */
215            protected volatile double mbpsSendRate;
216    
217            public double mbpsSendRate() {
218                    return mbpsSendRate;
219            }
220    
221            /**
222             * receiving rate in Mb/s
223             */
224            protected volatile double mbpsRecvRate;
225    
226            public double mbpsReceiveRate() {
227                    return mbpsRecvRate;
228            }
229    
230            /**
231             * busy sending time (i.e., idle time exclusive)
232             */
233            protected volatile long usSndDuration;
234    
235            public long microsSendTime() {
236                    return usSndDuration;
237            }
238    
239            // ### instant measurements
240    
241            /**
242             * packet sending period, in microseconds
243             */
244            protected volatile double usPktSndPeriod;
245    
246            public double currentSendPeriod() {
247                    return usPktSndPeriod;
248            }
249    
250            /**
251             * flow window size, in number of packets
252             */
253            protected volatile int pktFlowWindow;
254    
255            public int currentFlowWindow() {
256                    return pktFlowWindow;
257            }
258    
259            /**
260             * congestion window size, in number of packets
261             */
262            protected volatile int pktCongestionWindow;
263    
264            public int currentCongestionWindow() {
265                    return pktCongestionWindow;
266            }
267    
268            /**
269             * number of packets on flight
270             */
271            protected volatile int pktFlightSize;
272    
273            public int currentFlightSize() {
274                    return pktFlightSize;
275            }
276    
277            /**
278             * RTT, in milliseconds
279             */
280            protected volatile double msRTT;
281    
282            public double currentMillisRTT() {
283                    return msRTT;
284            }
285    
286            /**
287             * estimated bandwidth, in Mb/s
288             */
289            protected volatile double mbpsBandwidth;
290    
291            public double currentMbpsBandwidth() {
292                    return mbpsBandwidth;
293            }
294    
295            /**
296             * available UDT sender buffer size
297             */
298            protected volatile int byteAvailSndBuf;
299    
300            public int currentAvailableInSender() {
301                    return byteAvailSndBuf;
302            }
303    
304            /**
305             * available UDT receiver buffer size
306             */
307            protected volatile int byteAvailRcvBuf;
308    
309            public int currentAvailableInReceiver() {
310                    return byteAvailRcvBuf;
311            }
312    
313            /**
314             * current monitor status snapshot for all parameters
315             */
316            public void appendSnapshot(final StringBuilder text) {
317    
318                    text.append("\n\t");
319                    text.append(String.format("[id: 0x%08x]", socketUDT.id()));
320    
321                    final Field fieldArray[] = MonitorUDT.class.getDeclaredFields();
322    
323                    for (final Field field : fieldArray) {
324    
325                            if (!isNumeric(field)) {
326                                    continue;
327                            }
328    
329                            try {
330    
331                                    field.setAccessible(true);
332    
333                                    final String fieldName = field.getName();
334                                    final String fieldValue = field.get(this).toString();
335    
336                                    text.append("\n\t");
337                                    text.append(fieldName);
338                                    text.append(" = ");
339                                    text.append(fieldValue);
340    
341                            } catch (final Exception e) {
342                                    log.error("unexpected", e);
343                            }
344    
345                    }
346    
347                    final double localSendLoss = 100.0 * pktSndLoss / pktSent;
348    
349                    text.append("\n\t% localSendLoss = ");
350                    text.append(localSendLoss);
351    
352                    final double localReceiveLoss = 100.0 * pktRcvLoss / pktRecv;
353    
354                    text.append("\n\t% localReceiveLoss = ");
355                    text.append(localReceiveLoss);
356    
357            }
358    
359            protected boolean isNumeric(final Field field) {
360    
361                    final Class<?> fieledType = field.getType();
362    
363                    return fieledType == int.class || fieledType == long.class
364                                    || fieledType == double.class;
365    
366            }
367    
368            @Override
369            public String toString() {
370    
371                    final StringBuilder text = new StringBuilder(1024);
372    
373                    appendSnapshot(text);
374    
375                    return text.toString();
376    
377            }
378    
379    }