hyperion-0.1.0.0
Safe HaskellNone
LanguageHaskell2010

Hyperion.ExtVar

Description

An ExtVar is an MVar that can be accessed by an external client. The "host" is the machine where the underlying MVar exists. The host can continue to use the underlying MVar as usual. A client can interact with it via functions like takeExtVar, putExtVar, readExtVar, etc., which behave in the same way as their MVar counterparts. An ExtVar can be recontstructed from its representation as a String or serialized to/from Binary data (and hence sent across a network).

For an example of using an ExtVar as a client, look in the hosts logs for a line that looks like:

[Thu 01/06/22 13:04:17] New ExtVar: extVar @Int "login1.cm.cluster:39443:0" "test"

This shows that the host machine has made an ExtVar and it is ready to be accessed by a client. Now in a GHCi session (possibly on a completely different machine), you can do:

>>> eVar = extVar @Int "login1.cm.cluster:39443:0" "test"
>>> tryReadExtVarIO eVar
Just 42
>>> modifyExtVarIO_ eVar (\x -> pure (x+1))
()
>>> tryReadExtVarIO eVar
Just 43
Synopsis

Documentation

data ExtVar a Source #

Instances

Instances details
Eq (ExtVar a) Source # 
Instance details

Defined in Hyperion.ExtVar

Methods

(==) :: ExtVar a -> ExtVar a -> Bool #

(/=) :: ExtVar a -> ExtVar a -> Bool #

Ord (ExtVar a) Source # 
Instance details

Defined in Hyperion.ExtVar

Methods

compare :: ExtVar a -> ExtVar a -> Ordering #

(<) :: ExtVar a -> ExtVar a -> Bool #

(<=) :: ExtVar a -> ExtVar a -> Bool #

(>) :: ExtVar a -> ExtVar a -> Bool #

(>=) :: ExtVar a -> ExtVar a -> Bool #

max :: ExtVar a -> ExtVar a -> ExtVar a #

min :: ExtVar a -> ExtVar a -> ExtVar a #

Typeable a => Show (ExtVar a) Source # 
Instance details

Defined in Hyperion.ExtVar

Methods

showsPrec :: Int -> ExtVar a -> ShowS #

show :: ExtVar a -> String #

showList :: [ExtVar a] -> ShowS #

Generic (ExtVar a) Source # 
Instance details

Defined in Hyperion.ExtVar

Associated Types

type Rep (ExtVar a) :: Type -> Type #

Methods

from :: ExtVar a -> Rep (ExtVar a) x #

to :: Rep (ExtVar a) x -> ExtVar a #

Binary (ExtVar a) Source # 
Instance details

Defined in Hyperion.ExtVar

Methods

put :: ExtVar a -> Put #

get :: Get (ExtVar a) #

putList :: [ExtVar a] -> Put #

type Rep (ExtVar a) Source # 
Instance details

Defined in Hyperion.ExtVar

type Rep (ExtVar a) = D1 ('MetaData "ExtVar" "Hyperion.ExtVar" "hyperion-0.1.0.0-BChDBJtiU1m4GBpewNuAxw" 'False) (C1 ('MetaCons "MkExtVar" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 NodeId) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 String)))

extVar Source #

Arguments

:: ByteString

End point address.

-> String

Name of the ExtVar

-> ExtVar a 

ExtVar from an address and a name. To see what arguments you should pass to extVar, it is best to look for the "Made ExtVar" entry in the log of the host machine.

newExtVar :: (Binary a, Typeable a) => a -> Process (MVar a, ExtVar a) Source #

Make a new ExtVar containing x. Return both the ExtVar and its underlying MVar.

newEmptyExtVar :: (Binary a, Typeable a) => Process (MVar a, ExtVar a) Source #

Make a new empty ExtVar. Return both the ExtVar and its underlying MVar.

makeExtVar :: (Binary a, Typeable a) => MVar a -> Process (ExtVar a) Source #

Make a new ExtVar from an MVar. The host program can continue to use the MVar as usual.

killExtVar :: forall a. (Binary a, Typeable a) => ExtVar a -> Process () Source #

Kill the server underlying the ExtVar. Subsequent calls from clients may block indefinitely.

takeExtVar :: (Binary a, Typeable a) => ExtVar a -> Process a Source #

takeExtVar, etc. are analogous to takeMVar, etc. All functions block until they receive a response from the host.

Note: Safety
The functions takeExtVar, tryTakeExtVar, and those that use them like withExtVar, modifyExtVar_, and modifyExtVar (and all of their IO variants) must be used with care. On the host side, they cause data to be taken out of the underlying MVar. If an exception occurs, that data will not be automatically replaced. Thus, the underlying MVar could remain empty and the data that was in it may be lost.

Here is an example situation where that would occur. Suppose that we have an ExtVar with type String:

extVar @String "host.address.com" "extVar:0"

However, suppose that a client tries to take an ExtVar with the same address and name, but the wrong type:

>>> takeExtVarIO $ extVar @Int "host.address.com" "extVar:0"

On the host, the String will be removed from the MVar, serialized to ByteString, and sent to the client. (The host no longer has the data.) The client will try to deserialize the ByteString to an Int, which will fail (because Int is the incorrect type) and throw an exception. As takeExtVar is currently implemented, the data will never get sent back to the host.

It is the client's responsibility to make sure this doesn't happen. In a GHCi session, it is recommended that you use readExtVarIO first to make sure your connection is good and you have the right ExtVar *including its type*, before you use functions like takeExtVar.

tryTakeExtVar :: (Binary a, Typeable a) => ExtVar a -> Process (Maybe a) Source #

putExtVar :: (Binary a, Typeable a) => ExtVar a -> a -> Process () Source #

tryPutExtVar :: (Binary a, Typeable a) => ExtVar a -> a -> Process Bool Source #

readExtVar :: (Binary a, Typeable a) => ExtVar a -> Process a Source #

tryReadExtVar :: (Binary a, Typeable a) => ExtVar a -> Process (Maybe a) Source #

withExtVar :: (Binary a, Typeable a) => ExtVar a -> (a -> Process b) -> Process b Source #

modifyExtVar_ :: (Binary a, Typeable a) => ExtVar a -> (a -> Process a) -> Process () Source #

modifyExtVar :: (Binary a, Typeable a) => ExtVar a -> (a -> Process (a, b)) -> Process b Source #

takeExtVarIO :: (Binary a, Typeable a) => ExtVar a -> IO a Source #

IO versions of ExtVar functions, for convenience.

putExtVarIO :: (Binary a, Typeable a) => ExtVar a -> a -> IO () Source #

withExtVarIO :: (Binary a, Typeable a) => ExtVar a -> (a -> IO b) -> IO b Source #

modifyExtVarIO_ :: (Binary a, Typeable a) => ExtVar a -> (a -> IO a) -> IO () Source #

modifyExtVarIO :: (Binary a, Typeable a) => ExtVar a -> (a -> IO (a, b)) -> IO b Source #

newExtVarStream :: (Binary a, Typeable a, MonadIO m, MonadBase Process n) => [a] -> n (ExtVar [a], m (Maybe a)) Source #

Store the given list in an ExtVar and return an action that repeatedly pops the first element from the list until there are none left. An external client can freely modify the contents of the ExtVar, and in this way insert or delete elements by hand while the program is running.