Skip to content

Commit 9a7bcd7

Browse files
author
antonybi
committed
1. add coverage test
2. add travis CI 3. remove unnecessary lib 4. fix security problems
1 parent 2f73b54 commit 9a7bcd7

File tree

9 files changed

+156
-116
lines changed

9 files changed

+156
-116
lines changed

.travis.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
language: java
22

33
jdk:
4-
- openjdk8
4+
- openjdk8
5+
6+
after_success:
7+
- mvn clean test jacoco:report coveralls:report

pom.xml

Lines changed: 47 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>io.github.antonybi</groupId>
88
<artifactId>timechannel</artifactId>
9-
<version>1.1.0</version>
9+
<version>1.1.1</version>
1010

1111
<name>timechannel</name>
1212
<description>snowflake guid sdk</description>
@@ -33,8 +33,7 @@
3333
<properties>
3434
<java.version>8</java.version>
3535
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
36-
<spring-boot.version>2.3.12.RELEASE</spring-boot.version>
37-
<junit.version>5.6.2</junit.version>
36+
<spring-boot.version>2.6.11</spring-boot.version>
3837
</properties>
3938

4039
<dependencies>
@@ -45,12 +44,6 @@
4544
</dependency>
4645

4746
<!-- TOOL -->
48-
<dependency>
49-
<groupId>org.projectlombok</groupId>
50-
<artifactId>lombok</artifactId>
51-
<scope>provided</scope>
52-
</dependency>
53-
5447
<dependency>
5548
<groupId>javax.el</groupId>
5649
<artifactId>javax.el-api</artifactId>
@@ -66,7 +59,7 @@
6659
<dependency>
6760
<groupId>redis.clients</groupId>
6861
<artifactId>jedis</artifactId>
69-
<version>4.2.0</version>
62+
<version>4.2.3</version>
7063
</dependency>
7164

7265
<!-- SPRING -->
@@ -98,12 +91,6 @@
9891
</exclusion>
9992
</exclusions>
10093
</dependency>
101-
<dependency>
102-
<groupId>org.junit.jupiter</groupId>
103-
<artifactId>junit-jupiter-api</artifactId>
104-
<version>${junit.version}</version>
105-
<scope>test</scope>
106-
</dependency>
10794
</dependencies>
10895

10996
<dependencyManagement>
@@ -137,6 +124,31 @@
137124
<target>${java.version}</target>
138125
</configuration>
139126
</plugin>
127+
<plugin>
128+
<groupId>org.apache.maven.plugins</groupId>
129+
<artifactId>maven-surefire-plugin</artifactId>
130+
<version>2.22.2</version>
131+
</plugin>
132+
<plugin>
133+
<groupId>org.jacoco</groupId>
134+
<artifactId>jacoco-maven-plugin</artifactId>
135+
<version>0.8.8</version>
136+
<executions>
137+
<execution>
138+
<id>prepare-agent</id>
139+
<goals>
140+
<goal>prepare-agent</goal>
141+
</goals>
142+
</execution>
143+
<execution>
144+
<id>generate-code-coverage-report</id>
145+
<phase>test</phase>
146+
<goals>
147+
<goal>report</goal>
148+
</goals>
149+
</execution>
150+
</executions>
151+
</plugin>
140152
</plugins>
141153
</build>
142154

@@ -172,17 +184,6 @@
172184
</executions>
173185
</plugin>
174186
<plugin>
175-
<groupId>org.sonatype.plugins</groupId>
176-
<artifactId>nexus-staging-maven-plugin</artifactId>
177-
<version>1.6.7</version>
178-
<extensions>true</extensions>
179-
<configuration>
180-
<serverId>ossrh</serverId>
181-
<nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
182-
<autoReleaseAfterClose>true</autoReleaseAfterClose>
183-
</configuration>
184-
</plugin>
185-
<plugin>
186187
<groupId>org.apache.maven.plugins</groupId>
187188
<artifactId>maven-gpg-plugin</artifactId>
188189
<version>1.6</version>
@@ -196,6 +197,25 @@
196197
</execution>
197198
</executions>
198199
</plugin>
200+
<plugin>
201+
<groupId>org.eluder.coveralls</groupId>
202+
<artifactId>coveralls-maven-plugin</artifactId>
203+
<version>4.3.0</version>
204+
<configuration>
205+
<repoToken>yavqijXiUmoq93guQTknXuB9JEfpNc8v7</repoToken>
206+
</configuration>
207+
</plugin>
208+
<plugin>
209+
<groupId>org.sonatype.plugins</groupId>
210+
<artifactId>nexus-staging-maven-plugin</artifactId>
211+
<version>1.6.7</version>
212+
<extensions>true</extensions>
213+
<configuration>
214+
<serverId>ossrh</serverId>
215+
<nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
216+
<autoReleaseAfterClose>true</autoReleaseAfterClose>
217+
</configuration>
218+
</plugin>
199219
</plugins>
200220
</build>
201221
</profile>

