156 lines
3.7 KiB
Haskell
156 lines
3.7 KiB
Haskell
|
|
module API
|
|
( P2PRCapi(..)
|
|
, MapPortRequest(..)
|
|
, p2prcAPI
|
|
)
|
|
where
|
|
|
|
|
|
import System.Directory ( getCurrentDirectory )
|
|
|
|
import System.Process ( ProcessHandle )
|
|
|
|
import Data.Aeson ( FromJSON )
|
|
|
|
import Error
|
|
( IOEitherError
|
|
)
|
|
|
|
import JSON
|
|
( IPAddressTable(..)
|
|
, MapPortResponse(..)
|
|
, P2PRCConfig
|
|
)
|
|
|
|
import CLI
|
|
( StdInput(..)
|
|
, CLIOpt(..)
|
|
, eitherErrDecode
|
|
, p2prcCmdName
|
|
, eitherExecProcess
|
|
, eitherExecProcessParser
|
|
, spawnProcP2PRC
|
|
)
|
|
|
|
-- import System.Environment (lookupEnv)
|
|
|
|
|
|
|
|
-- | Lower level P2PRC Haskell api that exposes basic functionality necessary to joint the network.
|
|
|
|
data P2PRCapi
|
|
= MkP2PRCapi
|
|
{ startServer :: IOEitherError ProcessHandle
|
|
-- ^ Start server
|
|
-- , execInitConfig :: IOEitherError P2PRCConfig
|
|
-- ^ Instantiate server configuration
|
|
, execListServers :: IOEitherError IPAddressTable
|
|
-- ^ List servers in network
|
|
, execMapPort :: MapPortRequest -> IOEitherError MapPortResponse
|
|
-- ^ Exposes and associates a local TCP port with a remote DNS address
|
|
}
|
|
|
|
|
|
-- | This defines the request required to create an association between a TCP socket port and a DNS server in the network. If successful, it makes a resource available in the network.
|
|
data MapPortRequest =
|
|
MkMapPortRequest -- ^ P2PRC's port allocation request value
|
|
Int -- ^ TCP socket number
|
|
String -- ^ Network domain name
|
|
|
|
|
|
{-|
|
|
This function intiates a pure P2PRC runtime state and builds up a 'P2PRCapi' API instance. It allows a developer to create computing orchestration algorithms using the API primitives.
|
|
|
|
==== __Example__
|
|
|
|
The following example show how this function can be used to expose the runtime functionalities:
|
|
|
|
@
|
|
module Main where
|
|
|
|
import P2PRC
|
|
( p2prcAPI
|
|
, P2PRCapi(..)
|
|
)
|
|
|
|
main :: IO ()
|
|
main =
|
|
|
|
print "Hello P2PRC"
|
|
|
|
-- your code logic goes here
|
|
|
|
where
|
|
|
|
MkP2PRCapi
|
|
{ startServer=startServer
|
|
, execMapPort=execMapPort
|
|
, execListServers=execListServers
|
|
, execInitConfig=execInitConfig
|
|
} = p2prcAPI
|
|
@
|
|
-}
|
|
|
|
{-# WARNING p2prcAPI "This function is currently unstable because the configuration reading is dependent on the following issue: https://github.com/Akilan1999/p2p-rendering-computation/issues/120" #-}
|
|
p2prcAPI :: P2PRCapi
|
|
p2prcAPI =
|
|
MkP2PRCapi
|
|
{ startServer = spawnProcP2PRC p2prcCmdName [ MkOptAtomic "-s" ]
|
|
|
|
, execListServers =
|
|
execProcP2PRCParser [ MkOptAtomic "--ls" ] MkEmptyStdInput
|
|
|
|
, execMapPort =
|
|
\ (MkMapPortRequest portNumber domainName) ->
|
|
execProcP2PRCParser
|
|
[ MkOptTuple
|
|
( "--mp"
|
|
, show portNumber
|
|
)
|
|
, MkOptTuple
|
|
( "--dn"
|
|
, domainName
|
|
)
|
|
]
|
|
MkEmptyStdInput
|
|
|
|
-- , execInitConfig = do
|
|
|
|
-- confInitRes <- execProcP2PRC [ MkOptAtomic "--dc" ] MkEmptyStdInput
|
|
|
|
-- case confInitRes of
|
|
-- (Right _) -> do
|
|
|
|
-- maybeValue <- lookupEnv "P2PRC"
|
|
|
|
-- -- TODO: get config file name dynamically
|
|
-- --
|
|
-- currDirectory <- getCurrentDirectory
|
|
|
|
-- -- TODO: change values before loading file
|
|
-- let fname = currDirectory ++ "/config.json" :: FilePath
|
|
|
|
|
|
-- -- TODO: read config check if file exists
|
|
-- configContent <- readFile fname
|
|
|
|
-- pure $ eitherErrDecode configContent
|
|
|
|
-- (Left err) -> pure $ Left err
|
|
|
|
}
|
|
|
|
|
|
where
|
|
|
|
execProcP2PRCParser ::
|
|
FromJSON a =>
|
|
[CLIOpt] -> StdInput -> IOEitherError a
|
|
|
|
execProcP2PRCParser = eitherExecProcessParser p2prcCmdName
|
|
-- TODO: GHC question, why does it scope down instead staying generic
|
|
|
|
-- execProcP2PRC = eitherExecProcess p2prcCmdName
|
|
|