|
42 | 42 | import java.util.List; |
43 | 43 | import java.util.Optional; |
44 | 44 | import java.util.Set; |
| 45 | +import java.util.concurrent.locks.Lock; |
45 | 46 | import java.util.function.Consumer; |
46 | 47 | import java.util.stream.Collectors; |
47 | 48 |
|
@@ -322,26 +323,64 @@ public void offer(List<FlowContext<I>> contexts, Consumer<PreSendCallbackInfo<I> |
322 | 323 | // qualifiedWhens表示的与from节点连接的所有事件,条件节点符合条件的事件在这里筛选,在事件上处理需要下发的context |
323 | 324 | java.util.Map<FitStream.Subscription<I, ?>, List<FlowContext<I>>> matchedContexts = new LinkedHashMap<>(); |
324 | 325 | Set<FlowContext<I>> matchedContextSet = new HashSet<>(); |
325 | | - qualifiedWhens.forEach( |
326 | | - w -> { |
327 | | - List<FlowContext<I>> afterContexts = contexts |
328 | | - .stream() |
329 | | - .filter(c -> w.getWhether().is(c)) |
330 | | - .peek(c -> c.setNextPositionId(w.getId())) |
331 | | - .collect(Collectors.toList()); |
332 | | - matchedContexts.put(w, afterContexts); |
333 | | - matchedContextSet.addAll(afterContexts); |
| 326 | + List<FlowContext<I>> forkedContexts = new ArrayList<>(); |
| 327 | + for (FlowContext<I> contextItem : contexts) { |
| 328 | + List<FitStream.Subscription<I, ?>> matchedSubscriptions = qualifiedWhens.stream() |
| 329 | + .filter(w -> w.getWhether().is(contextItem)) |
| 330 | + .collect(Collectors.toList()); |
| 331 | + if (CollectionUtils.isEmpty(matchedSubscriptions)) { |
| 332 | + continue; |
| 333 | + } |
| 334 | + matchedContextSet.add(contextItem); |
| 335 | + for (int index = 0; index < matchedSubscriptions.size(); index++) { |
| 336 | + FitStream.Subscription<I, ?> matchedSubscription = matchedSubscriptions.get(index); |
| 337 | + FlowContext<I> branchContext = index == 0 ? contextItem : contextItem.fork(); |
| 338 | + branchContext.setNextPositionId(matchedSubscription.getId()); |
| 339 | + matchedContexts.computeIfAbsent(matchedSubscription, key -> new ArrayList<>()).add(branchContext); |
| 340 | + if (index > 0) { |
| 341 | + forkedContexts.add(branchContext); |
334 | 342 | } |
335 | | - ); |
| 343 | + } |
| 344 | + } |
| 345 | + qualifiedWhens.forEach(w -> matchedContexts.computeIfAbsent(w, key -> new ArrayList<>())); |
336 | 346 | List<FlowContext<I>> unMatchedContexts = contexts |
337 | 347 | .stream() |
338 | 348 | .filter(c -> !matchedContextSet.contains(c)) |
339 | 349 | .collect(Collectors.toList()); |
340 | 350 | PreSendCallbackInfo<I> callbackInfo = new PreSendCallbackInfo<>(matchedContexts, unMatchedContexts); |
341 | 351 | preSendCallback.accept(callbackInfo); |
| 352 | + persistForkedContexts(forkedContexts, matchedContexts); |
342 | 353 | matchedContexts.forEach(FitStream.Subscription::cache); |
343 | 354 | } |
344 | 355 |
|
| 356 | + private void persistForkedContexts(List<FlowContext<I>> forkedContexts, |
| 357 | + java.util.Map<FitStream.Subscription<I, ?>, List<FlowContext<I>>> matchedContexts) { |
| 358 | + if (CollectionUtils.isEmpty(forkedContexts)) { |
| 359 | + return; |
| 360 | + } |
| 361 | + Set<String> forkedIds = forkedContexts.stream().map(FlowContext::getId).collect(Collectors.toSet()); |
| 362 | + List<FlowContext<I>> effectiveForkedContexts = matchedContexts.values() |
| 363 | + .stream() |
| 364 | + .flatMap(List::stream) |
| 365 | + .filter(context -> forkedIds.contains(context.getId())) |
| 366 | + .collect(Collectors.toList()); |
| 367 | + if (CollectionUtils.isEmpty(effectiveForkedContexts)) { |
| 368 | + return; |
| 369 | + } |
| 370 | + Set<String> traces = effectiveForkedContexts.stream() |
| 371 | + .flatMap(context -> context.getTraceId().stream()) |
| 372 | + .collect(Collectors.toSet()); |
| 373 | + Lock lock = this.locks.getDistributedLock(this.locks.streamNodeLockKey(this.streamId, this.id, |
| 374 | + "ForkContextPool")); |
| 375 | + lock.lock(); |
| 376 | + try { |
| 377 | + this.repo.updateContextPool(effectiveForkedContexts, traces); |
| 378 | + this.repo.save(effectiveForkedContexts); |
| 379 | + } finally { |
| 380 | + lock.unlock(); |
| 381 | + } |
| 382 | + } |
| 383 | + |
345 | 384 | /** |
346 | 385 | * 是否有publisher目标 |
347 | 386 | * 用于stream闭环时将没有subscribed的publisher关闭到close subscriber |
|
0 commit comments