src/main/java/timechannel/Guid.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package timechannel;
22

3-
import lombok.extern.slf4j.Slf4j;
43
import org.springframework.stereotype.Component;
54
import timechannel.core.Generator;
65

@@ -14,7 +13,6 @@
1413
* @author antonybi
1514
* @since 2022/08/18
1615
*/
17-
@Slf4j
1816
@Component
1917
public class Guid {
2018

src/main/java/timechannel/core/Allocator.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package timechannel.core;
22

3-
import lombok.extern.slf4j.Slf4j;
43
import org.apache.commons.io.IOUtils;
4+
import org.slf4j.Logger;
5+
import org.slf4j.LoggerFactory;
56
import org.springframework.beans.factory.annotation.Value;
67
import org.springframework.stereotype.Component;
78
import org.springframework.util.Assert;
@@ -21,9 +22,10 @@
2122
* @since 2022/08/18
2223
*/
2324
@Component
24-
@Slf4j
2525
public class Allocator {
2626

27+
private final Logger log = LoggerFactory.getLogger(Allocator.class);
28+
2729
private Jedis jedis;
2830

2931
/**
@@ -99,11 +101,7 @@ private Lease doGrant(int channelQuantity, Duration ttl, String appName) {
99101
throw new TimeChannelInternalException("no idle channel: " + Arrays.toString(response.toArray()));
100102
}
101103

102-
return Lease.builder()
103-
.channel(response.get(1))
104-
.effectiveTime(response.get(2))
105-
.expiryTime(response.get(3))
106-
.build();
104+
return new Lease(response.get(1), response.get(2), response.get(3));
107105
}
108106

109107
/**

src/main/java/timechannel/core/Generator.java

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package timechannel.core;
22

3-
import lombok.extern.slf4j.Slf4j;
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
45
import org.springframework.beans.factory.annotation.Value;
56
import org.springframework.stereotype.Component;
6-
import timechannel.exception.TimeChannelConfigException;
7-
import timechannel.exception.TimeChannelInternalException;
7+
import org.springframework.util.Assert;
88

99
import javax.annotation.PostConstruct;
1010
import javax.annotation.Resource;
@@ -32,9 +32,10 @@
3232
* @since 2022/08/18
3333
*/
3434
@Component
35-
@Slf4j
3635
public class Generator {
3736

37+
private final Logger log = LoggerFactory.getLogger(Generator.class);
38+
3839
/**
3940
* id生成的锁,此处采用非公平锁以保证性能
4041
*/
@@ -122,13 +123,12 @@ public class Generator {
122123
@PostConstruct
123124
public void init() {
124125
// 配置检查
125-
if (groupBits + channelBits + sequenceBits > CONFIGURABLE_BITS) {
126-
throw new TimeChannelConfigException("groupBits+channelBits+sequenceBits should be less than " + CONFIGURABLE_BITS);
127-
}
126+
Assert.isTrue(groupBits + channelBits + sequenceBits <= CONFIGURABLE_BITS,
127+
"groupBits+channelBits+sequenceBits should be less than " + CONFIGURABLE_BITS);
128+
128129
int groupRange = (int) Math.pow(2, groupBits);
129-
if (groupId < 0 || groupId >= groupRange) {
130-
throw new TimeChannelConfigException(String.format("group id %d should be in group range [0, %d)", groupId, groupRange));
131-
}
130+
Assert.isTrue(groupId >= 0 && groupId < groupRange,
131+
String.format("group id %d should be in group range [0, %d)", groupId, groupRange));
132132

133133
// 修正本地时间与lease时间差值
134134
localEffectiveTime = System.nanoTime();
@@ -140,27 +140,34 @@ public void init() {
140140
lease = allocator.grant(channelQuantity, ttl, appName);
141141

142142
// 开启异步的续期线程
143-
Thread renewThread = new Thread(() -> {
144-
while (true) {
145-
try {
146-
// 这里线程启动后立刻执行续期,是为了尽早暴露续期的异常
147-
allocator.renew(lease, ttl);
143+
Thread renewThread = new Thread(this::renewInLoop, "GUID Renew Thread");
144+
renewThread.start();
145+
}
148146

149-
// 这里需要提前更新,避免到期后更新的等待时间
150-
Thread.sleep(ttl.toMillis() / 2);
151-
} catch (InterruptedException e) {
152-
Thread.currentThread().interrupt();
153-
} catch (Exception e) {
147+
private void renewInLoop() {
148+
while (true) {
149+
try {
150+
// 这里线程启动后立刻执行续期,是为了尽早暴露续期的异常
151+
allocator.renew(lease, ttl);
152+
153+
// 这里需要提前更新,避免到期后更新的等待时间
154+
Thread.sleep(ttl.toMillis() / 2);
155+
} catch (InterruptedException e) {
156+
Thread.currentThread().interrupt();
157+
} catch (Exception e) {
158+
if (getLocalServerTime() >= lease.getExpiryTime()) {
159+
// 租约已经过期,正常情况有续期异步线程,不应该出现此现象
160+
log.error("lease has expired: {}", lease);
161+
} else {
154162
log.warn("renew lease failed, retry later", e);
155-
try {
156-
Thread.sleep(ERROR_WAIT);
157-
} catch (InterruptedException ie) {
158-
Thread.currentThread().interrupt();
159-
}
163+
}
164+
try {
165+
Thread.sleep(ERROR_WAIT);
166+
} catch (InterruptedException ie) {
167+
Thread.currentThread().interrupt();
160168
}
161169
}
162-
}, "GUID Renew Thread");
163-
renewThread.start();
170+
}
164171
}
165172

166173
/**
@@ -195,7 +202,6 @@ private <T> T next(Supplier<T> supplier) {
195202
try {
196203
Thread.sleep(ERROR_WAIT);
197204
} catch (InterruptedException interruptedException) {
198-
log.info("interrupted", e);
199205
Thread.currentThread().interrupt();
200206
}
201207
}
@@ -207,8 +213,7 @@ private <T> T next(Supplier<T> supplier) {
207213
}
208214

209215
private long fetchSequence() {
210-
// 这里需要采用nanoTime单调时钟用于计时,避免本地时钟回拨的问题
211-
long localServerTime = (System.nanoTime() - localEffectiveTime) / 1000000 + lease.getEffectiveTime();
216+
long localServerTime = getLocalServerTime();
212217

213218
// 时间片过期
214219
if (localServerTime > lastTimeSlice) {
@@ -232,6 +237,11 @@ private long fetchSequence() {
232237
return seq++;
233238
}
234239

240+
private long getLocalServerTime() {
241+
// 这里需要采用nanoTime单调时钟用于计时,避免本地时钟回拨的问题
242+
return (System.nanoTime() - localEffectiveTime) / 1000000 + lease.getEffectiveTime();
243+
}
244+
235245
public LocalDateTime parseDateTime(long guid) {
236246
return LocalDateTime.ofInstant(
237247
Instant.ofEpochMilli(guid >> (channelBits + sequenceBits)),
Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,10 @@
11
package timechannel.core;
22

3-
import lombok.*;
4-
53
/**
64
* 频道的租约
75
* @author antonybi
86
* @since 2022/08/18
97
*/
10-
@Data
11-
@Builder
12-
@NoArgsConstructor
13-
@AllArgsConstructor
14-
@ToString
158
public class Lease {
169

1710
/**
@@ -25,8 +18,47 @@ public class Lease {
2518
private long effectiveTime;
2619

2720
/**
28-
* 过期时间(注:这里虽然涉及多线程操作,但是逻辑上既做了提前更新,且含义上读取到旧值不会有任何问题,故没使用并发类)
21+
* 过期时间
2922
*/
3023
private long expiryTime;
3124

25+
long getChannel() {
26+
return channel;
27+
}
28+
29+
void setChannel(long channel) {
30+
this.channel = channel;
31+
}
32+
33+
long getEffectiveTime() {
34+
return effectiveTime;
35+
}
36+
37+
void setEffectiveTime(long effectiveTime) {
38+
this.effectiveTime = effectiveTime;
39+
}
40+
41+
long getExpiryTime() {
42+
return expiryTime;
43+
}
44+
45+
void setExpiryTime(long expiryTime) {
46+
this.expiryTime = expiryTime;
47+
}
48+
49+
Lease(long channel, long effectiveTime, long expiryTime) {
50+
this.channel = channel;
51+
this.effectiveTime = effectiveTime;
52+
this.expiryTime = expiryTime;
53+
}
54+
55+
@Override
56+
public String toString() {
57+
return "Lease{" +
58+
"channel=" + channel +
59+
", effectiveTime=" + effectiveTime +
60+
", expiryTime=" + expiryTime +
61+
'}';
62+
}
63+
3264
}

0 commit comments

Comments
 (0)