| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
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 eVarJust 42>>>modifyExtVarIO_ eVar (\x -> pure (x+1))()>>>tryReadExtVarIO eVarJust 43
Synopsis
- data ExtVar a
- extVar :: ByteString -> String -> ExtVar a
- newExtVar :: (Binary a, Typeable a) => a -> Process (MVar a, ExtVar a)
- newEmptyExtVar :: (Binary a, Typeable a) => Process (MVar a, ExtVar a)
- makeExtVar :: (Binary a, Typeable a) => MVar a -> Process (ExtVar a)
- killExtVar :: forall a. (Binary a, Typeable a) => ExtVar a -> Process ()
- takeExtVar :: (Binary a, Typeable a) => ExtVar a -> Process a
- tryTakeExtVar :: (Binary a, Typeable a) => ExtVar a -> Process (Maybe a)
- putExtVar :: (Binary a, Typeable a) => ExtVar a -> a -> Process ()
- tryPutExtVar :: (Binary a, Typeable a) => ExtVar a -> a -> Process Bool
- readExtVar :: (Binary a, Typeable a) => ExtVar a -> Process a
- tryReadExtVar :: (Binary a, Typeable a) => ExtVar a -> Process (Maybe a)
- withExtVar :: (Binary a, Typeable a) => ExtVar a -> (a -> Process b) -> Process b
- modifyExtVar_ :: (Binary a, Typeable a) => ExtVar a -> (a -> Process a) -> Process ()
- modifyExtVar :: (Binary a, Typeable a) => ExtVar a -> (a -> Process (a, b)) -> Process b
- takeExtVarIO :: (Binary a, Typeable a) => ExtVar a -> IO a
- tryTakeExtVarIO :: (Binary a, Typeable a) => ExtVar a -> IO (Maybe a)
- putExtVarIO :: (Binary a, Typeable a) => ExtVar a -> a -> IO ()
- tryPutExtVarIO :: (Binary a, Typeable a) => ExtVar a -> a -> IO Bool
- readExtVarIO :: (Binary a, Typeable a) => ExtVar a -> IO a
- tryReadExtVarIO :: (Binary a, Typeable a) => ExtVar a -> IO (Maybe a)
- withExtVarIO :: (Binary a, Typeable a) => ExtVar a -> (a -> IO b) -> IO b
- modifyExtVarIO_ :: (Binary a, Typeable a) => ExtVar a -> (a -> IO a) -> IO ()
- modifyExtVarIO :: (Binary a, Typeable a) => ExtVar a -> (a -> IO (a, b)) -> IO b
- newExtVarStream :: (Binary a, Typeable a, MonadIO m, MonadBase Process n) => [a] -> n (ExtVar [a], m (Maybe a))
Documentation
Instances
| Eq (ExtVar a) Source # | |
| Ord (ExtVar a) Source # | |
Defined in Hyperion.ExtVar | |
| Typeable a => Show (ExtVar a) Source # | |
| Generic (ExtVar a) Source # | |
| Binary (ExtVar a) Source # | |
| type Rep (ExtVar a) Source # | |
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))) | |
Arguments
| :: ByteString | End point address. |
| -> String | Name of the ExtVar |
| -> ExtVar a |
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 likewithExtVar,modifyExtVar_, andmodifyExtVar(and all of their IO variants) must be used with care. On the host side, they cause data to be taken out of the underlyingMVar. If an exception occurs, that data will not be automatically replaced. Thus, the underlyingMVarcould 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.