因此,最近几天我一直在阅读有关基于流的编程(FBP)的知识,也一直在阅读J. Paul Morrison的书。但是我觉得我仍然无法真正解决这个问题。一般概念是,您将编程视为某种装配线,其中的组件将某些数据包作为输入,并产生一些数据包作为输出。您可以连接这些组件,并且数据包通过网络传输。虽然我完全了解了它如何用于ETL类型的应用程序或批处理,但我不知道如何使用它来处理诸如同步请求/响应模式或数据库事务之类的事情。
例如,假设我有一个实施为FPB的Web服务器。该网络服务器有一个GET / user / {id},它应该返回一个JSON以及有关用户的一些信息。它还具有POST / user / {id},您可以在其中通过将一些JSON发送回服务器来更新用户。因此,这就是我想像的样子:
我试图拥有许多可重用的组件,而不是将处理请求的整个逻辑放在单个组件中。因此,有一个HTTP服务器组件将请求发送到分派器组件,然后分派器将请求分派到后续流中。在每个流中,请求都由通用的“请求解析器”组件解析,该组件将请求的各个部分输出到流的其余部分。
上部非常简单,我从数据库读取具有给定ID的用户实体,将对象序列化为JSON,然后将其发送回。但是,在这一点上,我们实际上不再有对HTTP请求的引用,所以我怎么知道将请求发送到哪里?
在下部,我们有一些额外的复杂性,因为我想以事务方式写入数据库。因此,首先启动一个事务(并行将请求主体解析为某个对象),然后从数据库中检索用户对象,并将其与请求中的输入合并。最后,将其写回到数据库,并提交事务。最后,某些“ OK”状态将响应呼叫者。在这里,我还有一个问题,就是在提交事务时,我真的不知道要提交哪个事务。当然,在发送响应时,我不知道将响应发送到哪个请求。
因此,这两个问题似乎有一个共同点-一种跨越许多组件的“上下文”。在一个示例中,它是HTTP请求/响应上下文,在另一个示例中是事务性上下文。在常规编程中,这些上下文通常在线程级别处理。由于请求在单个线程中运行,因此事务和请求上下文绑定到本地线程,因此只要所有内容都在同一线程中运行,就可以在任何地方访问它们。
在基于流的编程中,每个组件都独立运行,理想情况下在单独的线程上运行。这实际上是关键,因为它允许并行化和有效使用多个处理器。但是,当不再存在该局部局部上下文时,如何在基于流的编程中处理这些问题?正确的错误处理(在我的示例中省略了)会变得更加复杂。
我认为,当您进行反应式编程时,其中大多数处理也是异步和多线程的,那么您将遇到相同的问题,因此我想知道是否存在处理此问题的模式。您是否具有使用响应式编程或基于流的编程的现实生活经验,并且对如何解决此问题有一些提示?
答案 0 :(得分:1)
我在Twitter上写了一个快速的答案-认为我也将其发布在这里...抱歉,我要重复发布!
我喜欢用于此/这些问题的子流,其中子流中的第一个信息包提供了您正在谈论的“上下文”。这可能会有所帮助:https://github.com/jpaulm/javafbp-websockets ... HTH!
PS这种循环样式的网络拓扑结构也是Facebook新的“ Flux”技术的基础-请参见Jing Jing的演示,她在其中将这种方法与MVC进行了比较:https://www.youtube.com/watch?v=nYkdrAPrdcw
答案 1 :(得分:1)
希望这可能会在正确的方向上推动您。我有一个类似的问题,我需要在异步微服务架构中执行同步操作。
我如何解决它是使用观察者模式。我有3个组成部分; http服务器,回调服务器和计时器轮。与您类似的http服务器接收传入的请求,回调服务器在异步处理后接收总结果,而计时器轮将原始http上下文排队并协调对http请求的响应。
当接收到传入的请求时,http服务器会创建一个相关ID,将其添加到请求元数据中,将回调服务器url附加到请求元数据中,最后将请求和原始http上下文一起添加到计时器轮中。然后,http服务器会将请求传递给调度程序,就像您的情况一样,并将消息发送到相关组件以进行异步处理。
根据当前处理组件的执行结果,它将从元数据中检索回调URL并将响应发送到回调服务器。在您的情况下,将执行json序列化或数据库写操作。然后,回调服务器将提取附加的相关性ID,并获取相应的http上下文并编写响应。
注意,计时器轮中的每个计时器对象都有一个可配置的超时,这样,如果异步处理延迟,它将超时并向相应http上下文的http客户端返回可配置消息。