MyNixOS website logo
Description

An abstraction for inter-thread RPC based on MVars.

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

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
Metadata

Version

0.1.0.0

License

Platforms (77)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-freebsd
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64-windows
  • aarch64_be-none
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-darwin
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-darwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-windows