Skip to content

Commit

Permalink
[#9267] Add Clock with millisecond precision
Browse files Browse the repository at this point in the history
  • Loading branch information
emeroad committed Oct 13, 2022
1 parent e4e84e3 commit 3af5dcd
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.navercorp.pinpoint.common.profiler.clock;

/**
* millisecond precision clock
* @author Woonduk Kang(emeroad)
*/
public interface Clock {

long millis();

static Clock systemUTC() {
return SystemClock.UTC;
}

static Clock fixed(long timestamp) {
return new FixedClock(timestamp);
}

static Clock tick(long tick) {
return new TickClock(Clock.systemUTC(), tick);
}

static Clock tick(Clock clock, long tick) {
return new TickClock(clock, tick);
}

class SystemClock implements Clock {
static final SystemClock UTC = new SystemClock();

@Override
public long millis() {
return System.currentTimeMillis();
}
}

class FixedClock implements Clock {
private long timestamp;

public FixedClock(long timestamp) {
this.timestamp = timestamp;
}

@Override
public long millis() {
return timestamp;
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.navercorp.pinpoint.common.profiler.clock;

import java.util.Objects;

/**
* @author Woonduk Kang(emeroad)
*/
public class TickClock implements Clock {
private final Clock baseClock;
private final long tick;

public TickClock(Clock baseClock, long tick) {
this.baseClock = Objects.requireNonNull(baseClock, "baseClock");
if (tick < 0) {
throw new IllegalArgumentException("negative tick");
}
this.tick = tick;
}

public long millis() {
long millis = baseClock.millis();
return tick(millis);
}

public long tick(long millis) {
return millis - (millis % tick);
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package com.navercorp.pinpoint.common.server.bo.serializer.stat;

import com.navercorp.pinpoint.common.profiler.clock.Clock;
import com.navercorp.pinpoint.common.profiler.clock.TickClock;
import org.apache.commons.math3.util.Precision;

import static com.navercorp.pinpoint.common.hbase.HbaseColumnFamily.AGENT_STAT_STATISTICS;
Expand All @@ -28,6 +30,8 @@ public class AgentStatUtils {
public static final int NUM_DECIMALS = 4;
public static final long CONVERT_VALUE = (long) Math.pow(10, NUM_DECIMALS);

private static final TickClock CLOCK = new TickClock(Clock.systemUTC(), AGENT_STAT_STATISTICS.TIMESPAN_MS);

public static long convertDoubleToLong(double value) {
long convertedValue = (long) (value * CONVERT_VALUE);
return convertedValue;
Expand All @@ -49,6 +53,6 @@ public static double calculateRate(long count, long timeMs, int numDecimals, dou
}

public static long getBaseTimestamp(long timestamp) {
return timestamp - (timestamp % AGENT_STAT_STATISTICS.TIMESPAN_MS);
return CLOCK.tick(timestamp);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.navercorp.pinpoint.grpc.server.flowcontrol;

import com.navercorp.pinpoint.common.profiler.clock.Clock;
import com.navercorp.pinpoint.common.util.Assert;

import java.time.Clock;
import java.util.Objects;

public class DefaultIdleTimeout implements IdleTimeout {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package com.navercorp.pinpoint.grpc.server.flowcontrol;

import com.navercorp.pinpoint.common.profiler.clock.Clock;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.time.Clock;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

Expand All @@ -26,8 +25,7 @@ public void isExpired_init_state() {

@Test
public void isExpired_expired() {
Clock clock = mock(Clock.class);
when(clock.millis()).thenReturn(1L);
Clock clock = Clock.fixed(1L);

IdleTimeout idleTimeout = new DefaultIdleTimeout(0, clock);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.util.Objects;

import com.navercorp.pinpoint.common.profiler.clock.Clock;
import com.navercorp.pinpoint.common.util.Assert;
import com.navercorp.pinpoint.common.util.CollectionUtils;
import com.navercorp.pinpoint.profiler.monitor.metric.uri.AgentUriStatData;
Expand Down Expand Up @@ -82,9 +83,10 @@ private static class ExecutorListener implements AsyncQueueingExecutorListener<U
private final Object lock = new Object();

private final int uriStatDataLimitSize;
private final int collectInterval;
private final Clock clock;
private final LinkedList<AgentUriStatData> completedUriStatDataList;


private AgentUriStatData currentAgentUriStatData;

public ExecutorListener(int uriStatDataLimitSize) {
Expand All @@ -96,14 +98,14 @@ public ExecutorListener(int uriStatDataLimitSize, int collectInterval) {
this.uriStatDataLimitSize = uriStatDataLimitSize;

Assert.isTrue(collectInterval > 0, "collectInterval must be ' > 0'");
this.collectInterval = collectInterval;
this.clock = Clock.tick(collectInterval);

this.completedUriStatDataList = new LinkedList<>();
}

@Override
public void execute(Collection<UriStatInfo> messageList) {
final long currentBaseTimestamp = getBaseTimestamp();
final long currentBaseTimestamp = clock.millis();
checkAndFlushOldData(currentBaseTimestamp);

AgentUriStatData agentUriStatData = getCurrent(currentBaseTimestamp);
Expand All @@ -120,23 +122,18 @@ public void execute(Collection<UriStatInfo> messageList) {

@Override
public void execute(UriStatInfo message) {
long currentBaseTimestamp = getBaseTimestamp();
long currentBaseTimestamp = clock.millis();
checkAndFlushOldData(currentBaseTimestamp);

AgentUriStatData agentUriStatData = getCurrent(currentBaseTimestamp);
agentUriStatData.add(message);
}

public void executePollTimeout() {
long currentBaseTimestamp = getBaseTimestamp();
long currentBaseTimestamp = clock.millis();
checkAndFlushOldData(currentBaseTimestamp);
}

private long getBaseTimestamp() {
long currentTimeMillis = System.currentTimeMillis();
long timestamp = currentTimeMillis - (currentTimeMillis % collectInterval);
return timestamp;
}

private boolean checkAndFlushOldData(long currentBaseTimestamp) {
if (currentAgentUriStatData == null) {
Expand Down

0 comments on commit 3af5dcd

Please sign in to comment.