panjf2000 / ants

🐜🐜🐜 ants is the most powerful and reliable pooling solution for Go.
https://ants.andypan.me/
MIT License
12.83k stars 1.36k forks source link

[Question]: 如何支持有等待队列的非阻塞模式。 #338

Closed amosnothing closed 2 months ago

amosnothing commented 2 months ago

Questions with details

类似 Java 线程池一样,可以设置核心线程数,最大线程数,队列大小。并且每次 submit 任务都是不阻塞不报错。

我的使用场景: A 服务提交任务给 B 服务(这个是我的服务),B 服务因为资源有限不能无限提交任务(一个 nodejs 进程),并且任务耗时较长,所以每次 A 请求 B,B 会做基本的参数校验后,把任务放在池内,等池内有空闲 worker 来运行,并返回成功给 A,然后等待任务完毕后,回调给 A。所以 submit 如果阻塞会导致 A 调用 B 的 http 请求超时。

ants 能实现

  1. Nonblocking false 的情况下,当超过 pool size 后后续任务都会阻塞
  2. Nonblocking true 的情况下,当超过 pool size 后后续任务会报错

似乎无法满足我想要的效果。于是只能通过下面的方式来实现:(个人感觉写法不是太优雅)

Code snippets (optional)

go func() {
   err := pool.Submit()
}
panjf2000 commented 2 months ago

你其实就是想要一个像 ThreadPoolExecutor 里的 blocking queue,用 Go 很简单就能实现:你用一个 struct 把 ants.Pool 包起来,struct 里再塞一个阻塞队列然后用一个单独的 goroutine 去消费这个队列然后不断提交到 ants.Pool 就行了,图简单就直接用 channel 搞。

ants 的初衷就是为了限制 goroutine 的数量然后循环使用,节省系统资源,所以不会做像 Java 里的 CachedThreadPool 这样的无限缓冲线程池,如果用户有这种需求需要自己实现,做起来也很简单,就像我上面描述的。

amosnothing commented 2 months ago

谢谢

winterant commented 1 month ago

这种场景挺常见的,大佬提供的用struct包一层ants.Pool虽然没任何问题,但是如果ants能提供一个可选项来配置缓冲区也是很值得期待的。比如,用户可以自定义一个缓冲区大小,任务可以非阻塞放入缓冲区。默认情况下缓冲区大小为0就行。

用户的诉求可能希望尽可能简单的开箱即用、灵活使用,而不是自己还要包一层~