packages feed

futhark-server 1.2.4.0 → 1.3.0.0

raw patch · 4 files changed

+89/−45 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Futhark.Server: Field :: Text -> TypeName -> Field
+ Futhark.Server: ServerException :: Text -> ServerException
+ Futhark.Server: [fieldName] :: Field -> Text
+ Futhark.Server: [fieldType] :: Field -> TypeName
+ Futhark.Server: data Field
+ Futhark.Server: data ServerException
+ Futhark.Server: instance GHC.Exception.Type.Exception Futhark.Server.ServerException
+ Futhark.Server: instance GHC.Show.Show Futhark.Server.ServerException
+ Futhark.Server: type TuningParamName = Text
- Futhark.Server: cmdEntryPoints :: Server -> IO (Either CmdFailure [Text])
+ Futhark.Server: cmdEntryPoints :: Server -> IO (Either CmdFailure [EntryName])
- Futhark.Server: cmdFields :: Server -> Text -> IO (Either CmdFailure [Text])
+ Futhark.Server: cmdFields :: Server -> TypeName -> IO (Either CmdFailure [Field])
- Futhark.Server: cmdNew :: Server -> Text -> Text -> [Text] -> IO (Maybe CmdFailure)
+ Futhark.Server: cmdNew :: Server -> VarName -> TypeName -> [VarName] -> IO (Maybe CmdFailure)
- Futhark.Server: cmdProject :: Server -> Text -> Text -> Text -> IO (Maybe CmdFailure)
+ Futhark.Server: cmdProject :: Server -> VarName -> VarName -> Text -> IO (Maybe CmdFailure)
- Futhark.Server: cmdSetTuningParam :: Server -> Text -> Text -> IO (Either CmdFailure [Text])
+ Futhark.Server: cmdSetTuningParam :: Server -> TuningParamName -> Int -> IO (Maybe CmdFailure)
- Futhark.Server: cmdTuningParamClass :: Server -> Text -> IO (Either CmdFailure Text)
+ Futhark.Server: cmdTuningParamClass :: Server -> TuningParamName -> IO (Either CmdFailure Text)
- Futhark.Server: cmdTuningParams :: Server -> Text -> IO (Either CmdFailure [Text])
+ Futhark.Server: cmdTuningParams :: Server -> EntryName -> IO (Either CmdFailure [TuningParamName])
- Futhark.Server: cmdTypes :: Server -> IO (Either CmdFailure [Text])
+ Futhark.Server: cmdTypes :: Server -> IO (Either CmdFailure [TypeName])

Files

