SubmissionPublisher 是 JDK 自带的 Flow 发布者。缓冲区到底多大?订阅者慢了 submit 会怎样?offer 与 submit 的差别?这篇逐项触发,还撞到了一个会让监控调用卡住的细节。
默认容量 Flow.defaultBufferSize()=256;getMaxBufferCapacity=256
maxBufferCapacity=1 getMaxBufferCapacity()=1 订阅者始终没有 request,submit 成功 1 个后阻塞(线程状态 WAITING)
maxBufferCapacity=3 getMaxBufferCapacity()=4 订阅者始终没有 request,submit 成功 4 个后阻塞(线程状态 WAITING)
maxBufferCapacity=4 getMaxBufferCapacity()=4 订阅者始终没有 request,submit 成功 4 个后阻塞(线程状态 WAITING)
maxBufferCapacity=5 getMaxBufferCapacity()=8 订阅者始终没有 request,submit 成功 8 个后阻塞(线程状态 WAITING)
maxBufferCapacity=8 getMaxBufferCapacity()=8 订阅者始终没有 request,submit 成功 8 个后阻塞(线程状态 WAITING)
另一个线程在 submit 阻塞期间调用 estimateMaximumLag():500 ms 后线程状态 = WAITING(仍被阻塞)
同时调用 getNumberOfSubscribers():仍被阻塞
maxBufferCapacity=10 getMaxBufferCapacity()=16 订阅者始终没有 request,submit 成功 16 个后阻塞(线程状态 WAITING)
maxBufferCapacity=100 getMaxBufferCapacity()=128 订阅者始终没有 request,submit 成功 128 个后阻塞(线程状态 WAITING) onDrop 回调:元素 5,返回 false 表示不重试
onDrop 回调:元素 6,返回 false 表示不重试
onDrop 回调:元素 7,返回 false 表示不重试
onDrop 回调:元素 8,返回 false 表示不重试
offer(1..8) 的返回值(正数=估计滞后,负数=丢弃数的相反数):1 2 3 4 -1 -1 -1 -1
订阅者数 1;hasSubscribers=true;estimateMaximumLag=4;estimateMinimumDemand=-4
onNext 1
onNext 2
onNext 3
onNext 4
request(10) 后 estimateMaximumLag=0
onNext 9
带超时的 offer(9):1
onComplete 默认执行器的线程名(两个订阅者,各 request 无界):
[ForkJoinPool.commonPool-worker-1] S1 onSubscribe
[ForkJoinPool.commonPool-worker-2] S2 onSubscribe
[ForkJoinPool.commonPool-worker-1] S1 onNext 1
[ForkJoinPool.commonPool-worker-2] S2 onNext 1
[ForkJoinPool.commonPool-worker-1] S1 onNext 2
[ForkJoinPool.commonPool-worker-2] S2 onNext 2
[ForkJoinPool.commonPool-worker-1] S1 onComplete
[ForkJoinPool.commonPool-worker-2] S2 onComplete
同一个订阅者收到元素的顺序(submit 1..6 后,订阅者是否按顺序):
[1, 2, 3, 4, 5, 6]
订阅者的 onNext 抛异常:
[ForkJoinPool.commonPool-worker-2] onNext 1
[ForkJoinPool.commonPool-worker-2] onNext 2
[ForkJoinPool.commonPool-worker-2] onError java.lang.IllegalStateException: 订阅者处理 2 时失败
之后订阅者数 = 0(出错的订阅者已被移除)
request(0) 与 request(-1):
[ForkJoinPool.commonPool-worker-2] request(0) → onError java.lang.IllegalArgumentException: non-positive subscription request
[ForkJoinPool.commonPool-worker-2] request(-1) → onError java.lang.IllegalArgumentException: non-positive subscription request
closeExceptionally 与 close 之后 submit:
[ForkJoinPool.commonPool-worker-2] onError java.lang.RuntimeException: 发布者主动失败
isClosed=true;getClosedException=java.lang.RuntimeException: 发布者主动失败
关闭后 submit:java.lang.IllegalStateException: Closed