简体   繁体   English

是否可以将反应堆上下文传递给从接收器创建的通量?

[英]Is it possible to pass the Reactor Context to a Flux created from a Sinks?

We're currrently using the ReactiveSecurityContextHolder which gets our correct Auth details and is used along the Flux stream.我们目前正在使用 ReactiveSecurityContextHolder,它可以获取我们正确的 Auth 详细信息,并与 Flux stream 一起使用。

Now we want to de-couple stuff.现在我们想要解耦东西。 The first iteration is that we use a Sinks as an intermediate 'event-hub'.第一次迭代是我们使用接收器作为中间“事件中心”。 So from an endpoint we produce some item to the Sinks.Many.因此,我们从一个端点向 Sinks.Many 生成一些项目。

A listener is consuming events from this Sinks and doing the heavy work.一个监听器正在消费来自这个接收器的事件并做繁重的工作。 Now in this consumer I'd like to use the context which is available on the producing site.现在在这个消费者中,我想使用生产站点上可用的上下文。 I know one can do deferContextual to pass on the current context to another Flux.我知道可以做deferContextual将当前上下文传递给另一个 Flux。 But is it possible to pass the context to the resulting Flux from the Sinks?但是是否有可能将上下文从接收器传递给生成的通量?

Thanks in advance.提前致谢。

Alex亚历克斯

There is currently no API that exposes that on arbitrary Sinks .目前没有 API 在任意Sinks上公开它。 The challenge with Sinks is that a lot of them are multicasting to multiple Subscriber s, and the Context is defined on each Subscriber . Sinks的挑战在于它们中的很多都在多播到多个Subscriber ,并且每个Subscriber上都定义了Context

There is a hack though: Sinks.Many<T> is Scannable , and most concrete implementations should expose their current collection of subscribers through the Stream<Scannable> inners() method.但是有一个技巧: Sinks.Many<T>Scannable ,大多数具体的实现应该通过Stream<Scannable> inners()方法公开他们当前的订阅者集合。 In the case of a unicast sink, scan(Attr.ACTUAL) would also work.在单播接收器的情况下, scan(Attr.ACTUAL)也可以工作。

Two big caveats:两大警告:

  • these APIs only expose Scannable s, which doesn't allow access to Context directly这些 API 只公开Scannable ,不允许直接访问Context
  • if the implementation's inner subscriber isn't Scannable , it is replaced in the stream by the Scannable#NOT_SCANNABLE constant如果实现的内部订阅者不是Scannable ,则在 stream 中将其替换为Scannable#NOT_SCANNABLE常量

Most if not all of reactor-core CoreSubscribers are Scannable , but if you connect a custom subscriber which isn't Scannable, even though it has a Context , you won't be able to see it.大多数(如果不是全部) reactor-core CoreSubscribers都是Scannable ,但是如果您连接的自定义订阅者不是 Scannable ,即使它具有Context ,您也将看不到它。

Multicast Sinks in reactor-core tend to wrap downstream subscribers in their own inner Scannable inner tracker, which would make this approach work. reactor-core 中的多播接收器倾向于将下游订阅者包裹在他们自己的内部可扫描内部跟踪器中,这将使这种方法有效。

Unicast Sinks are a bit different as they directly attach to the downstream Subscriber .单播接收器有点不同,因为它们直接连接到下游Subscriber So if it is a CoreSubscriber but somehow not a Scannable , you won't be able to see it as a CoreSubscriber and access its Context .因此,如果它是CoreSubscriber但不知何故不是Scannable ,您将无法将其视为CoreSubscriber并访问其Context

To sum up the approach:总结一下方法:

  1. call sink.inners() to get a Stream<Scannable>调用sink.inners()获取Stream<Scannable>
  2. ensure values are instances of CoreSubscriber (that's the part where things can go wrong)确保值是CoreSubscriber的实例(这是 go 错误的部分)
  3. cast values to CoreSubscriber and call currentContext()将值转换为CoreSubscriber并调用currentContext()
  4. somehow reconcile the various Context s you got to extract the relevant key-value pair(s)以某种方式协调您提取相关键值对的各种Context

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM