Просмотр исходного кода

Refactor LeapArray to reuse code for current bucket

Signed-off-by: Eric Zhao <sczyh16@gmail.com>
master
Eric Zhao 6 лет назад
Родитель
Сommit
54905497d0
9 измененных файлов: 179 добавлений и 171 удалений
  1. +67
    -9
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/base/LeapArray.java
  2. +3
    -3
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/base/MetricBucket.java
  3. +30
    -31
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/metric/ArrayMetric.java
  4. +2
    -2
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/metric/Metric.java
  5. +45
    -0
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/metric/MetricsLeapArray.java
  6. +0
    -88
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/metric/WindowLeapArray.java
  7. +5
    -5
      sentinel-core/src/test/java/com/alibaba/csp/sentinel/base/metric/ArrayMetricTest.java
  8. +27
    -27
      sentinel-core/src/test/java/com/alibaba/csp/sentinel/base/metric/MetricsLeapArrayTest.java
  9. +0
    -6
      sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/WarmUpFlowTest.java

+ 67
- 9
sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/base/LeapArray.java Просмотреть файл

@@ -18,10 +18,13 @@ package com.alibaba.csp.sentinel.slots.statistic.base;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.concurrent.locks.ReentrantLock;


import com.alibaba.csp.sentinel.util.TimeUtil; import com.alibaba.csp.sentinel.util.TimeUtil;


/** /**
* Basic data structure for statistic metrics.
*
* @param <T> type of data wrapper * @param <T> type of data wrapper
* @author jialiang.linjl * @author jialiang.linjl
* @author Eric Zhao * @author Eric Zhao
@@ -32,27 +35,86 @@ public abstract class LeapArray<T> {
protected int sampleCount; protected int sampleCount;
protected int intervalInMs; protected int intervalInMs;


protected AtomicReferenceArray<WindowWrap<T>> array;
protected final AtomicReferenceArray<WindowWrap<T>> array;

private final ReentrantLock updateLock = new ReentrantLock();


public LeapArray(int windowLength, int intervalInSec) { public LeapArray(int windowLength, int intervalInSec) {
this.windowLength = windowLength; this.windowLength = windowLength;
this.sampleCount = intervalInSec * 1000 / windowLength;
this.intervalInMs = intervalInSec * 1000; this.intervalInMs = intervalInSec * 1000;
this.sampleCount = intervalInMs / windowLength;


this.array = new AtomicReferenceArray<WindowWrap<T>>(sampleCount); this.array = new AtomicReferenceArray<WindowWrap<T>>(sampleCount);
} }


/**
* Get the window at current timestamp.
*
* @return the window at current timestamp
*/
public WindowWrap<T> currentWindow() { public WindowWrap<T> currentWindow() {
return currentWindow(TimeUtil.currentTimeMillis()); return currentWindow(TimeUtil.currentTimeMillis());
} }


/**
* Create a new bucket.
*
* @return the new empty bucket
*/
public abstract T newEmptyBucket();

/**
* Reset current window to provided start time and reset all counters.
*
* @param startTime the start time of the window
* @param windowWrap current window
* @return new clean window wrap
*/
protected abstract WindowWrap<T> resetWindowTo(WindowWrap<T> windowWrap, long startTime);

/** /**
* Get window at provided timestamp. * Get window at provided timestamp.
* *
* @param time a valid timestamp * @param time a valid timestamp
* @return the window at provided timestamp * @return the window at provided timestamp
*/ */
abstract public WindowWrap<T> currentWindow(long time);
public WindowWrap<T> currentWindow(long time) {
long timeId = time / windowLength;
// Calculate current index.
int idx = (int)(timeId % array.length());

// Cut the time to current window start.
time = time - time % windowLength;

while (true) {
WindowWrap<T> old = array.get(idx);
if (old == null) {
WindowWrap<T> window = new WindowWrap<T>(windowLength, time, newEmptyBucket());
if (array.compareAndSet(idx, null, window)) {
return window;
} else {
Thread.yield();
}
} else if (time == old.windowStart()) {
return old;
} else if (time > old.windowStart()) {
if (updateLock.tryLock()) {
try {
// if (old is deprecated) then [LOCK] resetTo currentTime.
return resetWindowTo(old, time);
} finally {
updateLock.unlock();
}
} else {
Thread.yield();
}

} else if (time < old.windowStart()) {
// Cannot go through here.
return new WindowWrap<T>(windowLength, time, newEmptyBucket());
}
}
}


