haskell - Elegant egress from `Async` actions -
is there simple way of cancelling async a value, such won't interrupted in middle of critical action? suppose use semaphore inside loop condition.
async $ whilem readsemaphore runloopbody but i'd know whether async or other related library supports out-of-the-box.
my code, requested.
-- | -- todo | - rename (?) -- - time-out awaitresult :: string -> io -> io awaitresult s act = putstr s sem <- newmvar true <- async $ ellipsis sem r <- act swapmvar sem false return r ellipsis :: mvar bool -> io () ellipsis sem = void $ whilem (readmvar sem) $ form [". ", ".. ", "...", " "] $ \dots -> putstr dots cursorbackward 3 threaddelay (floor $ 0.4 * second) -- todo | - if windows console wasn't shit, i'd use checkmark putstr " (" >> withpretty fggreen "done" >> putstrln ")"
the phrasing of question made me think of more antagonistic relationship, in case using control.concurrent.mask limit when task can interrupted should reasonable.
based on updated code seems threads have tight coupling , first alternative can think of spawning action instead of indicator , using poll, think less noisy mvar route:
import control.monad (form_) import control.exception (throw) import control.concurrent (threaddelay) import control.concurrent.async (async,async,poll) second :: (num a) => second = 1000000 awaitresult :: string -> io -> io awaitresult s act = putstrln s <- async $ act ellipsis ellipsis :: async -> io ellipsis = result <- poll case result of nothing -> form_ [". ",".. ","..."," "] $ \dots -> putstr dots putstr "\r" threaddelay $ floor $ 0.4 * second ellipsis (left e) -> throw e (right x) -> return x main = awaitresult "testing" (threaddelay (5 * second) >> return 5)
Comments
Post a Comment