在下面的代碼中,我發送一條帶有關閉的記錄以填充到函式中,然后在函式回傳時IO (TMVar o)讀取我認為應該相同的內容。TMVar問題是當我讀回它時它是空的并且應用程式只是阻塞。
為什么會這樣?
Hook 初始化如下:
hook = Hook {
-- other props
hookResult = newEmptyTMVarIO,
}
稍后在 ap 中:
executeHook :: (Text -> IO ()) -> Node i o -> IO ()
executeHook db =
\case
Fixture {} -> pure ()
Hook
{ hookParent,
hookStatus,
hook,
hookResult, -- IO (TMVar o)
hookChildren
} -> do
input <- db "CALL PARENT LOCK EXECUTE HOOK" >> lockExecuteHook db hookParent
result <- hook input
hr <- hookResult
mtb <- atomically $ isEmptyTMVar hr
db $ "HOOK RESULT PUT EMPTY BEFORE: " <> txt mtb
atomically $ putTMVar hr result -- writes hook result to the TMVar
mt <- atomically $ isEmptyTMVar hr
db $ "HOOK RESULT PUT EMPTY AFTER: " <> txt mt
lockExecuteHook :: (Text -> IO ()) -> Either o (Node i o) -> IO o
lockExecuteHook db parent =
eitherf
parent
(\o -> db "NO PARENT HOOK RETURNING VALUE" >> pure o)
( \case
Fixture {} -> pure ()
hk@Hook
{ hookParent,
hookStatus,
hookResult, -- IO (TMVar o)
hook,
hookChildren,
hookRelease
} -> do
bs <- hookStatus
wantLaunch <- atomically $ tryLock db bs
db $ "HOOK LOCK >>> " <> txt wantLaunch
when
wantLaunch
$ executeHook db hk -- this writes hook result to the TMVar
hr <- hookResult
mt <- atomically $ isEmptyTMVar hr
db $ "READING HOOK !!!!!!!!!!!!!!!!!!!!!!!!!! EMPTY: " <> txt mt
r <- atomically $ readTMVar hr
db "RETURNING FROM LOCK EXECUTE HOOK " >> pure r
)
除錯 (db) 輸出
CALL PARENT LOCK EXECUTE HOOK
HOOK LOCK >>> True
HOOK RESULT PUT EMPTY BEFORE: True
HOOK RESULT PUT EMPTY AFTER: False
READING HOOK !!!!!!!!!!!!!!!!!!!!!!!!!! EMPTY: True
uj5u.com熱心網友回復:
正如@FyodorSoikin、@DanielWagner 和@chi 在上述評論中指出的那樣,它沒有按預期作業的原因是hookResult沒有正確初始化。
將記錄欄位設定為 anIO (TMVar a)將導致TMVar a每次hookResult讀取一個新欄位,如果該欄位設定為STM (TMVar a)using ,則會出現類似的問題newTMVar。要完成這項作業hookResult,需要TMVar a在 IO 或 STM 背景關系中設定為 a。
eg :: IO (Hook a)
eg = do
v <- newEmptyTMVarIO
pure $ Hook {
-- other props
hookResult = v,
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/446003.html
上一篇:使用串列單子進行迭代
下一篇:Haskell無法識別型別
