Skip to content

Commit 7841cae

Browse files
HzjNeverStop“HzjNeverStop”
and
“HzjNeverStop”
authored
Support auto transform SOFATracer Span in SOFA ThreadPool (#190)
Co-authored-by: “HzjNeverStop” <“[email protected]”>
1 parent e0ff800 commit 7841cae

14 files changed

+416
-8
lines changed

pom.xml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<groupId>com.alipay.sofa.common</groupId>
66
<artifactId>sofa-common-tools</artifactId>
7-
<version>2.0.1</version>
7+
<version>2.0.2</version>
88
<packaging>jar</packaging>
99

1010
<name>${project.groupId}:${project.artifactId}</name>
@@ -30,6 +30,7 @@
3030
<spring.boot.version>3.0.2</spring.boot.version>
3131
<junit.version>4.13.1</junit.version>
3232
<guava.version>27.0-jre</guava.version>
33+
<sofa.tracer.version>4.0.0</sofa.tracer.version>
3334
</properties>
3435

3536
<dependencyManagement>
@@ -50,6 +51,12 @@
5051
<artifactId>guava</artifactId>
5152
<version>${guava.version}</version>
5253
</dependency>
54+
<dependency>
55+
<groupId>com.alipay.sofa</groupId>
56+
<artifactId>tracer-core</artifactId>
57+
<version>${sofa.tracer.version}</version>
58+
<optional>true</optional>
59+
</dependency>
5360
<dependency>
5461
<groupId>org.slf4j</groupId>
5562
<artifactId>slf4j-api</artifactId>

src/main/java/com/alipay/sofa/common/thread/SofaScheduledThreadPoolExecutor.java

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
import com.alipay.sofa.common.thread.space.SpaceNamedThreadFactory;
2121
import com.alipay.sofa.common.utils.StringUtil;
2222

23+
import java.util.concurrent.Callable;
2324
import java.util.concurrent.RejectedExecutionHandler;
25+
import java.util.concurrent.ScheduledFuture;
2426
import java.util.concurrent.ScheduledThreadPoolExecutor;
2527
import java.util.concurrent.ThreadFactory;
2628
import java.util.concurrent.TimeUnit;
@@ -32,11 +34,12 @@
3234
* @version SofaScheduledThreadPoolExecutor.java, v 0.1 2020年11月09日 2:19 下午 huzijie Exp $
3335
*/
3436
public class SofaScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor {
35-
private static final String SIMPLE_CLASS_NAME = SofaScheduledThreadPoolExecutor.class
36-
.getSimpleName();
37-
private static final AtomicInteger POOL_COUNTER = new AtomicInteger(0);
37+
private static final String SIMPLE_CLASS_NAME = SofaScheduledThreadPoolExecutor.class
38+
.getSimpleName();
39+
private static final AtomicInteger POOL_COUNTER = new AtomicInteger(0);
3840
private final ThreadPoolConfig config;
3941
private final ThreadPoolStatistics statistics;
42+
private boolean sofaTracerTransmit = false;
4043

4144
/**
4245
* Basic constructor
@@ -193,4 +196,43 @@ public ThreadPoolConfig getConfig() {
193196
public ThreadPoolStatistics getStatistics() {
194197
return statistics;
195198
}
199+
200+
public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
201+
if (sofaTracerTransmit) {
202+
command = SofaTracerCommandFactory.ofRunnable(command);
203+
}
204+
return super.schedule(command, delay, unit);
205+
}
206+
207+
public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
208+
if (sofaTracerTransmit) {
209+
callable = SofaTracerCommandFactory.ofCallable(callable);
210+
}
211+
return super.schedule(callable, delay, unit);
212+
}
213+
214+
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period,
215+
TimeUnit unit) {
216+
if (sofaTracerTransmit) {
217+
command = SofaTracerCommandFactory.ofRunnable(command);
218+
}
219+
return super.scheduleAtFixedRate(command, initialDelay, period, unit);
220+
}
221+
222+
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay,
223+
long delay, TimeUnit unit) {
224+
if (sofaTracerTransmit) {
225+
command = SofaTracerCommandFactory.ofRunnable(command);
226+
}
227+
return super.scheduleWithFixedDelay(command, initialDelay, delay, unit);
228+
}
229+
230+
public void setSofaTracerTransmit(boolean sofaTracerTransmit) {
231+
this.sofaTracerTransmit = sofaTracerTransmit;
232+
}
233+
234+
public boolean isSofaTracerTransmit() {
235+
return sofaTracerTransmit;
236+
}
237+
196238
}

src/main/java/com/alipay/sofa/common/thread/SofaThreadPoolExecutor.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,12 @@
2929
* Created on 2020/3/16
3030
*/
3131
public class SofaThreadPoolExecutor extends ThreadPoolExecutor {
32-
private static final String SIMPLE_CLASS_NAME = SofaThreadPoolExecutor.class
33-
.getSimpleName();
34-
private static final AtomicInteger POOL_COUNTER = new AtomicInteger(0);
32+
private static final String SIMPLE_CLASS_NAME = SofaThreadPoolExecutor.class
33+
.getSimpleName();
34+
private static final AtomicInteger POOL_COUNTER = new AtomicInteger(0);
3535
private final ThreadPoolConfig config;
3636
private final ThreadPoolStatistics statistics;
37+
private boolean sofaTracerTransmit = false;
3738

3839
/**
3940
* Basic constructor
@@ -142,7 +143,8 @@ public SofaThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAl
142143

143144
@Override
144145
public void execute(Runnable command) {
145-
ExecutingRunnable runner = new ExecutingRunnable(command);
146+
ExecutingRunnable runner = sofaTracerTransmit ? SofaTracerCommandFactory
147+
.ofExecutingRunnable(command) : new ExecutingRunnable(command);
146148
runner.setEnqueueTime(System.currentTimeMillis());
147149
super.execute(runner);
148150
}
@@ -220,4 +222,12 @@ public ThreadPoolStatistics getStatistics() {
220222
private String createName() {
221223
return SIMPLE_CLASS_NAME + String.format("%08x", POOL_COUNTER.getAndIncrement());
222224
}
225+
226+
public void setSofaTracerTransmit(boolean sofaTracerTransmit) {
227+
this.sofaTracerTransmit = sofaTracerTransmit;
228+
}
229+
230+
public boolean isSofaTracerTransmit() {
231+
return sofaTracerTransmit;
232+
}
223233
}

src/main/java/com/alipay/sofa/common/thread/SofaThreadPoolTaskExecutor.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ public class SofaThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {
4242

4343
protected long period;
4444

45+
protected boolean sofaTracerTransmit;
46+
4547
@Override
4648
protected ExecutorService initializeExecutor(ThreadFactory threadFactory,
4749
RejectedExecutionHandler rejectedExecutionHandler) {
@@ -73,6 +75,7 @@ public void execute(Runnable command) {
7375
rejectedExecutionHandler, threadPoolName, spaceName, taskTimeout, period,
7476
TimeUnit.MILLISECONDS);
7577
}
78+
executor.setSofaTracerTransmit(sofaTracerTransmit);
7679

7780
Boolean allowCoreThreadTimeOut = ClassUtil.getField("allowCoreThreadTimeOut", this);
7881
if (allowCoreThreadTimeOut) {
@@ -144,4 +147,12 @@ public TimeUnit getTimeUnit() {
144147
}
145148
return sofaThreadPoolExecutor.getConfig().getTimeUnit();
146149
}
150+
151+
public boolean isSofaTracerTransmit() {
152+
return sofaTracerTransmit;
153+
}
154+
155+
public void setSofaTracerTransmit(boolean sofaTracerTransmit) {
156+
this.sofaTracerTransmit = sofaTracerTransmit;
157+
}
147158
}

src/main/java/com/alipay/sofa/common/thread/SofaThreadPoolTaskScheduler.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public class SofaThreadPoolTaskScheduler extends ThreadPoolTaskScheduler {
4343

4444
protected long period;
4545

46+
protected boolean sofaTracerTransmit;
47+
4648
@Override
4749
protected ExecutorService initializeExecutor(ThreadFactory threadFactory,
4850
RejectedExecutionHandler rejectedExecutionHandler) {
@@ -54,6 +56,7 @@ protected ExecutorService initializeExecutor(ThreadFactory threadFactory,
5456
SofaScheduledThreadPoolExecutor executor = new SofaScheduledThreadPoolExecutor(
5557
getPoolSize(), threadFactory, rejectedExecutionHandler, threadPoolName, spaceName,
5658
taskTimeout, period, TimeUnit.MILLISECONDS);
59+
executor.setSofaTracerTransmit(sofaTracerTransmit);
5760

5861
Boolean removeOnCancelPolicy = ClassUtil.getField("removeOnCancelPolicy", this);
5962
if (removeOnCancelPolicy) {
@@ -126,4 +129,8 @@ public TimeUnit getTimeUnit() {
126129
}
127130
return sofaScheduledThreadPoolExecutor.getConfig().getTimeUnit();
128131
}
132+
133+
public void setSofaTracerTransmit(boolean sofaTracerTransmit) {
134+
this.sofaTracerTransmit = sofaTracerTransmit;
135+
}
129136
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package com.alipay.sofa.common.thread;
18+
19+
import com.alipay.common.tracer.core.async.SofaTracerCallable;
20+
import com.alipay.common.tracer.core.async.SofaTracerRunnable;
21+
import com.alipay.sofa.common.utils.ClassUtil;
22+
23+
import java.util.concurrent.Callable;
24+
25+
/**
26+
* Factory to create SOFA-Tracer work command.
27+
* @author huzijie
28+
* @version SofaTracerCommandFactory.java, v 0.1 2023年09月26日 2:53 PM huzijie Exp $
29+
*/
30+
public class SofaTracerCommandFactory {
31+
32+
private static final String SOFA_TRACER_RUNNABLE_CLASS_NAME = "com.alipay.common.tracer.core.async.SofaTracerRunnable";
33+
private static final boolean SOFA_TRACER_CLASS_PRESENT = ClassUtil
34+
.isPresent(
35+
SOFA_TRACER_RUNNABLE_CLASS_NAME,
36+
SofaTracerCommandFactory.class
37+
.getClassLoader());
38+
39+
static ExecutingRunnable ofExecutingRunnable(Runnable runnable) {
40+
if (!SOFA_TRACER_CLASS_PRESENT) {
41+
return new ExecutingRunnable(runnable);
42+
}
43+
return new SofaTracerCommandFactory.SofaTracerExecutingRunnable(runnable);
44+
}
45+
46+
static Runnable ofRunnable(Runnable runnable) {
47+
if (!SOFA_TRACER_CLASS_PRESENT) {
48+
return runnable;
49+
}
50+
if (runnable instanceof SofaTracerRunnable) {
51+
return runnable;
52+
}
53+
return new SofaTracerRunnable(runnable);
54+
}
55+
56+
static <V> Callable<V> ofCallable(Callable<V> callable) {
57+
if (!SOFA_TRACER_CLASS_PRESENT) {
58+
return callable;
59+
}
60+
if (callable instanceof SofaTracerCallable) {
61+
return callable;
62+
}
63+
return new SofaTracerCallable<>(callable);
64+
}
65+
66+
/**
67+
* The wrapper to the {@link ExecutingRunnable} to transmit SofaTracerSpan.
68+
* @author huzijie
69+
* @version SofaTracerExecutingRunnable.java, v 0.1 2023年09月26日 11:45 AM huzijie Exp $
70+
*/
71+
public static class SofaTracerExecutingRunnable extends ExecutingRunnable {
72+
73+
private final SofaTracerRunnable sofaTracerRunnable;
74+
75+
public SofaTracerExecutingRunnable(Runnable originRunnable) {
76+
super(originRunnable);
77+
if (originRunnable instanceof SofaTracerRunnable) {
78+
this.sofaTracerRunnable = (SofaTracerRunnable) originRunnable;
79+
} else {
80+
this.sofaTracerRunnable = new SofaTracerRunnable(originRunnable);
81+
}
82+
}
83+
84+
@Override
85+
public void run() {
86+
sofaTracerRunnable.run();
87+
}
88+
}
89+
}

src/test/java/com/alipay/sofa/common/thread/SofaScheduledThreadPoolExecutorTest.java

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121
import org.junit.Before;
2222
import org.junit.Test;
2323

24+
import java.util.concurrent.CountDownLatch;
2425
import java.util.concurrent.ScheduledFuture;
2526
import java.util.concurrent.TimeUnit;
27+
import java.util.concurrent.atomic.AtomicInteger;
2628

2729
/**
2830
* @author huzijie
@@ -135,4 +137,81 @@ public void testLoggingBurst() throws Exception {
135137
Assert.assertEquals(numThreads, aberrantListAppender.list.size());
136138
Assert.assertTrue(isLastInfoMatch("Thread pool with name '\\S+' unregistered"));
137139
}
140+
141+
@Test
142+
public void testNoTracerTransmit() throws InterruptedException {
143+
AtomicInteger success = new AtomicInteger(0);
144+
CountDownLatch countDownLatch = new CountDownLatch(1);
145+
threadPool.schedule(() -> {
146+
try {
147+
assertTraceSpanNotExist();
148+
success.incrementAndGet();
149+
} finally {
150+
countDownLatch.countDown();
151+
}
152+
}, 10, TimeUnit.MILLISECONDS);
153+
countDownLatch.await();
154+
Assert.assertEquals(success.get(), 1);
155+
}
156+
157+
@Test
158+
public void testEnableTracerTransmit() throws InterruptedException {
159+
threadPool.setSofaTracerTransmit(true);
160+
161+
AtomicInteger fail = new AtomicInteger(0);
162+
CountDownLatch countDownLatch = new CountDownLatch(1);
163+
threadPool.schedule(() -> {
164+
try {
165+
assertTraceSpanExist();
166+
} catch (Throwable t) {
167+
fail.incrementAndGet();
168+
} finally {
169+
countDownLatch.countDown();
170+
}
171+
}, 10, TimeUnit.MILLISECONDS);
172+
Assert.assertTrue(countDownLatch.await(20, TimeUnit.MILLISECONDS));
173+
Assert.assertEquals(fail.get(), 0);
174+
175+
fail.set(0);
176+
threadPool.schedule(() -> {
177+
try {
178+
return assertTraceSpanExist();
179+
} catch (Throwable t) {
180+
fail.incrementAndGet();
181+
return null;
182+
} finally {
183+
countDownLatch.countDown();
184+
}
185+
}, 10, TimeUnit.MILLISECONDS);
186+
Assert.assertTrue(countDownLatch.await(20, TimeUnit.MILLISECONDS));
187+
Assert.assertEquals(fail.get(), 0);
188+
189+
fail.set(0);
190+
CountDownLatch fixRateCountDownLatch = new CountDownLatch(2);
191+
threadPool.scheduleAtFixedRate(() -> {
192+
try {
193+
assertTraceSpanExist();
194+
} catch (Throwable t) {
195+
fail.incrementAndGet();
196+
} finally {
197+
fixRateCountDownLatch.countDown();
198+
}
199+
}, 10, 10, TimeUnit.MILLISECONDS);
200+
Assert.assertTrue(fixRateCountDownLatch.await(30, TimeUnit.MILLISECONDS));
201+
Assert.assertEquals(fail.get(), 0);
202+
203+
fail.set(0);
204+
CountDownLatch fixDelayCountDownLatch = new CountDownLatch(2);
205+
threadPool.scheduleWithFixedDelay(() -> {
206+
try {
207+
assertTraceSpanExist();
208+
} catch (Throwable t) {
209+
fail.incrementAndGet();
210+
} finally {
211+
fixDelayCountDownLatch.countDown();
212+
}
213+
}, 10, 10, TimeUnit.MILLISECONDS);
214+
Assert.assertTrue(fixDelayCountDownLatch.await(30, TimeUnit.MILLISECONDS));
215+
Assert.assertEquals(fail.get(), 0);
216+
}
138217
}

0 commit comments

Comments
 (0)