content: /*
   * Copyright 1999-2018 Alibaba Group Holding Ltd.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package com.alibaba.csp.sentinel.demo.datasource.nacos;
  
  import java.util.Random;
  import java.util.concurrent.TimeUnit;
  import java.util.concurrent.atomic.AtomicInteger;
  
  import com.alibaba.csp.sentinel.Entry;
  import com.alibaba.csp.sentinel.SphU;
  import com.alibaba.csp.sentinel.slots.block.BlockException;
  import com.alibaba.csp.sentinel.util.TimeUtil;
  
  /**
   * Flow QPS runner.
   *
   * @author Carpenter Lee
   * @author Eric Zhao
   */
  class FlowQpsRunner {
  
      private final String resourceName;
      private final int threadCount;
      private int seconds;
  
      public FlowQpsRunner(String resourceName, int threadCount, int seconds) {
          this.resourceName = resourceName;
          this.threadCount = threadCount;
          this.seconds = seconds;
      }
  
      private final AtomicInteger pass = new AtomicInteger();
      private final AtomicInteger block = new AtomicInteger();
      private final AtomicInteger total = new AtomicInteger();
  
      private volatile boolean stop = false;
  
      public void simulateTraffic() {
          for (int i = 0; i < threadCount; i++) {
              Thread t = new Thread(new RunTask());
              t.setName("simulate-traffic-Task");
              t.start();
          }
      }
  
      public void tick() {
          Thread timer = new Thread(new TimerTask());
          timer.setName("sentinel-timer-task");
          timer.start();
      }
  
      final class RunTask implements Runnable {
          @Override
          public void run() {
              while (!stop) {
                  Entry entry = null;
  
                  try {
                      entry = SphU.entry(resourceName);
                      // token acquired, means pass
                      pass.addAndGet(1);
                  } catch (BlockException e1) {
                      block.incrementAndGet();
                  } catch (Exception e2) {
                      // biz exception
                  } finally {
                      total.incrementAndGet();
                      if (entry != null) {
                          entry.exit();
                      }
                  }
  
                  Random random2 = new Random();
                  try {
                      TimeUnit.MILLISECONDS.sleep(random2.nextInt(50));
                  } catch (InterruptedException e) {
                      // ignore
                  }
              }
          }
      }
  
      final class TimerTask implements Runnable {
          @Override
          public void run() {
              long start = System.currentTimeMillis();
              System.out.println("begin to statistic!!!");
  
              long oldTotal = 0;
              long oldPass = 0;
              long oldBlock = 0;
              while (!stop) {
                  try {
                      TimeUnit.SECONDS.sleep(1);
                  } catch (InterruptedException e) {
                  }
                  long globalTotal = total.get();
                  long oneSecondTotal = globalTotal - oldTotal;
                  oldTotal = globalTotal;
  
                  long globalPass = pass.get();
                  long oneSecondPass = globalPass - oldPass;
                  oldPass = globalPass;
  
                  long globalBlock = block.get();
                  long oneSecondBlock = globalBlock - oldBlock;
                  oldBlock = globalBlock;
  
                  System.out.println(seconds + " send qps is: " + oneSecondTotal);
                  System.out.println(TimeUtil.currentTimeMillis() + ", total:" + oneSecondTotal
                      + ", pass:" + oneSecondPass
                      + ", block:" + oneSecondBlock);
  
                  if (seconds-- <= 0) {
                      stop = true;
                  }
              }
  
              long cost = System.currentTimeMillis() - start;
              System.out.println("time cost: " + cost + " ms");
              System.out.println("total:" + total.get() + ", pass:" + pass.get()
                  + ", block:" + block.get());
              System.exit(0);
          }
      }
  }
  