我一直在使用Spring Integration(SI)DSL。我有一个Rest服务,定义了以下Async Gateway:
@MessagingGateway
public interface Provision {
@Async
@Gateway(requestChannel = "provision.input")
ListenableFuture<List<ResultDto>> provision(List<ItemsDto> stuff);
}
从逐行演练中我有以下示例IntegrationFlow。
@Bean
public IntegrationFlow provision() {
return f -> f
.split(ArrayList.class, List::toArray)
.channel(c -> c.executor(Executors.newCachedThreadPool()))
.<ItemsDto, String>route(ItemsDto::getType, m -> m
.subFlowMapping("IPTV", sf -> sf
.<ItemsDto, String>route(ItemsDto::getAction, m2 -> m2
.subFlowMapping("OPEN", sf2 -> sf2
.handle((p, h) -> iptvService.open((ItemsDto) p))))
)
)
.aggregate();
}
我可以看到几层路由。我需要稍微分解一下。我尝试了几件不起作用的东西(这里我没有得到回应......线程不等待):
@Bean(name = "routerInput")
private MessageChannel routerInput() {
return MessageChannels.direct().get();
}
@Bean
public IntegrationFlow provision() {
return f -> f
.split(ArrayList.class, List::toArray)
.channel(c -> c.executor(Executors.newCachedThreadPool()))
.<ItemsDto, String>route(ItemsDto::getType, m ->
m.subFlowMapping("IPTV", sf -> sf.channel("routerInput"))
)
.aggregate();
}
@Bean
public IntegrationFlow action() {
return IntegrationFlows.from("routerInput")
.<ItemsDto, String>route(ItemsDto::getAction, m -> m
.subFlowMapping("OPEN", sf -> sf
.handle(p -> iptvService.open((ItemsDto) p.getPayload())))).get();
}
我显然在概念上遗漏了一些东西:)有人可能会帮助提供“如何和为什么”的观点?
我有一个需要拆分的项目列表,按“类型”路由,然后通过“操作”路由,最后聚合(包含处理程序的响应)。每个处理的项目都需要并行处理。
提前致谢
更新: 从Artem的建议我删除了所有异步的东西。我把它修剪得几乎没有......
@Bean(name = "routerInput")
private MessageChannel routerInput() {
return MessageChannels.direct().get();
}
@Bean
public IntegrationFlow provision() {
return f -> f
.split()
.<ItemDto, String>route(ItemDto::getType, m ->
m.subFlowMapping("IPTV", sf -> sf.channel("routerInput")))
.aggregate();
}
@Bean
public IntegrationFlow action() {
return IntegrationFlows.from("routerInput")
.<ItemDto, String>route(ItemDto::getAction, m -> m
.subFlowMapping("OPEN", sf -> sf
.handle((p, h) -> iptvService.open((ItemDto) p)))).get();
}
我通过更改
来做出回应.handle(p - &gt;
到这个
.handle((p,h) - &gt;
所以它至少会响应,但它不会聚合分裂的3个测试项目。输出包含1个项目。我需要使用流收集吗?发布政策?这不应该没问题吗?
答案 0 :(得分:0)
如果你想将它分开,使用def create_hist(a,dr):
class SaveArraysCallable(object):
def __call__(self,bins,hist):
self.bins = bins.copy()
self.hist = hist.copy()
f = SaveArrayCallable()
fortran_module.create_hist(a,dr,f)
return f.bins, f.hist
而不是channelMapping
可能更简单......
subflowMapping
为其他选项创建流并聚合每个结果:
@Bean
public IntegrationFlow typeRoute() {
return IntegrationFlows.from(foo())
.split()
.<ItemsDto, String>route(ItemsDto::getType, m -> m
.channelMapping("foo", "channel1")
.channelMapping("bar", "channel2"))
.get();
}
@Bean
public IntegrationFlow fooActionRoute() {
return IntegrationFlows.from(channel1())
.<ItemsDto, String>route(ItemsDto::getAction, m -> m
.channelMapping("foo", "channel3")
.channelMapping("bar", "channel4"))
.get();
}
@Bean
public IntegrationFlow barActionRoute() {
return IntegrationFlows.from(channel1())
.<ItemsDto, String>route(ItemsDto::getAction, m -> m
.channelMapping("foo", "channel5")
.channelMapping("bar", "channel6"))
.get();
}
@Bean
public IntegrationFlow fooFooHandle() {
return IntegrationFlows.from(channel3())
// handle
.channel(aggChannel())
.get();
}
使用 // fooBarHandle(), barFooHandle(), barBarHandle()
@Bean IntegrationFlow agg() {
return IntegrationFlows.from(aggChannel())
.aggregate()
.get();
}
s ...
ExecutorChannel
答案 1 :(得分:0)
我没有看到您的配置中存在任何重大问题,而且确实应该有效。
希望我不喜欢有:
如果您使用async
网关(ListenableFuture<List<ResultDto>>
),则不需要@Async
注释,因为它已经是网关合同。
如果List::toArray
已经是payload
,则您不需要转换List
。只使用没有参数的.split()
就足够了。
这就是设计风格。
我还不确定那里的问题是什么,但你是否想让你的整个流程同步并在这里与我们分享DEBUG
流动并指出你看到问题的地方。
答案 2 :(得分:0)
将聚合移动到“action”Bean并且它有效。 感谢您的耐心:)