concurrent-rpc

An abstraction for inter-thread RPC based on MVars https://github.com/lpeterse/haskell-concurrent-rpc

Latest on Hackage:0.1.0.0

This package is not currently in any snapshots. If you're interested in using it, we recommend adding it to Stackage Nightly. Doing so will make builds more reliable, and allow stackage.org to host generated Haddocks.

MIT licensed by Lars Petersen

concurrent-rpc

Available on Hackage License MIT Build Status

Summary

This library is small wrapper around Control.Concurrent.MVar.MVars that can be used to implement request-response communication between different threads.

Example

module MissileLauncher where

import Control.Exception
import Control.Monad
import Control.Concurrent
import Control.Concurrent.Async
import Control.Concurrent.RPC
import Data.Word
import System.Random

type Missile    = Word
type LaunchSite = String

main :: IO ()
main = do
  (launchMissile, withMissile) <- newRPC
  runMissileProduction launchMissile
    `race_` runLaunchSite withMissile "Redmond"
    `race_` runLaunchSite withMissile "Cambridge"

runLaunchSite :: WithRPC Missile LaunchSite -> LaunchSite -> IO ()
runLaunchSite withMissile site = forever $ do
  sleepRandom
  catch
    ( withMissile $ \missile-> do
        r <- random100
        if r < 10
          then error $ "bad weather in " ++ site
          else do
            printThread $ site ++ ": LAUNCH THE MISSILE!"
            return site
    )
    ( \e-> do
      let _ = e :: SomeException
      printThread $ site ++ ": Couldn't launch. Waiting for next missile."
    )

runMissileProduction :: RPC Missile LaunchSite -> IO ()
runMissileProduction launchMissile =
  produce  `race_` produce `race_` produce `race_` produce
  where
    produce = forever $ do
      sleepRandom
      missile <- randomIO :: IO Missile
      catch
        ( do
            printThread $ "Production: Ready to launch missile " ++ show missile
            site <- launchMissile missile
            printThread $ "Production: Missile " ++ show missile ++ " launched in " ++ site
        )
        ( \e->
            printThread $ "Production: Missile " ++ show missile ++
                          " failed to launch due to " ++ show (e :: SomeException)
        )

printThread :: Show a => a -> IO ()
printThread x = do
  threadId <- myThreadId
  random100 >>= \x-> threadDelay (x * 100)
  putStrLn $ show threadId ++ ": " ++ show x

random100 :: IO Int
random100 = (`mod` 100) <$> randomIO

sleepRandom :: IO ()
sleepRandom = random100 >>= \x-> threadDelay (x * 100000)

Dependencies

  • base >= 4.7 && < 5

Depends on:
comments powered byDisqus