Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support TTL Wrapper for Functional Interface like Supplier | 对Supplier方式提交的任务支持不友好 #162

Closed
liuzhongkai opened this issue Jan 20, 2020 · 4 comments

Comments

@liuzhongkai
Copy link

liuzhongkai commented Jan 20, 2020

support TTL Wrapper for Functional Interface like Supplier.

Otherwise need convert Supplier to Callable, this is not convenient.


需要将Supplier转换为Callable

@oldratlee oldratlee added 📐 design discussion ❓question Further information is requested labels Jan 20, 2020
@oldratlee
Copy link
Member

oldratlee commented Jan 22, 2020

  • Callable/Runnable表义的是运行的任务,与Executor相关;而Suppiler表义的是数据源。

  • 如果你用的Java8Suppiler转成Callable通过lambda半行代码完成,很简单:

    executorService.invoke(() -> supplier.get());

考虑上面2个原因,就像ExecutorService一样,先不直接支持Suppiler@liuzhongkai

  • 避免使用的API膨胀复杂,表义不清
  • 需要的Suppiler转成Callable的地方,业务半行代码完成,很简单

@liuzhongkai
Copy link
Author

liuzhongkai commented Jan 22, 2020

使用java8中的CompletableFuture类对外接口并没有Callable类型的输入,取而代之的是Suppiler,Suppiler转换Callable很丑陋

TtlCallable<Object> objectTtlCallable = TtlCallable.get(supplier::get);
CompletableFuture.supplyAsync(() -> {
    try {
        return objectTtlCallable.call();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}, executor);

@oldratlee
Copy link
Member

oldratlee commented Jan 22, 2020

使用java8中的CompletableFuture类对外接口并没有Callable类型的输入

1. 对CompletableFutureWrap Suppiler

上面Suppiler转换Callable的方式确实繁复丑陋,推荐下一节的Java Agent透明支持的方式。

或是你先模仿TtlCallable实现一下TtlSuppiler 😀
简单、有效、直接的方式是实现一个工具方法(不用Suppiler转换Callable、包异常): @liuzhongkai

// 工具方法
public static <T> Supplier<T> getTtlSupplier(Supplier<T> supplier) {
    final Object capture = TransmittableThreadLocal.Transmitter.capture();
    return () -> {
        final Object backup = TransmittableThreadLocal.Transmitter.replay(capture);
        try {
            return supplier.get();
        } finally {
            TransmittableThreadLocal.Transmitter.restore(backup);
        }
    };
}

// 使用方式
CompletableFuture.supplyAsync(getTtlSupplier(supplier), executor);

# 我也想想怎么wapper方式做TTL的Supplier集成

2. Java Agent方式 透明 支持了CompletableFutureStream

见文档说明:2.3 使用Java Agent来修饰JDK线程池实现类
👉 透明👈 支持了CompletableFutureStream

注意Java 8引入的CompletableFuture与(并行执行的)Stream底层是通过ForkJoinPool来执行,所以支持ForkJoinPool后,TTL也就透明支持了CompletableFutureStream。🎉

因为 CompletableFutureStream 封装的设计实现方式,没有办法用 Wrapper/修饰器的方式 为 CompletableFutureStream 提供 传递功能(TransmittableThreadLocal)。


如果你对原因有兴趣/进一步系统理解或确认,可以看看:

@oldratlee
Copy link
Member

oldratlee commented Jan 22, 2020

发布了v2.11.4,增加了对相关类型(如SupplierConsumer)的TTL Wrapper工具方法。

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>transmittable-thread-local</artifactId>
    <version>2.11.4</version>
</dependency>

@liuzhongkai 试试,看看是不是OK的?

import com.alibaba.ttl.TtlWrappers;

import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;

public class SupplierTtlWrapperDemo {
    public static void main(String[] args) throws Exception {
        final Supplier<String> supplier = () -> "42";
        final CompletableFuture<String> future = CompletableFuture.supplyAsync(
                TtlWrappers.wrap(supplier));

        System.out.println(future.get());
    }
}

更多详见JavaDoc

@oldratlee oldratlee changed the title 对Supplier方式提交的任务不友好 support TTL Wrapper for Functional Interface like Supplier | Supplier对Supplier方式提交的任务不友好 Jan 24, 2020
@oldratlee oldratlee changed the title support TTL Wrapper for Functional Interface like Supplier | Supplier对Supplier方式提交的任务不友好 support TTL Wrapper for Functional Interface like Supplier | 对Supplier方式提交的任务支持不友好 Jun 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants