README-EN.md 12.2 KB
Newer Older
oldratlee's avatar
oldratlee 已提交
1
# 📌 Transmittable ThreadLocal(TTL) 📌
oldratlee's avatar
oldratlee 已提交
2

oldratlee's avatar
oldratlee 已提交
3
[![Build Status](https://travis-ci.org/alibaba/transmittable-thread-local.svg?branch=master)](https://travis-ci.org/alibaba/transmittable-thread-local)
4
[![Windows Build Status](https://img.shields.io/appveyor/ci/oldratlee/transmittable-thread-local/master.svg?label=windows%20build)](https://ci.appveyor.com/project/oldratlee/transmittable-thread-local)
oldratlee's avatar
oldratlee 已提交
5
[![Coverage Status](https://img.shields.io/codecov/c/github/alibaba/transmittable-thread-local/master.svg)](https://codecov.io/gh/alibaba/transmittable-thread-local/branch/master)
oldratlee's avatar
oldratlee 已提交
6 7 8
[![Maintainability](https://api.codeclimate.com/v1/badges/de6af6136e538cf1557c/maintainability)](https://codeclimate.com/github/alibaba/transmittable-thread-local/maintainability)  
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
[![Javadocs](https://www.javadoc.io/badge/com.alibaba/transmittable-thread-local.svg)](https://www.javadoc.io/doc/com.alibaba/transmittable-thread-local)
J
Jerry Lee 已提交
9
[![Maven Central](https://img.shields.io/maven-central/v/com.alibaba/transmittable-thread-local.svg)](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.alibaba%22%20AND%20a%3A%22transmittable-thread-local%22)
oldratlee's avatar
oldratlee 已提交
10
[![GitHub release](https://img.shields.io/github/release/alibaba/transmittable-thread-local.svg)](https://github.com/alibaba/transmittable-thread-local/releases)  
T
The Gitter Badger 已提交
11
[![Join the chat at https://gitter.im/alibaba/transmittable-thread-local](https://badges.gitter.im/alibaba/transmittable-thread-local.svg)](https://gitter.im/alibaba/transmittable-thread-local?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
oldratlee's avatar
oldratlee 已提交
12
[![GitHub issues](https://img.shields.io/github/issues/alibaba/transmittable-thread-local.svg)](https://github.com/alibaba/transmittable-thread-local/issues)
oldratlee's avatar
oldratlee 已提交
13 14
[![Percentage of issues still open](http://isitmaintained.com/badge/open/alibaba/transmittable-thread-local.svg)](http://isitmaintained.com/project/alibaba/transmittable-thread-local "Percentage of issues still open")
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/alibaba/transmittable-thread-local.svg)](http://isitmaintained.com/project/alibaba/transmittable-thread-local "Average time to resolve an issue")
oldratlee's avatar
oldratlee 已提交
15

oldratlee's avatar
oldratlee 已提交
16
📖 English Documentation | [📖 中文文档](README.md)
oldratlee's avatar
oldratlee 已提交
17

oldratlee's avatar
oldratlee 已提交
18 19 20 21 22 23
----------------------------------------

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->


oldratlee's avatar
oldratlee 已提交
24 25 26
- [🔧 Functions](#-functions)
- [🎨 Requirements](#-requirements)
- [👥 User Guide](#-user-guide)
oldratlee's avatar
oldratlee 已提交
27 28 29 30
    - [1. simple usage](#1-simple-usage)
    - [2. Transmit value even using thread pool](#2-transmit-value-even-using-thread-pool)
        - [2.1 Decorate `Runnable` and `Callable`](#21-decorate-runnable-and-callable)
        - [2.2 Decorate thread pool](#22-decorate-thread-pool)
31
        - [2.3 Use Java Agent to decorate thread pool implementation class](#23-use-java-agent-to-decorate-thread-pool-implementation-class)
oldratlee's avatar
oldratlee 已提交
32 33 34 35 36
- [🔌 Java API Docs](#-java-api-docs)
- [🍪 Maven dependency](#-maven-dependency)
- [🗿 More documentation](#-more-documentation)
- [📚 Related resources](#-related-resources)
    - [JDK core classes](#jdk-core-classes)
oldratlee's avatar
oldratlee 已提交
37 38
    - [Java Agent](#java-agent)
    - [Javassist](#javassist)
oldratlee's avatar
oldratlee 已提交
39
- [👷 Contributors](#-contributors)
oldratlee's avatar
oldratlee 已提交
40 41 42 43 44

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

----------------------------------------

oldratlee's avatar
oldratlee 已提交
45
# 🔧 Functions
oldratlee's avatar
oldratlee 已提交
46

oldratlee's avatar
oldratlee 已提交
47
👉 The missing std Java™ lib(simple &amp; 0-dependency) for framework/middleware,
J
Jerry Lee 已提交
48
transmitting ThreadLocal value between threads even using thread pool like components.
oldratlee's avatar
oldratlee 已提交
49
Support `Java` 11/10/9/8/7/6.
oldratlee's avatar
oldratlee 已提交
50

51
Class [`InheritableThreadLocal`](https://docs.oracle.com/javase/8/docs/api/java/lang/InheritableThreadLocal.html) in `JDK`
52
can transmit value to child thread from parent thread.
oldratlee's avatar
oldratlee 已提交
53

54 55
But when use thread pool, thread is cached up and used repeatedly. Transmitting value from parent thread to child thread has no meaning.
Application need transmit value from the time task is created to the time task is executed.
oldratlee's avatar
oldratlee 已提交
56

oldratlee's avatar
oldratlee 已提交
57
If you have problem or question, please [submit Issue](https://github.com/alibaba/transmittable-thread-local/issues) or play [fork](https://github.com/alibaba/transmittable-thread-local/fork) and pull request dance.
oldratlee's avatar
oldratlee 已提交
58

oldratlee's avatar
oldratlee 已提交
59
# 🎨 Requirements
oldratlee's avatar
oldratlee 已提交
60

oldratlee's avatar
oldratlee 已提交
61
The Requirements listed below is also why I sort out `TTL` in my work.
oldratlee's avatar
oldratlee 已提交
62

oldratlee's avatar
oldratlee 已提交
63 64
- Application container or high layer framework transmit information to low layer sdk.
- Transmit context to logging without application code aware.
oldratlee's avatar
oldratlee 已提交
65

oldratlee's avatar
oldratlee 已提交
66
# 👥 User Guide
oldratlee's avatar
oldratlee 已提交
67

oldratlee's avatar
oldratlee 已提交
68
## 1. simple usage
oldratlee's avatar
oldratlee 已提交
69 70 71

```java
// set in parent thread
72
TransmittableThreadLocal<String> parent = new TransmittableThreadLocal<String>();
oldratlee's avatar
oldratlee 已提交
73 74 75 76 77
parent.set("value-set-in-parent");

// =====================================================

// read in child thread, value is "value-set-in-parent"
oldratlee's avatar
oldratlee 已提交
78
String value = parent.get();
oldratlee's avatar
oldratlee 已提交
79 80
```

81
This is the function of class [`InheritableThreadLocal`](https://docs.oracle.com/javase/8/docs/api/java/lang/InheritableThreadLocal.html), should use class [`InheritableThreadLocal`](https://docs.oracle.com/javase/8/docs/api/java/lang/InheritableThreadLocal.html) instead.
oldratlee's avatar
oldratlee 已提交
82

83 84
But when use thread pool, thread is cached up and used repeatedly. Transmitting value from parent thread to child thread has no meaning.
Application need transmit value from the time task is created to the point task is executed.
oldratlee's avatar
oldratlee 已提交
85 86 87

The solution is below usage.

oldratlee's avatar
oldratlee 已提交
88
## 2. Transmit value even using thread pool
oldratlee's avatar
oldratlee 已提交
89 90 91

### 2.1 Decorate `Runnable` and `Callable`

oldratlee's avatar
oldratlee 已提交
92 93
Decorate input `Runnable` and `Callable` by [`TtlRunnable`](/src/main/java/com/alibaba/ttl/TtlRunnable.java)
and [`TtlCallable`](src/main/java/com/alibaba/ttl/TtlCallable.java).
oldratlee's avatar
oldratlee 已提交
94 95 96 97

Sample code:

```java
98
TransmittableThreadLocal<String> parent = new TransmittableThreadLocal<String>();
oldratlee's avatar
oldratlee 已提交
99 100 101
parent.set("value-set-in-parent");

Runnable task = new Task("1");
102
// extra work, create decorated ttlRunnable object
oldratlee's avatar
oldratlee 已提交
103
Runnable ttlRunnable = TtlRunnable.get(task);
104
executorService.submit(ttlRunnable);
oldratlee's avatar
oldratlee 已提交
105 106 107 108

// =====================================================

// read in task, value is "value-set-in-parent"
oldratlee's avatar
oldratlee 已提交
109
String value = parent.get();
oldratlee's avatar
oldratlee 已提交
110 111 112 113 114
```

above code show how to dealing with `Runnable`, `Callable` is similar:

```java
115
TransmittableThreadLocal<String> parent = new TransmittableThreadLocal<String>();
oldratlee's avatar
oldratlee 已提交
116 117 118
parent.set("value-set-in-parent");

Callable call = new Call("1");
119
// extra work, create decorated ttlCallable object
oldratlee's avatar
oldratlee 已提交
120
Callable ttlCallable = TtlCallable.get(call);
121
executorService.submit(ttlCallable);
oldratlee's avatar
oldratlee 已提交
122 123 124 125

// =====================================================

// read in call, value is "value-set-in-parent"
oldratlee's avatar
oldratlee 已提交
126
String value = parent.get();
oldratlee's avatar
oldratlee 已提交
127 128 129 130 131 132 133
```

### 2.2 Decorate thread pool

Eliminating the work of `Runnable` and `Callable` Decoration every time it is submitted to thread pool. This work can completed in the thread pool.

Use util class
134
[`com.alibaba.ttl.threadpool.TtlExecutors`](src/main/java/com/alibaba/ttl/threadpool/TtlExecutors.java)
oldratlee's avatar
oldratlee 已提交
135 136
to decorate thread pool.

137
Util class `com.alibaba.ttl.threadpool.TtlExecutors` has below methods:
oldratlee's avatar
oldratlee 已提交
138

oldratlee's avatar
oldratlee 已提交
139 140 141
- `getTtlExecutor`: decorate interface `Executor`
- `getTtlExecutorService`: decorate interface `ExecutorService`
- `getTtlScheduledExecutorService`: decorate interface `ScheduledExecutorService`
oldratlee's avatar
oldratlee 已提交
142 143 144 145 146 147

Sample code:

```java
ExecutorService executorService = ...
// extra work, create decorated executorService object
oldratlee's avatar
oldratlee 已提交
148
executorService = TtlExecutors.getTtlExecutorService(executorService);
oldratlee's avatar
oldratlee 已提交
149

150
TransmittableThreadLocal<String> parent = new TransmittableThreadLocal<String>();
oldratlee's avatar
oldratlee 已提交
151 152 153 154 155 156 157 158 159 160
parent.set("value-set-in-parent");

Runnable task = new Task("1");
Callable call = new Call("2");
executorService.submit(task);
executorService.submit(call);

// =====================================================

// read in Task or Callable, value is "value-set-in-parent"
oldratlee's avatar
oldratlee 已提交
161
String value = parent.get();
oldratlee's avatar
oldratlee 已提交
162 163
```

164
### 2.3 Use Java Agent to decorate thread pool implementation class
oldratlee's avatar
oldratlee 已提交
165

166
In this usage, transmission is transparent\(no decoration operation\).
oldratlee's avatar
oldratlee 已提交
167 168 169 170 171 172 173 174 175 176 177 178 179

Sample code:

```java
ExecutorService executorService = Executors.newFixedThreadPool(3);

Runnable task = new Task("1");
Callable call = new Call("2");
executorService.submit(task);
executorService.submit(call);

// =====================================================

oldratlee's avatar
oldratlee 已提交
180
// read in Task or Callable, value is "value-set-in-parent"
oldratlee's avatar
oldratlee 已提交
181 182 183
String value = parent.get();
```

184
See demo [`AgentDemo.java`](src/test/java/com/alibaba/demo/agent/AgentDemo.java).
oldratlee's avatar
oldratlee 已提交
185 186

Agent decorate 2 thread pool implementation classes
187
\(implementation code [`TtlTransformer.java`](src/main/java/com/alibaba/ttl/threadpool/agent/TtlTransformer.java)\):
oldratlee's avatar
oldratlee 已提交
188 189 190 191

- `java.util.concurrent.ThreadPoolExecutor`
- `java.util.concurrent.ScheduledThreadPoolExecutor`

oldratlee's avatar
oldratlee 已提交
192
Add start options on Java command:
oldratlee's avatar
oldratlee 已提交
193

oldratlee's avatar
oldratlee 已提交
194
- `-javaagent:path/to/transmittable-thread-local-2.x.x.jar`
oldratlee's avatar
oldratlee 已提交
195

oldratlee's avatar
oldratlee 已提交
196
**NOTE**
oldratlee's avatar
oldratlee 已提交
197

oldratlee's avatar
oldratlee 已提交
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
- Because TTL agent modify the `JDK` std lib classes, make code refer from std lib class to the `TTL` class, so the jar of `TTL Agent` should add to `boot classpath`.
- Since `v2.6.0`, `TTL agent jar` will auto add self to `boot classpath`. But you can NOT modify the downloaded `TTL jar` file name.
    - if you modified the download `TTL jar` file name(eg: `ttl-foo-name-changed.jar`), 
      you must add by `-Xbootclasspath/a:path/to/ttl-foo-name-changed.jar`.

Implementation is using `Boot-Class-Path` property of `manifest` file(`META-INF/MANIFEST.MF`) in the `TTL Java Agent Jar`

> Boot-Class-Path
> A list of paths to be searched by the bootstrap class loader. Paths represent directories or libraries (commonly referred to as JAR or zip libraries on many platforms).
> These paths are searched by the bootstrap class loader after the platform specific mechanisms of locating a class have failed. Paths are searched in the order listed.

More info:

- [`Java Agent Specification` - `JavaDoc`文档](https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html#package.description)
- [JAR File Specification - JAR Manifest](https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#JAR_Manifest)
- [Working with Manifest Files - The Java™ TutorialsHide](https://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html)
oldratlee's avatar
oldratlee 已提交
214 215 216 217

Java command example:

```bash
oldratlee's avatar
oldratlee 已提交
218 219 220 221 222 223 224 225 226 227
java -javaagent:transmittable-thread-local-2.x.x.jar \
    -cp classes \
    com.alibaba.ttl.threadpool.agent.demo.AgentDemo
```

or

```bash
java -javaagent:path/to/ttl-foo-name-changed.jar \
    -Xbootclasspath/a:path/to/ttl-foo-name-changed.jar \
oldratlee's avatar
oldratlee 已提交
228
    -cp classes \
229
    com.alibaba.ttl.threadpool.agent.demo.AgentDemo
oldratlee's avatar
oldratlee 已提交
230 231
```

oldratlee's avatar
oldratlee 已提交
232
Run the script [`scripts/run-agent-demo.sh`](scripts/run-agent-demo.sh)
oldratlee's avatar
oldratlee 已提交
233 234
to start demo of "Use Java Agent to decorate thread pool implementation class".

oldratlee's avatar
oldratlee 已提交
235
# 🔌 Java API Docs
236

oldratlee's avatar
oldratlee 已提交
237
The current version Java API documentation: <http://alibaba.github.io/transmittable-thread-local/apidocs/>
238

oldratlee's avatar
oldratlee 已提交
239
# 🍪 Maven dependency
oldratlee's avatar
oldratlee 已提交
240 241 242

```xml
<dependency>
oldratlee's avatar
oldratlee 已提交
243 244
    <groupId>com.alibaba</groupId>
    <artifactId>transmittable-thread-local</artifactId>
oldratlee's avatar
oldratlee 已提交
245
    <version>2.6.0</version>
oldratlee's avatar
oldratlee 已提交
246 247 248
</dependency>
```

249
Check available version at [search.maven.org](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.alibaba%22%20AND%20a%3A%22transmittable-thread-local%22).
oldratlee's avatar
oldratlee 已提交
250

oldratlee's avatar
oldratlee 已提交
251
# 🗿 More documentation
oldratlee's avatar
oldratlee 已提交
252

oldratlee's avatar
oldratlee 已提交
253
- [🎓 Developer Guide](docs/developer-guide-en.md)
oldratlee's avatar
oldratlee 已提交
254

oldratlee's avatar
oldratlee 已提交
255
# 📚 Related resources
oldratlee's avatar
oldratlee 已提交
256

oldratlee's avatar
oldratlee 已提交
257
## JDK core classes
oldratlee's avatar
oldratlee 已提交
258

oldratlee's avatar
oldratlee 已提交
259 260
- [WeakHashMap](https://docs.oracle.com/javase/8/docs/api/java/util/WeakHashMap.html)
- [InheritableThreadLocal](https://docs.oracle.com/javase/8/docs/api/java/lang/InheritableThreadLocal.html)
oldratlee's avatar
oldratlee 已提交
261

oldratlee's avatar
oldratlee 已提交
262
## Java Agent
oldratlee's avatar
oldratlee 已提交
263

oldratlee's avatar
oldratlee 已提交
264 265 266 267
- [Java Agent规范](https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html)
- [Java SE 6 新特性: Instrumentation 新功能](http://www.ibm.com/developerworks/cn/java/j-lo-jse61/)
- [Creation, dynamic loading and instrumentation with javaagents](http://dhruba.name/2010/02/07/creation-dynamic-loading-and-instrumentation-with-javaagents/)
- [JavaAgent加载机制分析](http://alipaymiddleware.com/jvm/javaagent%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6%E5%88%86%E6%9E%90/)
oldratlee's avatar
oldratlee 已提交
268

oldratlee's avatar
oldratlee 已提交
269
## Javassist
oldratlee's avatar
oldratlee 已提交
270

oldratlee's avatar
oldratlee 已提交
271 272 273 274 275 276 277
- [Getting Started with Javassist](http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/tutorial/tutorial.html)

# 👷 Contributors

- Jerry Lee \<oldratlee at gmail dot com> [@oldratlee](https://github.com/oldratlee)
- Yang Fang \<snoop.fy at gmail dot com> [@driventokill](https://github.com/driventokill)
- wuwen \<wuwen.55 at aliyun dot com> [@wuwen5](https://github.com/wuwen5)
oldratlee's avatar
oldratlee 已提交
278
- David Dai \<351450944 at qq dot com> [@LNAmp](https://github.com/LNAmp)
oldratlee's avatar
oldratlee 已提交
279
- Your name here :-)