public WindowWrap<T> getPreviousWindow(long time) { public WindowWrap<T> getPreviousWindow(long time) {
long timeId = (time - windowLength) / windowLength; long timeId = (time - windowLength) / windowLength;
@@ -87,16 +149,12 @@ public abstract class LeapArray<T> {
return old.value(); return old.value();
} }


AtomicReferenceArray<WindowWrap<T>> array() {
return array;
}

private boolean isWindowDeprecated(WindowWrap<T> windowWrap) { private boolean isWindowDeprecated(WindowWrap<T> windowWrap) {
return TimeUtil.currentTimeMillis() - windowWrap.windowStart() >= intervalInMs; return TimeUtil.currentTimeMillis() - windowWrap.windowStart() >= intervalInMs;
} }


public List<WindowWrap<T>> list() { public List<WindowWrap<T>> list() {
ArrayList<WindowWrap<T>> result = new ArrayList<WindowWrap<T>>();
List<WindowWrap<T>> result = new ArrayList<WindowWrap<T>>();


for (int i = 0; i < array.length(); i++) { for (int i = 0; i < array.length(); i++) {
WindowWrap<T> windowWrap = array.get(i); WindowWrap<T> windowWrap = array.get(i);
@@ -110,7 +168,7 @@ public abstract class LeapArray<T> {
} }


public List<T> values() { public List<T> values() {
ArrayList<T> result = new ArrayList<T>();
List<T> result = new ArrayList<T>();


for (int i = 0; i < array.length(); i++) { for (int i = 0; i < array.length(); i++) {
WindowWrap<T> windowWrap = array.get(i); WindowWrap<T> windowWrap = array.get(i);


sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/base/Window.java → sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/base/MetricBucket.java Просмотреть файл

@@ -23,7 +23,7 @@ import com.alibaba.csp.sentinel.Constants;
* @author jialiang.linjl * @author jialiang.linjl
* @author Eric Zhao * @author Eric Zhao
*/ */
public class Window {
public class MetricBucket {


private final LongAdder pass = new LongAdder(); private final LongAdder pass = new LongAdder();
private final LongAdder block = new LongAdder(); private final LongAdder block = new LongAdder();
@@ -33,7 +33,7 @@ public class Window {


private volatile long minRt; private volatile long minRt;


public Window() {
public MetricBucket() {
initMinRt(); initMinRt();
} }


@@ -46,7 +46,7 @@ public class Window {
* *
* @return new clean window * @return new clean window
*/ */
public Window reset() {
public MetricBucket reset() {
pass.reset(); pass.reset();
block.reset(); block.reset();
exception.reset(); exception.reset();

+ 30
- 31
sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/metric/ArrayMetric.java Просмотреть файл

@@ -20,27 +20,27 @@ import java.util.List;


import com.alibaba.csp.sentinel.Constants; import com.alibaba.csp.sentinel.Constants;
import com.alibaba.csp.sentinel.node.metric.MetricNode; import com.alibaba.csp.sentinel.node.metric.MetricNode;
import com.alibaba.csp.sentinel.slots.statistic.base.Window;
import com.alibaba.csp.sentinel.slots.statistic.base.MetricBucket;
import com.alibaba.csp.sentinel.slots.statistic.base.WindowWrap; import com.alibaba.csp.sentinel.slots.statistic.base.WindowWrap;


/** /**
* The basic metric class in Sentinel using a {@link WindowLeapArray} internal.
* The basic metric class in Sentinel using a {@link MetricsLeapArray} internal.
* *
* @author jialiang.linjl * @author jialiang.linjl
* @author Eric Zhao * @author Eric Zhao
*/ */
public class ArrayMetric implements Metric { public class ArrayMetric implements Metric {


private final WindowLeapArray data;
private final MetricsLeapArray data;


public ArrayMetric(int windowLength, int interval) { public ArrayMetric(int windowLength, int interval) {
this.data = new WindowLeapArray(windowLength, interval);
this.data = new MetricsLeapArray(windowLength, interval);
} }


/** /**
* For unit test. * For unit test.
*/ */
public ArrayMetric(WindowLeapArray array) {
public ArrayMetric(MetricsLeapArray array) {
this.data = array; this.data = array;
} }


@@ -49,8 +49,8 @@ public class ArrayMetric implements Metric {
data.currentWindow(); data.currentWindow();
long success = 0; long success = 0;


List<Window> list = data.values();
for (Window window : list) {
List<MetricBucket> list = data.values();
for (MetricBucket window : list) {
success += window.success(); success += window.success();
} }
return success; return success;
@@ -61,8 +61,8 @@ public class ArrayMetric implements Metric {
data.currentWindow(); data.currentWindow();
long success = 0; long success = 0;


List<Window> list = data.values();
for (Window window : list) {
List<MetricBucket> list = data.values();
for (MetricBucket window : list) {
if (window.success() > success) { if (window.success() > success) {
success = window.success(); success = window.success();
} }
@@ -74,8 +74,8 @@ public class ArrayMetric implements Metric {
public long exception() { public long exception() {
data.currentWindow(); data.currentWindow();
long exception = 0; long exception = 0;
List<Window> list = data.values();
for (Window window : list) {
List<MetricBucket> list = data.values();
for (MetricBucket window : list) {
exception += window.exception(); exception += window.exception();
} }
return exception; return exception;
@@ -85,8 +85,8 @@ public class ArrayMetric implements Metric {
public long block() { public long block() {
data.currentWindow(); data.currentWindow();
long block = 0; long block = 0;
List<Window> list = data.values();
for (Window window : list) {
List<MetricBucket> list = data.values();
for (MetricBucket window : list) {
block += window.block(); block += window.block();
} }
return block; return block;
@@ -96,9 +96,9 @@ public class ArrayMetric implements Metric {
public long pass() { public long pass() {
data.currentWindow(); data.currentWindow();
long pass = 0; long pass = 0;
List<Window> list = data.values();
List<MetricBucket> list = data.values();


for (Window window : list) {
for (MetricBucket window : list) {
pass += window.pass(); pass += window.pass();
} }
return pass; return pass;
@@ -108,8 +108,8 @@ public class ArrayMetric implements Metric {
public long rt() { public long rt() {
data.currentWindow(); data.currentWindow();
long rt = 0; long rt = 0;
List<Window> list = data.values();
for (Window window : list) {
List<MetricBucket> list = data.values();
for (MetricBucket window : list) {
rt += window.rt(); rt += window.rt();
} }
return rt; return rt;
@@ -119,8 +119,8 @@ public class ArrayMetric implements Metric {
public long minRt() { public long minRt() {
data.currentWindow(); data.currentWindow();
long rt = Constants.TIME_DROP_VALVE; long rt = Constants.TIME_DROP_VALVE;
List<Window> list = data.values();
for (Window window : list) {
List<MetricBucket> list = data.values();
for (MetricBucket window : list) {
if (window.minRt() < rt) { if (window.minRt() < rt) {
rt = window.minRt(); rt = window.minRt();
} }
@@ -133,7 +133,7 @@ public class ArrayMetric implements Metric {
public List<MetricNode> details() { public List<MetricNode> details() {
List<MetricNode> details = new ArrayList<MetricNode>(); List<MetricNode> details = new ArrayList<MetricNode>();
data.currentWindow(); data.currentWindow();
for (WindowWrap<Window> window : data.list()) {
for (WindowWrap<MetricBucket> window : data.list()) {
if (window == null) { if (window == null) {
continue; continue;
} }
@@ -156,38 +156,38 @@ public class ArrayMetric implements Metric {
} }


@Override @Override
public Window[] windows() {
public MetricBucket[] windows() {
data.currentWindow(); data.currentWindow();
return data.values().toArray(new Window[data.values().size()]);
return data.values().toArray(new MetricBucket[data.values().size()]);
} }


@Override @Override
public void addException() { public void addException() {
WindowWrap<Window> wrap = data.currentWindow();
WindowWrap<MetricBucket> wrap = data.currentWindow();
wrap.value().addException(); wrap.value().addException();
} }


@Override @Override
public void addBlock() { public void addBlock() {
WindowWrap<Window> wrap = data.currentWindow();
WindowWrap<MetricBucket> wrap = data.currentWindow();
wrap.value().addBlock(); wrap.value().addBlock();
} }


@Override @Override
public void addSuccess() { public void addSuccess() {
WindowWrap<Window> wrap = data.currentWindow();
WindowWrap<MetricBucket> wrap = data.currentWindow();
wrap.value().addSuccess(); wrap.value().addSuccess();
} }


@Override @Override
public void addPass() { public void addPass() {
WindowWrap<Window> wrap = data.currentWindow();
WindowWrap<MetricBucket> wrap = data.currentWindow();
wrap.value().addPass(); wrap.value().addPass();
} }


@Override @Override
public void addRT(long rt) { public void addRT(long rt) {
WindowWrap<Window> wrap = data.currentWindow();
WindowWrap<MetricBucket> wrap = data.currentWindow();
wrap.value().addRT(rt); wrap.value().addRT(rt);
} }


@@ -196,7 +196,7 @@ public class ArrayMetric implements Metric {
data.currentWindow(); data.currentWindow();
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(Thread.currentThread().getId()).append("_"); sb.append(Thread.currentThread().getId()).append("_");
for (WindowWrap<Window> windowWrap : data.list()) {
for (WindowWrap<MetricBucket> windowWrap : data.list()) {


sb.append(windowWrap.windowStart()).append(":").append(windowWrap.value().pass()).append(":") sb.append(windowWrap.windowStart()).append(":").append(windowWrap.value().pass()).append(":")
.append(windowWrap.value().block()); .append(windowWrap.value().block());
@@ -208,7 +208,7 @@ public class ArrayMetric implements Metric {


@Override @Override
public long previousWindowBlock() { public long previousWindowBlock() {
WindowWrap<Window> wrap = data.currentWindow();
WindowWrap<MetricBucket> wrap = data.currentWindow();
wrap = data.getPreviousWindow(); wrap = data.getPreviousWindow();
if (wrap == null) { if (wrap == null) {
return 0; return 0;
@@ -218,12 +218,11 @@ public class ArrayMetric implements Metric {


@Override @Override
public long previousWindowPass() { public long previousWindowPass() {
WindowWrap<Window> wrap = data.currentWindow();
WindowWrap<MetricBucket> wrap = data.currentWindow();
wrap = data.getPreviousWindow(); wrap = data.getPreviousWindow();
if (wrap == null) { if (wrap == null) {
return 0; return 0;
} }
return wrap.value().pass(); return wrap.value().pass();
} }

} }

+ 2
- 2
sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/metric/Metric.java Просмотреть файл

@@ -18,7 +18,7 @@ package com.alibaba.csp.sentinel.slots.statistic.metric;
import java.util.List; import java.util.List;


import com.alibaba.csp.sentinel.node.metric.MetricNode; import com.alibaba.csp.sentinel.node.metric.MetricNode;
import com.alibaba.csp.sentinel.slots.statistic.base.Window;
import com.alibaba.csp.sentinel.slots.statistic.base.MetricBucket;


/** /**
* Represents a basic structure recording invocation metrics of protected resources. * Represents a basic structure recording invocation metrics of protected resources.
@@ -79,7 +79,7 @@ public interface Metric {
* *
* @return window metric array * @return window metric array
*/ */
Window[] windows();
MetricBucket[] windows();


/** /**
* Increment by one the current exception count. * Increment by one the current exception count.


+ 45
- 0
sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/metric/MetricsLeapArray.java Просмотреть файл

@@ -0,0 +1,45 @@
/*
* 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.slots.statistic.metric;

import com.alibaba.csp.sentinel.slots.statistic.base.LeapArray;
import com.alibaba.csp.sentinel.slots.statistic.base.MetricBucket;
import com.alibaba.csp.sentinel.slots.statistic.base.WindowWrap;

/**
* The fundamental data structure for metric statistics in a time window.
*
* @author jialiang.linjl
* @author Eric Zhao
*/
public class MetricsLeapArray extends LeapArray<MetricBucket> {

public MetricsLeapArray(int windowLengthInMs, int intervalInSec) {
super(windowLengthInMs, intervalInSec);
}

@Override
public MetricBucket newEmptyBucket() {
return new MetricBucket();
}

@Override
protected WindowWrap<MetricBucket> resetWindowTo(WindowWrap<MetricBucket> w, long startTime) {
w.resetTo(startTime);
w.value().reset();
return w;
}
}

+ 0
- 88
sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/metric/WindowLeapArray.java Просмотреть файл

@@ -1,88 +0,0 @@
/*
* 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.slots.statistic.metric;

import java.util.concurrent.locks.ReentrantLock;

import com.alibaba.csp.sentinel.slots.statistic.base.LeapArray;
import com.alibaba.csp.sentinel.slots.statistic.base.Window;
import com.alibaba.csp.sentinel.slots.statistic.base.WindowWrap;

/**
* The fundamental data structure for metric statistics in a time window.
*
* @author jialiang.linjl
* @author Eric Zhao
*/
public class WindowLeapArray extends LeapArray<Window> {

public WindowLeapArray(int windowLengthInMs, int intervalInSec) {
super(windowLengthInMs, intervalInSec);
}

private ReentrantLock addLock = new ReentrantLock();

/**
* Reset current window to provided start time and reset all counters.
*
* @param startTime the start time of the window
* @return new clean window wrap
*/
private WindowWrap<Window> resetWindowTo(WindowWrap<Window> w, long startTime) {
w.resetTo(startTime);
w.value().reset();
return w;
}

@Override
public WindowWrap<Window> currentWindow(long time) {
long timeId = time / windowLength;
// Calculate current index.
int idx = (int)(timeId % array.length());

// Cut the time to current window start.
time = time - time % windowLength;

while (true) {
WindowWrap<Window> old = array.get(idx);
if (old == null) {
WindowWrap<Window> window = new WindowWrap<Window>(windowLength, time, new Window());
if (array.compareAndSet(idx, null, window)) {
return window;
} else {
Thread.yield();
}
} else if (time == old.windowStart()) {
return old;
} else if (time > old.windowStart()) {
if (addLock.tryLock()) {
try {
// if (old is deprecated) then [LOCK] resetTo currentTime.
return resetWindowTo(old, time);
} finally {
addLock.unlock();
}
} else {
Thread.yield();
}

} else if (time < old.windowStart()) {
// Cannot go through here.
return new WindowWrap<Window>(windowLength, time, new Window());
}
}
}
}

+ 5
- 5
sentinel-core/src/test/java/com/alibaba/csp/sentinel/base/metric/ArrayMetricTest.java Просмотреть файл

@@ -19,10 +19,10 @@ import java.util.ArrayList;


import org.junit.Test; import org.junit.Test;


import com.alibaba.csp.sentinel.slots.statistic.base.Window;
import com.alibaba.csp.sentinel.slots.statistic.base.MetricBucket;
import com.alibaba.csp.sentinel.slots.statistic.base.WindowWrap; import com.alibaba.csp.sentinel.slots.statistic.base.WindowWrap;
import com.alibaba.csp.sentinel.slots.statistic.metric.ArrayMetric; import com.alibaba.csp.sentinel.slots.statistic.metric.ArrayMetric;
import com.alibaba.csp.sentinel.slots.statistic.metric.WindowLeapArray;
import com.alibaba.csp.sentinel.slots.statistic.metric.MetricsLeapArray;


import static org.junit.Assert.*; import static org.junit.Assert.*;


@@ -40,10 +40,10 @@ public class ArrayMetricTest {


@Test @Test
public void testOperateArrayMetric() { public void testOperateArrayMetric() {
WindowLeapArray leapArray = mock(WindowLeapArray.class);
final WindowWrap<Window> windowWrap = new WindowWrap<Window>(windowLengthInMs, 0, new Window());
MetricsLeapArray leapArray = mock(MetricsLeapArray.class);
final WindowWrap<MetricBucket> windowWrap = new WindowWrap<MetricBucket>(windowLengthInMs, 0, new MetricBucket());
when(leapArray.currentWindow()).thenReturn(windowWrap); when(leapArray.currentWindow()).thenReturn(windowWrap);
when(leapArray.values()).thenReturn(new ArrayList<Window>() {{ add(windowWrap.value()); }});
when(leapArray.values()).thenReturn(new ArrayList<MetricBucket>() {{ add(windowWrap.value()); }});


ArrayMetric metric = new ArrayMetric(leapArray); ArrayMetric metric = new ArrayMetric(leapArray);




sentinel-core/src/test/java/com/alibaba/csp/sentinel/base/metric/WindowLeapArrayTest.java → sentinel-core/src/test/java/com/alibaba/csp/sentinel/base/metric/MetricsLeapArrayTest.java Просмотреть файл

@@ -21,30 +21,30 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;


import com.alibaba.csp.sentinel.slots.statistic.base.MetricBucket;
import com.alibaba.csp.sentinel.util.TimeUtil; import com.alibaba.csp.sentinel.util.TimeUtil;
import com.alibaba.csp.sentinel.slots.statistic.base.Window;
import com.alibaba.csp.sentinel.slots.statistic.base.WindowWrap; import com.alibaba.csp.sentinel.slots.statistic.base.WindowWrap;
import com.alibaba.csp.sentinel.slots.statistic.metric.WindowLeapArray;
import com.alibaba.csp.sentinel.slots.statistic.metric.MetricsLeapArray;


import org.junit.Test; import org.junit.Test;


import static org.junit.Assert.*; import static org.junit.Assert.*;


/** /**
* Test cases for {@link WindowLeapArray}.
* Test cases for {@link MetricsLeapArray}.
* *
* @author Eric Zhao * @author Eric Zhao
*/ */
public class WindowLeapArrayTest {
public class MetricsLeapArrayTest {


private final int windowLengthInMs = 1000; private final int windowLengthInMs = 1000;
private final int intervalInSec = 2; private final int intervalInSec = 2;


@Test @Test
public void testNewWindow() { public void testNewWindow() {
WindowLeapArray leapArray = new WindowLeapArray(windowLengthInMs, intervalInSec);
MetricsLeapArray leapArray = new MetricsLeapArray(windowLengthInMs, intervalInSec);
long time = TimeUtil.currentTimeMillis(); long time = TimeUtil.currentTimeMillis();
WindowWrap<Window> window = leapArray.currentWindow(time);
WindowWrap<MetricBucket> window = leapArray.currentWindow(time);


assertEquals(window.windowLength(), windowLengthInMs); assertEquals(window.windowLength(), windowLengthInMs);
assertEquals(window.windowStart(), time - time % windowLengthInMs); assertEquals(window.windowStart(), time - time % windowLengthInMs);
@@ -54,11 +54,11 @@ public class WindowLeapArrayTest {


@Test @Test
public void testLeapArrayWindowStart() { public void testLeapArrayWindowStart() {
WindowLeapArray leapArray = new WindowLeapArray(windowLengthInMs, intervalInSec);
MetricsLeapArray leapArray = new MetricsLeapArray(windowLengthInMs, intervalInSec);
long firstTime = TimeUtil.currentTimeMillis(); long firstTime = TimeUtil.currentTimeMillis();
long previousWindowStart = firstTime - firstTime % windowLengthInMs; long previousWindowStart = firstTime - firstTime % windowLengthInMs;


WindowWrap<Window> window = leapArray.currentWindow(firstTime);
WindowWrap<MetricBucket> window = leapArray.currentWindow(firstTime);


assertEquals(windowLengthInMs, window.windowLength()); assertEquals(windowLengthInMs, window.windowLength());
assertEquals(previousWindowStart, window.windowStart()); assertEquals(previousWindowStart, window.windowStart());
@@ -66,15 +66,15 @@ public class WindowLeapArrayTest {


@Test @Test
public void testWindowAfterOneInterval() { public void testWindowAfterOneInterval() {
WindowLeapArray leapArray = new WindowLeapArray(windowLengthInMs, intervalInSec);
MetricsLeapArray leapArray = new MetricsLeapArray(windowLengthInMs, intervalInSec);
long firstTime = TimeUtil.currentTimeMillis(); long firstTime = TimeUtil.currentTimeMillis();
long previousWindowStart = firstTime - firstTime % windowLengthInMs; long previousWindowStart = firstTime - firstTime % windowLengthInMs;
WindowWrap<Window> window = leapArray.currentWindow(previousWindowStart);
WindowWrap<MetricBucket> window = leapArray.currentWindow(previousWindowStart);


assertEquals(windowLengthInMs, window.windowLength()); assertEquals(windowLengthInMs, window.windowLength());
assertEquals(previousWindowStart, window.windowStart()); assertEquals(previousWindowStart, window.windowStart());


Window currentWindow = window.value();
MetricBucket currentWindow = window.value();
assertNotNull(currentWindow); assertNotNull(currentWindow);


currentWindow.addPass(); currentWindow.addPass();
@@ -87,7 +87,7 @@ public class WindowLeapArrayTest {
window = leapArray.currentWindow(middleTime); window = leapArray.currentWindow(middleTime);
assertEquals(previousWindowStart, window.windowStart()); assertEquals(previousWindowStart, window.windowStart());


Window middleWindow = window.value();
MetricBucket middleWindow = window.value();
middleWindow.addPass(); middleWindow.addPass();
assertSame(currentWindow, middleWindow); assertSame(currentWindow, middleWindow);
assertEquals(2L, middleWindow.pass()); assertEquals(2L, middleWindow.pass());
@@ -106,18 +106,18 @@ public class WindowLeapArrayTest {


@Deprecated @Deprecated
public void testWindowDeprecatedRefresh() { public void testWindowDeprecatedRefresh() {
WindowLeapArray leapArray = new WindowLeapArray(windowLengthInMs, intervalInSec);
MetricsLeapArray leapArray = new MetricsLeapArray(windowLengthInMs, intervalInSec);
final int len = intervalInSec * 1000 / windowLengthInMs; final int len = intervalInSec * 1000 / windowLengthInMs;
long firstTime = TimeUtil.currentTimeMillis(); long firstTime = TimeUtil.currentTimeMillis();
List<WindowWrap<Window>> firstIterWindowList = new ArrayList<WindowWrap<Window>>(len);
List<WindowWrap<MetricBucket>> firstIterWindowList = new ArrayList<WindowWrap<MetricBucket>>(len);
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
WindowWrap<Window> w = leapArray.currentWindow(firstTime + windowLengthInMs * i);
WindowWrap<MetricBucket> w = leapArray.currentWindow(firstTime + windowLengthInMs * i);
w.value().addPass(); w.value().addPass();
firstIterWindowList.add(i, w); firstIterWindowList.add(i, w);
} }


for (int i = len; i < len * 2; i++) { for (int i = len; i < len * 2; i++) {
WindowWrap<Window> w = leapArray.currentWindow(firstTime + windowLengthInMs * i);
WindowWrap<MetricBucket> w = leapArray.currentWindow(firstTime + windowLengthInMs * i);
assertNotSame(w, firstIterWindowList.get(i - len)); assertNotSame(w, firstIterWindowList.get(i - len));
} }
} }
@@ -126,7 +126,7 @@ public class WindowLeapArrayTest {
public void testMultiThreadUpdateEmptyWindow() throws Exception { public void testMultiThreadUpdateEmptyWindow() throws Exception {
final long time = TimeUtil.currentTimeMillis(); final long time = TimeUtil.currentTimeMillis();
final int nThreads = 16; final int nThreads = 16;
final WindowLeapArray leapArray = new WindowLeapArray(windowLengthInMs, intervalInSec);
final MetricsLeapArray leapArray = new MetricsLeapArray(windowLengthInMs, intervalInSec);
final CountDownLatch latch = new CountDownLatch(nThreads); final CountDownLatch latch = new CountDownLatch(nThreads);
Runnable task = new Runnable() { Runnable task = new Runnable() {
@Override @Override
@@ -147,9 +147,9 @@ public class WindowLeapArrayTest {


@Test @Test
public void testGetPreviousWindow() { public void testGetPreviousWindow() {
WindowLeapArray leapArray = new WindowLeapArray(windowLengthInMs, intervalInSec);
MetricsLeapArray leapArray = new MetricsLeapArray(windowLengthInMs, intervalInSec);
long time = TimeUtil.currentTimeMillis(); long time = TimeUtil.currentTimeMillis();
WindowWrap<Window> previousWindow = leapArray.currentWindow(time);
WindowWrap<MetricBucket> previousWindow = leapArray.currentWindow(time);
assertNull(leapArray.getPreviousWindow(time)); assertNull(leapArray.getPreviousWindow(time));


long nextTime = time + windowLengthInMs; long nextTime = time + windowLengthInMs;
@@ -165,16 +165,16 @@ public class WindowLeapArrayTest {
final int intervalInSec = 1; final int intervalInSec = 1;
final int intervalInMs = intervalInSec * 1000; final int intervalInMs = intervalInSec * 1000;


WindowLeapArray leapArray = new WindowLeapArray(windowLengthInMs, intervalInSec);
MetricsLeapArray leapArray = new MetricsLeapArray(windowLengthInMs, intervalInSec);
long time = TimeUtil.currentTimeMillis(); long time = TimeUtil.currentTimeMillis();


Set<WindowWrap<Window>> windowWraps = new HashSet<WindowWrap<Window>>();
Set<WindowWrap<MetricBucket>> windowWraps = new HashSet<WindowWrap<MetricBucket>>();


windowWraps.add(leapArray.currentWindow(time)); windowWraps.add(leapArray.currentWindow(time));
windowWraps.add(leapArray.currentWindow(time + windowLengthInMs)); windowWraps.add(leapArray.currentWindow(time + windowLengthInMs));


List<WindowWrap<Window>> list = leapArray.list();
for (WindowWrap<Window> wrap : list) {
List<WindowWrap<MetricBucket>> list = leapArray.list();
for (WindowWrap<MetricBucket> wrap : list) {
assertTrue(windowWraps.contains(wrap)); assertTrue(windowWraps.contains(wrap));
} }


@@ -191,18 +191,18 @@ public class WindowLeapArrayTest {
final int windowLengthInMs = 100; final int windowLengthInMs = 100;
final int intervalInSec = 1; final int intervalInSec = 1;


WindowLeapArray leapArray = new WindowLeapArray(windowLengthInMs, intervalInSec);
MetricsLeapArray leapArray = new MetricsLeapArray(windowLengthInMs, intervalInSec);
long time = TimeUtil.currentTimeMillis(); long time = TimeUtil.currentTimeMillis();


Set<WindowWrap<Window>> windowWraps = new HashSet<WindowWrap<Window>>();
Set<WindowWrap<MetricBucket>> windowWraps = new HashSet<WindowWrap<MetricBucket>>();


windowWraps.add(leapArray.currentWindow(time)); windowWraps.add(leapArray.currentWindow(time));
windowWraps.add(leapArray.currentWindow(time + windowLengthInMs)); windowWraps.add(leapArray.currentWindow(time + windowLengthInMs));


Thread.sleep(intervalInSec * 1000 + windowLengthInMs * 3); Thread.sleep(intervalInSec * 1000 + windowLengthInMs * 3);


List<WindowWrap<Window>> list = leapArray.list();
for (WindowWrap<Window> wrap : list) {
List<WindowWrap<MetricBucket>> list = leapArray.list();
for (WindowWrap<MetricBucket> wrap : list) {
assertTrue(windowWraps.contains(wrap)); assertTrue(windowWraps.contains(wrap));
} }



+ 0
- 6
sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/WarmUpFlowTest.java Просмотреть файл

@@ -39,12 +39,6 @@ public class WarmUpFlowTest {


FlowRuleManager.loadRules(Arrays.asList(flowRule)); FlowRuleManager.loadRules(Arrays.asList(flowRule));


//ContextUtil.enter(null);

//when(flowRule.selectNodeByRequsterAndStrategy(null, null, null)).thenReturn(value)

// flowRule.passCheck(null, DefaultNode, acquireCount, args)
// when(leapArray.values()).thenReturn(new ArrayList<Window>() {{ add(windowWrap.value()); }});
ContextUtil.enter("test"); ContextUtil.enter("test");


ContextUtil.exit(); ContextUtil.exit();


Загрузка…
Отмена
Сохранить