CHANGELOG.md view
@@ -1,5 +1,16 @@ # Revision history for futhark-server +## 1.3.0.0 -- 2026-03-05++* `Futhark.Server.Values.getValue` now detects attempts to retrieve (some)+  non-opaque values instead of silently producing something invalid.++* `cmdSetTuningParam` now has a more precise type.++* Server-related exceptions are now reported with the `ServerException` type.++* `cmdFields` now produces structured information.+ ## 1.2.4.0 -- 2026-02-19  * Report exit code when server terminates with nonzero exit code.
futhark-server.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.4 name:               futhark-server-version:            1.2.4.0+version:            1.3.0.0 synopsis: Client implementation of the Futhark server protocol.  description: Provides an easy way to interact with a running Futhark
src/Futhark/Server.hs view
@@ -10,26 +10,32 @@ -- functions for loading data into a server. -- -- Error messages produced by the server will be returned as a--- 'CmdFailure'.  However, certain errors (such as if the server+-- t'CmdFailure'.  However, certain errors (such as if the server -- process terminates unexpectedly, or temporary files cannot be -- created) will result in an IO exception. -- -- Many of the functions here are documented only as the server -- protocol command they correspond to.  See the protocol -- documentation for details.+--+-- Type aliases are added for readability, but many of the commands simply+-- accept and produce 'T.Text's. module Futhark.Server   ( -- * Server creation     Server,     ServerCfg (..),     newServerCfg,     withServer,+    ServerException (..),      -- * Commands     Cmd,     CmdFailure (..),+    Field (..),     VarName,     TypeName,     EntryName,+    TuningParamName,     InputType (..),     OutputType (..), @@ -89,9 +95,24 @@ import System.IO.Temp (getCanonicalTemporaryDirectory) import qualified System.Process as P +-- | An unexpected IO exception describing an error related to interacting with+-- the server, such as failing to start it, or the server crashing.+data ServerException+  = -- | Human-readable error message.+    ServerException T.Text+  deriving (Show)++instance Exception ServerException+ -- | The name of a command. type Cmd = Text +-- | A record field+data Field = Field+  { fieldName :: Text,+    fieldType :: TypeName+  }+ -- | A handle to a running server. data Server = Server   { serverStdin :: Handle,@@ -131,11 +152,10 @@       cfgOnLine = \_ _ -> pure ()     } --- | Start up a server.  Make sure that 'stopServer' is eventually--- called on the server.  If this does not happen, then temporary--- files may be left on the file system.  You almost certainly wish to--- use 'bracket' or similar to avoid this.  Calls 'error' if startup--- fails.+-- | Start up a server. Make sure that 'stopServer' is eventually called on the+-- server. If this does not happen, then temporary files may be left on the file+-- system. You almost certainly wish to use 'bracket' or similar to avoid this.+-- Throws 'ServerException' if startup fails. startServer :: ServerCfg -> IO Server startServer (ServerCfg prog options debug on_line_f) = do   tmpdir <- getCanonicalTemporaryDirectory@@ -152,9 +172,11 @@   code <- P.getProcessExitCode phandle   case code of     Just (ExitFailure e) ->-      error $ "Cannot start " ++ prog ++ ": error " ++ show e+      throw . ServerException $+        "Cannot start " <> T.pack prog <> ": error " <> T.pack (show e)     Just ExitSuccess ->-      error $ "Cannot start " ++ prog ++ ": terminated immediately, but reported success."+      throw . ServerException $+        "Cannot start " <> T.pack prog <> ": terminated immediately, but reported success."     Nothing -> do       let server =             Server@@ -171,19 +193,19 @@     onStartupError :: Server -> IOError -> IO a     onStartupError s _ = do       code <- P.waitForProcess $ serverProc s-      stderr_s <- readFile $ serverErrLog s+      stderr_s <- T.readFile $ serverErrLog s       removeFile $ serverErrLog s-      error $+      throw . ServerException $         "Command failed with "-          ++ show code-          ++ ":\n"-          ++ unwords (prog : options)-          ++ "\nStderr:\n"-          ++ stderr_s+          <> T.pack (show code)+          <> ":\n"+          <> T.pack (unwords (prog : options))+          <> "\nStderr:\n"+          <> stderr_s --- | Shut down a server.  It may not be used again.  Calls 'error' if--- the server process terminates with a failing exit code--- (i.e. anything but 'ExitSuccess').+-- | Shut down a server. It may not be used again. Throws 'ServerException' if+-- the server process terminates with a failing exit code (i.e. anything but+-- 'ExitSuccess'). stopServer :: Server -> IO () stopServer s = flip finally (removeFile (serverErrLog s)) $ do   hClose $ serverStdin s@@ -191,10 +213,10 @@   case code of     ExitSuccess -> pure ()     ExitFailure x -> do-      stderr_s <- readFile $ serverErrLog s-      error $+      stderr_s <- T.readFile $ serverErrLog s+      throw . ServerException $         "Server terminated with nonzero exit code "-          <> show x+          <> T.pack (show x)           <> " and stderr:\n"           <> stderr_s @@ -205,7 +227,7 @@ abortServer = P.terminateProcess . serverProc  -- | Start a server, execute an action, then shut down the server.--- The 'Server' may not be returned from the action.+-- The t'Server' may not be returned from the action. withServer :: ServerCfg -> (Server -> IO a) -> IO a withServer cfg m = mask $ \restore -> do   server <- startServer cfg@@ -280,18 +302,18 @@       let code_msg =             case code of               Just (ExitFailure x) ->-                "\nServer process exited unexpectedly with exit code: " ++ show x+                "\nServer process exited unexpectedly with exit code: " <> T.pack (show x)               Just ExitSuccess -> mempty               Nothing -> mempty-      stderr_s <- readFile $ serverErrLog s-      error $+      stderr_s <- T.readFile $ serverErrLog s+      throw . ServerException $         "After sending command "-          ++ show cmd-          ++ " to server process:"-          ++ show e-          ++ code_msg-          ++ "\nServer stderr:\n"-          ++ stderr_s+          <> cmd+          <> " to server process:"+          <> T.pack (show e)+          <> code_msg+          <> "\nServer stderr:\n"+          <> stderr_s  -- | The name of a server-side variable. type VarName = Text@@ -302,6 +324,9 @@ -- | The name of an entry point. type EntryName = Text +-- | The name of a tuning parameter.+type TuningParamName = Text+ -- | The type of an input of an entry point.  If 'inputConsumed', then -- the value passed in a 'cmdCall' must not be used again (nor any of -- its aliases).@@ -381,35 +406,41 @@ cmdUnpauseProfiling s = helpCmd s "unpause_profiling" []  -- | @set_tuning_param param value@-cmdSetTuningParam :: Server -> Text -> Text -> IO (Either CmdFailure [Text])-cmdSetTuningParam s param value = sendCommand s "set_tuning_param" [param, value]+cmdSetTuningParam :: Server -> TuningParamName -> Int -> IO (Maybe CmdFailure)+cmdSetTuningParam s param value = helpCmd s "set_tuning_param" [param, T.pack (show value)] --- | @tuning_params@-cmdTuningParams :: Server -> Text -> IO (Either CmdFailure [Text])+-- | @tuning_params entry_point@+cmdTuningParams :: Server -> EntryName -> IO (Either CmdFailure [TuningParamName]) cmdTuningParams s entry = sendCommand s "tuning_params" [entry]  -- | @tuning_param_class param@-cmdTuningParamClass :: Server -> Text -> IO (Either CmdFailure Text)+cmdTuningParamClass :: Server -> TuningParamName -> IO (Either CmdFailure Text) cmdTuningParamClass s param = fmap mconcat <$> sendCommand s "tuning_param_class" [param]  -- | @types@-cmdTypes :: Server -> IO (Either CmdFailure [Text])+cmdTypes :: Server -> IO (Either CmdFailure [TypeName]) cmdTypes s = sendCommand s "types" []  -- | @entry_points@-cmdEntryPoints :: Server -> IO (Either CmdFailure [Text])+cmdEntryPoints :: Server -> IO (Either CmdFailure [EntryName]) cmdEntryPoints s = sendCommand s "entry_points" []  -- | @fields type@-cmdFields :: Server -> Text -> IO (Either CmdFailure [Text])-cmdFields s t = sendCommand s "fields" [t]+cmdFields :: Server -> TypeName -> IO (Either CmdFailure [Field])+cmdFields s t = fmap (zipWith parseField [1..]) <$> sendCommand s "fields" [t]+  where+    parseField :: Int -> Text -> Field+    parseField l f =+      case T.words f of+        (fn : ft) -> Field fn $ T.unwords ft+        _ -> error $ "Invalid field on line " ++ show l ++ " of `fields` output: \"" ++ T.unpack f ++ "\""  -- | @new var0 type var1...@-cmdNew :: Server -> Text -> Text -> [Text] -> IO (Maybe CmdFailure)+cmdNew :: Server -> VarName -> TypeName -> [VarName] -> IO (Maybe CmdFailure) cmdNew s var0 t vars = helpCmd s "new" $ var0 : t : vars  -- | @project to from field@-cmdProject :: Server -> Text -> Text -> Text -> IO (Maybe CmdFailure)+cmdProject :: Server -> VarName -> VarName -> Text -> IO (Maybe CmdFailure) cmdProject s to from field = helpCmd s "project" [to, from, field]  -- | @shape v@
src/Futhark/Server/Values.hs view
@@ -27,8 +27,10 @@         case Bin.decodeOrFail bytes of           Left (_, _, e) ->             pure $ Left $ "Cannot load value from generated byte stream:\n" <> T.pack e-          Right (_, _, val) ->-            pure $ Right val+          Right (remnant, _, val)+            | LBS.null remnant -> pure $ Right val+            | otherwise ->+                pure $ Left "Cannot load opaque value."  -- | Store a non-opaque value in the server.  A variable with the -- given name must not already exist (use 'cmdFree' to free it first