Skip to content

Instantly share code, notes, and snippets.

@yihuang
Created December 24, 2012 05:53
Show Gist options
  • Select an option

  • Save yihuang/4367902 to your computer and use it in GitHub Desktop.

Select an option

Save yihuang/4367902 to your computer and use it in GitHub Desktop.
要实现一个API,API内部有两个http接口A,B并发调用,如果都在200ms内返回,则合并结果输出,如果B比A慢,且B耗时超过200ms,则丢弃B调用只返回A结果. 要一直等到A返回(可以最多等5秒),而B如果比A还慢,则最多等200ms-A的耗时
import Control.Concurrent (forkIO, threadDelay)
import Control.Concurrent.MVar (MVar, newEmptyMVar, putMVar, takeMVar)
import System.Random (randomRIO)
import System.Timeout (timeout)
import Data.Time.Clock.POSIX (getPOSIXTime)
-- 开一个线程执行 io ,返回等待结果的Action
spawn :: IO a -> IO (IO a)
spawn io = do
mresult <- newEmptyMVar
forkIO (io >>= putMVar mresult)
return (takeMVar mresult)
-- 模拟 a 操作
slow_a :: IO String
slow_a = do
threadDelay 100000
return "a"
-- 模拟 b 操作
slow_b :: IO String
slow_b = do
randomRIO (0, 300000) >>= threadDelay
return "b"
main :: IO ()
main = do
-- 启动线程执行 a 和 b,分别设置5秒和200毫秒超时
geta <- spawn (timeout 5000000 slow_a)
getb <- spawn (timeout 200000 slow_b)
-- 等待 a 的结果
ra <- geta
-- 等待 b 的结果
rb <- getb
-- 结果为 Maybe String,Nothing代表执行超时,Just str表示成功的结果
print (ra, rb)
--λ /tmp/ ./hugozhu
--(Just "a",Nothing)
--λ /tmp/ ./hugozhu
--(Just "a",Just "b")
--λ /tmp/ ./hugozhu
--(Just "a",Just "b")
--λ /tmp/ ./hugozhu
--(Just "a",Nothing)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment