无论如何,我是否可以表达“背压”来抑制来自导管源的值的产生?
假设我有类似的东西:
source :: ConduitT () Tweet Twitter ()
source = do
ts <- lift $ getNewTweets [("screen_name", "Bits90824664")]
yieldMany ts
_ <- liftIO $ threadDelay 3000000
source
getNewTweets
通过受限制的Web API请求其数据的位置。通过在生产者中添加threadDelay
,我已经能够成功地“调整”正在执行的请求数量。但是,我计划在管道中添加其他源,并开始以循环方式使用每个生产者的数据。因此,在生产者中放置threadDelay
不再有意义。我想把延迟放在上游。
我已经尝试了诸如增加消费者延迟或将iterMC
与threadDelay
添加到管道中间的事情,但是什么也没做。我猜测正在发生多线程,因此延迟无法正常工作?
或者,一个新想法!在大多数情况下,我的生产者根本不产生任何值,而是执行yieldMany []
...,因此,除非我将[]
视为正常的流值并且将生产者重写为ConduitT () [Value] IO ()
。 关于这是否可以与消费者的大块(我在想使用非块状变压器添加延迟,以便每次请求都会触发该延迟,并在管道末端使用使用者的CE变体之一。如果有机会,我会做实验。CE
)变体一起使用的任何想法,还是可以将空块以某种方式短路?
如果在Haskell中还有其他技术可以对这种行为进行编码,那么我将感谢任何建议,因为我对Haskell相对较新,尤其是导管库。我什至不知道如何/是否可以循环浏览多个来源。
答案 0 :(得分:0)
更改流以返回数据块(包括空块)可以将延迟添加到上游。我有一个与ZipSource一起使用的粗略原型,但很可能需要更改我的方法,以使源彼此独立地提取数据。
followUser :: Text -> ConduitT () [Tweet] Twitter ()
followUser sn = do
ts <- lift $ getNewTweets [("screen_name", sn)]
yield ts
source
handleTweet :: Tweet -> IO ()
handleTweet = print
main :: IO ()
main = do
let sources = sequenceSources [ followUser "user1"
, followUser "user2"
]
_ <- runTwitter $ runConduit
$ sources
.| iterMC (\a -> threadDelay 3000000)
.| mapM_CE (liftIO . Prelude.mapM_ handleTweet)
return ()