@@ -2,11 +2,73 @@
22
33Curryer (pun intended) is a fast, Haskell-exclusive RPC (remote procedure call) library. By using the latest Haskell serialization and streaming libraries, curryer aims to be the fastest and easiest means of communicating between Haskell-based processes.
44
5−Curryer is inspired by the now unmaintained [distributed-process](https://hackage.haskell.org/package/distributed-process) library.
5+Curryer is inspired by the now unmaintained [distributed-process](https://hackage.haskell.org/package/distributed-process) library, but is lighter-weight and uses a higher-performance serialization package.
66
77## Features
88
99* blocking and non-blocking remote function calls
1010* asynchronous server-to-client callbacks (for server-initiated notifications)
1111* timeouts
12−* utilizes versionable shared ADT for communication instead of shared function `StaticPtr`s
12+* leverages [winery](https://hackage.haskell.org/package/winery) for high-performance serialization
13+
14+## Code Example
15+
16+[Server](https://github.com/agentm/curryer/examples/SimpleKeyValueServer.hs):
17+
18+```haskell
19+data SetKey = SetKey String String
20+ deriving (Generic, Show)
21+ deriving Serialise via WineryVariant SetKey
22+
23+data GetKey = GetKey String
24+ deriving (Generic, Show)
25+ deriving Serialise via WineryVariant GetKey
26+
27+main :: IO ()
28+main = do
29+ kvmap <- M.newIO
30+ void $ serve kvRequestHandlers kvmap localHostAddr 8765 Nothing
31+
32+kvRequestHandlers :: RequestHandlers (M.Map String String)
33+kvRequestHandlers = [ RequestHandler $ \state (SetKey k v) ->
34+ atomically $ M.insert v k (connectionServerState state)
35+ , RequestHandler $ \state (GetKey k) ->
36+ atomically $ M.lookup k (connectionServerState state)
37+ ]
38+```
39+
40+[Client](https://github.com/agentm/curryer/examples/SimpleKeyValueClient.hs):
41+
42+```haskell
43+data SetKey = SetKey String String
44+ deriving (Generic, Show)
45+ deriving Serialise via WineryVariant SetKey
46+
47+data GetKey = GetKey String
48+ deriving (Generic, Show)
49+ deriving Serialise via WineryVariant GetKey
50+
51+data CommandOptions = Get {name :: String}
52+ | Set {name :: String, value :: String}
53+ deriving (Generic, Show)
54+
55+instance ParseRecord CommandOptions
56+
57+main :: IO ()
58+main = do
59+ opts <- getRecord "SimpleKeyValueClient"
60+ conn <- connect [] localHostAddr 8765
61+ case opts of
62+ Get k -> do
63+ eRet <- call conn (GetKey k)
64+ case eRet of
65+ Left err -> error (show err)
66+ Right (Just val) -> putStrLn val
67+ Right Nothing -> error "no such key"
68+ Set k v -> do
69+ eRet <- call conn (SetKey k v)
70+ case eRet of
71+ Left err -> error (show err)
72+ Right () -> pure ()
73+
74+```