
Hello Café! It's my first post here so do tell me if I get something wrong :) I'm in the process of writing an event database; it should adhere to ACID principles and is specifically aimed at persisting then broadcasting events in some event-driven system. The code is up on GitHub and I expect to build a Hackage package soon, for now I'm prototyping with Stack generating the .cabal file, but this will change when things settle down. My question is about a function I have: readEvents :: Word64 -> Connection -> IO ([IndexedEvent], TChan IndexedEvent) readEvents from conn = do (ec, chan) <- atomically $ (,) <$> (readTVar $ evCount conn) <*> (dupTChan $ readSubs conn) evsFromDisk <- readEventsRange from ec conn pure (evsFromDisk, chan) For context please see the whole file: https://github.com/ahri/eventdb/blob/4747afb/src/Database/EventDB.hs#L172-L1... 1. What I'd like to understand is how I might unify the return type into a single `TChan IndexedEvent` which would contain first the `evsFromDisk` and then pull from the broadcast channel `chan`. The only way I can think to do it is to fork a thread to write to a new broadcast channel - which might be unexpected for a client of my API and seems quite heavyweight. I have a connected couple of questions too, related to lazy IO as I'm still learning Haskell! 2. does my `readEventsRange` function pull all events into memory or does lazy IO magically avoid this by streaming the data through from the disk? 3. if I did fork a thread and write the `evsFromDisk` and the sit in a ` forever` reading off `chan` and onto my new broadcast channel, would this result in all the written events being read into memory or does the laziness spread so that only when the client does a `readTChan` will the data flow through from the disk/`chan`? Thanks for reading, Adam
participants (1)
-
Adam