簡體   English   中英

通過agreggateId通過流進行分組(Haskell /並發流)

[英]GroupBy of stream by agreggateId (Haskell / concurrency streaming)

上下文 :我正在CQRS中實現一個App,並且正在嘗試優化命令的處理(基本上是通過匯總ID的1個流)...

問題 :我想擁有第一個流來接收所有命令,並通過它們的集合ID在不同線程上分派這些命令:

1)集合中的命令以串行方式處理
2)聚合獨立(並行)處理其命令。

解決方案 :我試圖基本上通過聚合ID在流上執行groupBy ...為了幫助一點,我將示例簡化如下:

module Sandbox where

import Streamly
import qualified Streamly.Prelude as S
import Control.Concurrent
import Control.Monad.IO.Class (MonadIO(..))

main :: IO ()
main = do
         runStream $ parallely $ S.fromList getAggregateIds |& S.mapM (\x -> do
            threadId <- myThreadId
            liftIO $ putStrLn $ (show threadId) ++ "  value " ++ (show x))


getAggregateIds :: [Integer]
getAggregateIds = [1..3] <> [1..3]

因此此腳本顯示以下結果:

ThreadId 17  value 1
ThreadId 15  value 2
ThreadId 19  value 3
ThreadId 13  value 1
ThreadId 16  value 3
ThreadId 18  value 2

我期望的是這樣的事情(沒有特殊的命令x總是在同一線程x1上進行處理):

ThreadId X1  value X
ThreadId Y1  value Y
ThreadId Z1  value Z
ThreadId X1  value X
ThreadId Y1  value Y
ThreadId Z1  value Z

謝謝 !!

在上面的代碼中, parallely決定為getAggregateIds列表中的每個元素創建一個Haskell線程,該線程為[1,2,3,1,2,3] parallely並不關心列表中是否有重復的元素:它只是為每個元素啟動一個線程。

原則上, parallely只能分配少量的Haskell線程,以后再使用它們(可能是相同的ID或另一個ID),但這樣做不會提高性能。 實際上,這里的關鍵部分是分配了Haskell線程,而不是OS線程,

Haskell線程非常輕巧,它們使用的內存很少,因此創建和處理它們的成本非常低廉。 嘗試重用它們可能會導致性能下降。

此外,Haskell運行時可以在單個OS線程中執行許多Haskell線程。 通常,運行時會保留一小部分OS線程,並且Haskell線程會映射到這些線程。 由於OS線程不如輕量級OS線程確實在Haskell線程之間重用。

最后,請注意, ThreadId是Haskell線程的名稱,而不是OS的名稱,因此正常情況下不會重復使用這些ID。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM