f335b28dfa30c20145d5c114d5865900eae2fa38
[vpp.git] / src / vpp-api / java / jvpp-core / io / fd / vpp / jvpp / core / examples / FutureApiReadPerfTest.java
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package io.fd.vpp.jvpp.core.examples;
18
19 import io.fd.vpp.jvpp.JVppRegistry;
20 import io.fd.vpp.jvpp.JVppRegistryImpl;
21 import io.fd.vpp.jvpp.core.JVppCoreImpl;
22 import io.fd.vpp.jvpp.core.callback.ShowVersionReplyCallback;
23 import io.fd.vpp.jvpp.core.dto.*;
24 import io.fd.vpp.jvpp.core.future.FutureJVppCoreFacade;
25
26 import java.util.concurrent.CompletableFuture;
27 import java.util.logging.Logger;
28
29 public class FutureApiReadPerfTest {
30
31     private static final Logger LOG = Logger.getLogger(FutureApiReadPerfTest.class.getName());
32     private static final ShowVersion REQUEST = new ShowVersion();
33     private static volatile int currentCount = 0;
34     private static int desiredCount = 0;
35     private static long timeAfter = 0;
36     private static volatile boolean stop = false;
37     /**
38      * Run after reply message is received
39      * in case of running for 1 sec check if time passed (stop variable) and if it does skip processing
40      * in case of running for set amount of REQUEST, record time in which was last reply received
41      * not thread save but since reading part process only one message at a time it's ok
42      */
43     private static Runnable replyFc = () -> {
44         if (stop) {
45             return;
46         }
47         currentCount++;
48         if(currentCount == desiredCount) {
49             timeAfter = System.nanoTime();
50         }
51     };
52
53     /**
54      * Used to reset counters and flags between runs
55      */
56     private static void reset() {
57         currentCount = 0;
58         timeAfter = 0;
59         stop = false;
60     }
61
62     public static boolean stop() {
63         stop = true;
64         return false;
65     }
66
67     /**
68      *
69      * @return time of last reply received
70      * @throws Exception during thread sleep
71      */
72     private static long getTime() throws Exception {
73         while(timeAfter == 0) {
74             LOG.info(String.format("Received %d replies", currentCount));
75             Thread.sleep(1000);
76         }
77         return timeAfter;
78     }
79
80     /**
81      *
82      * @param args - for running for one sec requires no parameter
83      *             - for running for set amount of requests requires one parameters, desired REQUEST amount
84      * @throws Exception if arguments aren't String representations of numbers
85      */
86     public static void main(String[] args) throws Exception {
87         if (args.length == 1) {
88             desiredCount =  Integer.parseUnsignedInt(args[0]);
89             testInvokeCounter(true);
90         } else {
91             testInvokeCounter(false);
92         }
93     }
94
95     /**
96      *
97      * @param setCount true = run with set amount of requests, false = run for 1 sec
98      * @throws Exception
99      */
100     private static void testInvokeCounter(boolean setCount) throws Exception {
101         LOG.info("Testing callback API Invocation Counter");
102         try (final JVppRegistry registry = new JVppRegistryImpl("FutureApiReadPerfTest");
103              final FutureJVppCoreFacade jvpp = new FutureJVppCoreFacade(registry, new JVppCoreImpl())) {
104             if (!setCount) {
105                 for(int i = 0; i < 5; i++) {
106                     reset();
107                     LOG.info("Starting invocation for 1sec");
108                     long time = System.nanoTime();
109                     do {
110                         CompletableFuture<ShowVersionReply> replyFuture = jvpp.showVersion(REQUEST).toCompletableFuture();
111                         replyFuture.thenRun(replyFc);
112                     } while (System.nanoTime() - time < 1000000000 || stop());
113                     LOG.info(String.format("Invocation count within 1 second: %d", currentCount));
114                 }
115             } else {
116                 for (int i = 0; i < 5; i++) {
117                     LOG.info("Starting invocations");
118                     reset();
119                     long time = System.nanoTime();
120                     for (int x = 0; x < desiredCount; x++) {
121                         CompletableFuture<ShowVersionReply> replyFuture = jvpp.showVersion(REQUEST).toCompletableFuture();
122                         replyFuture.thenRun(replyFc);
123                     }
124                     LOG.info("Invocations send");
125                     long timeAfter = getTime();
126                     LOG.info(String.format("Invocations took %d ns (%f invocations/s)", timeAfter - time,
127                             desiredCount * (1000000000.0/(timeAfter - time))));
128                 }
129             }
130
131
132             Thread.sleep(1000);
133             LOG.info("Disconnecting...");
134         }
135         Thread.sleep(1000);
136     }
137 }