aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLia Lenckowski <lialenck@protonmail.com>2023-07-23 10:13:15 +0200
committerLia Lenckowski <lialenck@protonmail.com>2023-07-23 10:13:15 +0200
commit29c7f3e75a7b9589aff6d46a7a47bcd47207a0e4 (patch)
treefc11c64ded34530aff44143645d63d320c77947c /src
parentb5e131f3aefc3ac3d498991e57aa05cffd955044 (diff)
downloadfastbangs-29c7f3e75a7b9589aff6d46a7a47bcd47207a0e4.tar
fastbangs-29c7f3e75a7b9589aff6d46a7a47bcd47207a0e4.tar.bz2
fastbangs-29c7f3e75a7b9589aff6d46a7a47bcd47207a0e4.tar.zst
sync own bangs with disk
Diffstat (limited to 'src')
-rw-r--r--src/Main.hs59
1 files changed, 51 insertions, 8 deletions
diff --git a/src/Main.hs b/src/Main.hs
index 1517ebd..c8290db 100644
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -1,22 +1,65 @@
-{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE OverloadedStrings, LambdaCase #-}
module Main (main) where
+import Control.Concurrent.STM.TChan
+import Control.Monad (forever)
import Data.Aeson
-import Data.ByteString (ByteString)
-import Data.IORef
-import Network.HTTP.Simple
+import Data.ByteString (ByteString, toStrict)
+import GHC.Conc
+import Network.HTTP.Simple (Response, httpJSON, getResponseBody)
+import System.AtomicWrite.Writer.LazyByteString (atomicWriteFile)
import Yesod
+import qualified Data.ByteString as BS
+
import Bangs
data Search = Search {
- ddgBangs :: IORef Bangs,
- ownBangs :: IORef Bangs,
- serializedBangs :: IORef ByteString
+ ownBangs :: TVar Bangs,
+ ddgBangs :: TVar Bangs,
+ serializedBangs :: TVar ByteString,
+ syncFileNotifications :: TChan ()
}
+reserialize :: Search -> STM ()
+reserialize s = do
+ own <- readTVar $ ownBangs s
+ ddg <- readTVar $ ddgBangs s
+ writeTVar (serializedBangs s) $ toStrict $ encode $ own <> ddg -- left biased union
+ writeTChan (syncFileNotifications s) ()
+
+-- second argument: readable tchan, duped from the tchan in 'Search'
+fileSyncThread :: Search -> TChan () -> IO a
+fileSyncThread s rc = forever $ do
+ nextBangs <- atomically $ do
+ readTChan rc
+ readTVar (ownBangs s)
+ atomicWriteFile "bangs.json" $ encode nextBangs
+
+spawnFileSyncThread :: Search -> IO ()
+spawnFileSyncThread s = do
+ readableChan <- atomically $ dupTChan (syncFileNotifications s)
+ forkIO $ fileSyncThread s readableChan
+ return ()
+
+loadOwnBangs :: IO Bangs
+loadOwnBangs = eitherDecodeFileStrict "bangs.json" >>= \case
+ Left e -> error e
+ Right b -> return b
+
main :: IO ()
main = do
ans <- (httpJSON "https://duckduckgo.com/bang.v255.js") :: IO (Response DDGBangs)
- print ans
+ s <- Search
+ <$> (loadOwnBangs >>= newTVarIO)
+ <*> newTVarIO (toBangs $ getResponseBody ans)
+ <*> newTVarIO BS.empty
+ <*> newBroadcastTChanIO
+
+ spawnFileSyncThread s
+ atomically $ reserialize s
+
+ print =<< readTVarIO (serializedBangs s)
+ _ <- getLine
+ return ()