shrub/pkg/hs-urbit/lib/Vere/Pier.hs

94 lines
2.7 KiB
Haskell
Raw Normal View History

module Vere.Pier where
import ClassyPrelude
import Data.Noun
import Data.Noun.Pill
import Vere
import Vere.Pier.Types
import qualified Vere.Log as Log
import qualified Vere.Worker as Worker
ioDrivers = [] :: [IODriver]
-- This is called to make a freshly booted pier. It assigns an identity to an
-- event log and takes a chill pill.
newPier :: Pill -> FilePath -> LogIdentity -> IO Pier
newPier pill top id = do
let logPath = top <> "/log"
computeQueue <- newTQueueIO
persistQueue <- newTQueueIO
releaseQueue <- newTQueueIO
-- What we really want to do is write the log identity and then do normal
-- startup, but writeLogIdentity requires a full log state including
-- input/output queues.
logState <- Log.init logPath persistQueue (writeTQueue releaseQueue)
-- In first boot, we need to write this!
Log.writeLogIdentity logState id
let logLatestEventNumber = 0
let getEvents = Log.readEvents logState
workerState <- Worker.startWorkerProcess
Worker.bootWorker workerState id pill
performCommonPierStartup workerState computeQueue persistQueue releaseQueue logState
-- This reads in a pier
runPierFromDisk :: FilePath -> IO Pier
runPierFromDisk top = do
let logPath = top <> "/log"
computeQueue <- newTQueueIO
persistQueue <- newTQueueIO
releaseQueue <- newTQueueIO
-- What we really want to do is write the log identity and then do normal
-- startup, but writeLogIdentity requires a full log state including
-- input/output queues.
logState <- Log.init logPath persistQueue (writeTQueue releaseQueue)
-- In first boot, we need to write this!
id <- Log.readLogIdentity logState
logLatestEventNumber <- Log.latestEventNumber logState
let getEvents = Log.readEvents logState
workerState <- Worker.startWorkerProcess
Worker.resumeWorker workerState id logLatestEventNumber getEvents
performCommonPierStartup workerState computeQueue persistQueue releaseQueue logState
performCommonPierStartup :: Worker.Worker
-> TQueue Noun
-> TQueue (Writ [Eff])
-> TQueue (Writ [Eff])
-> LogState
-> IO Pier
performCommonPierStartup workerState computeQueue persistQueue releaseQueue logState = do
for ioDrivers $ \x -> do
bootMessage <- bornEvent x
atomically $ writeTQueue computeQueue bootMessage
driverThreads <- for ioDrivers $ \x -> do
startDriver x (writeTQueue computeQueue)
-- TODO: Don't do a bunch of extra work; we send all events to all drivers
portingThread <- async $ do
forever $ do
r <- atomically (readTQueue releaseQueue)
for_ driverThreads $ \(_, k) ->
for_ (payload r) $ \eff ->
k eff
Worker.workerThread workerState
pure (Pier{..})