MFlow-0.4.6.0: stateful, RESTful web framework

Safe HaskellNone
LanguageHaskell98

MFlow

Contents

Description

Non monadic low level primitives that implement the MFlow application server. See MFlow.Form for the higher level interface that you may use.

It implements a scheduler of Processable messages that are served according to the source identification and the verb invoked. The scheduler executes the appropriate workflow (using the workflow package). The workflow will send additional messages to the source and wait for the responses. The dialog is identified by a Token, which is associated to the Flow. The computation state is optionally logged, on timeout the process is killed, when invoked again, the execution state is recovered as if no interruption took place.

There is no assumption about message codification, so instantiations of this scheduler for different infrastructures is possible, including non-web based ones as long as they support or emulate cookies.

MFlow.Hack is an instantiation for the Hack interface in a Web context.

MFlow.Wai is a instantiation for the WAI interface.

MFlow.Forms implements a monadic type safe interface with composable widgets and an applicative combinator with a higher-level communication interface.

MFlow.Forms.XHtml is an instantiation for the Text.XHtml format

MFlow.Forms.HSP is an instantiation for the Haskell Server Pages format

MFlow.Forms.Blaze.Html is an instantiation for blaze-html. Use this instead of XHtml and HSP, which are for backwards compat reasons.

There are some *.All packages that contain a mix of these instantiations. For example, MFlow.Wai.Blaze.Html.All includes most of all necessary for using MFlow with Wai http://hackage.haskell.org/package/wai and Blaze-html http://hackage.haskell.org/package/blaze-html

In order to manage resources, there are primitives that kill the process and its state after a timeout.

All these details are hidden in the monad of MFlow.Forms which provides an higher level interface.

Fragment based streaming: sendFragment are provided only at this level.

stateless and transient server processes are also possible. stateless are request-response processes. While transient processes do not persist after timeout, they restart anew after a timeout or a crash.

Synopsis

Documentation

type Flow = Token -> Workflow IO () #

type Params = [(String, String)] #

class Processable a where #

Minimal complete definition

pwfPath, puser, pind, getParams

Methods

pwfname :: a -> String #

pwfPath :: a -> [String] #

puser :: a -> String #

pind :: a -> String #

getParams :: a -> Params #

data Token #

A Token identifies a Flow that handle messages. The scheduler composes a Token with every Processable message that arrives and sends the message to the appropriate Flow.

Constructors

Token 

Fields

type ProcList = WorkflowList IO Token () #

List of (wfname, workflow) pairs, to be scheduled depending on the message's pwfname

low level comunication primitives. Use ask instead

flushRec :: Token -> IO (Maybe Req) #

receive :: Typeable a => Token -> IO a #

receiveReq :: Token -> IO Req #

send :: Token -> HttpData -> IO () #

Send a complete response. send :: Token -> HttpData -> IO()

sendFragment :: Token -> HttpData -> IO () #

Send a response fragment, useful for streaming. The last packet must be sent trough send.

sendEndFragment :: Token -> HttpData -> IO () #

Deprecated: use "send" to end a fragmented response instead

sendToMF :: (Typeable * a, Processable a) => Token -> a -> IO () #

Flow configuration

setNoScript :: String -> IO () #

Set the flow to be executed when the URL has no path. The home page.

By default it is "noscript". Although it is changed by runNavigation to it's own flow name.

addMessageFlows :: [(String, Token -> Workflow IO ())] -> IO () #

Add a list of flows to be scheduled. Each entry in the list is a pair (path, flow)

getMessageFlows :: IO (WorkflowList IO Token ()) #

Return the list of the scheduler.

transient :: (Token -> IO ()) -> Flow #

Executes a monadic computation that are send and receive messages, but does not store it's state in permanent storage. The process once stopped, will restart anew

stateless :: (Params -> IO HttpData) -> Flow #

Executes a simple request-response computation that receive the params and return a response.

It is used with addMessageFlows

There is a higher level version wstateless in MFLow.Forms

anonymous :: [Char] #

The anonymous user.

hlog :: Handle #

The handler of the error log.

setNotFoundResponse :: (Bool -> String -> ByteString) -> IO () #

Set the 404 "not found" response.

The parameter is as follows: (Bool Either if the user is Administrator or not -> String The error string -> HttpData) The response. See defNotFoundResponse code for an example

ByteString tags

very basic but efficient bytestring tag formatting

btag :: String -> Attribs -> ByteString -> ByteString #

Writes a XML tag in a ByteString. It is the most basic form of formatting. For more sophisticated formatting , use MFlow.Forms.XHtml or MFlow.Forms.HSP.

bhtml :: Attribs -> ByteString -> ByteString #

bhtml ats v= btag "html" ats v

bbody :: Attribs -> ByteString -> ByteString #

bbody ats v= btag "body" ats v

type Attribs = [(String, String)] #

user

userRegister :: MonadIO m => UserStr -> PasswdStr -> m (Maybe String) #

Register a user with the auth method.

setAdminUser :: MonadIO m => UserStr -> PasswdStr -> m () #

Set the Administrator user and password. It must be defined in Main, before any configuration parameter is read and before the execution of any flow.

data Auth #

Constructors

Auth 

setAuthMethod :: Auth -> IO () #

Sets an authentication method, that includes the registration and validation calls. Both return Nothing if successful. Otherwise they return a text message explaining the failure.

static files

config

getConfig :: String -> String -> String #

Read a config variable from the config file "mflow.config". If it is not set, use the second parameter and add it to the configuration list so next time the administrator can change it in the configuration file.

setFilesPath :: MonadIO m => String -> m () #

Set the path of the files in the web server. The links to the files are relative to it. The files are cached (memoized) according with the Data.TCache policies in the program space. This avoid the blocking of the efficient GHC threads by frequent IO calls. This enhances the performance in the context of heavy concurrency. It uses Memoization. The caching and uncaching follows the setPersist criteria

internal use

msgScheduler :: (Typeable a, Processable a) => a -> IO (HttpData, ThreadId) #

The scheduler creates a Token with every Processable message that arrives and sends the message to the appropriate flow, then waits for the response and returns it.

This is the core of the application server. MFLow.Wai and MFlow.Hack use it