https://wiki.haskell.org/api.php?action=feedcontributions&user=Mbrodersen&feedformat=atomHaskellWiki - User contributions [en]2024-03-28T15:53:19ZUser contributionsMediaWiki 1.35.5https://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58530Real World Applications/Event Driven Applications2014-07-04T08:53:42Z<p>Mbrodersen: /* Consequences */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application/architecture is an application/architecture that is driven by internal/external events. Most non-trivial applications/architectures (from Operating Systems to Web Servers and Enterprise applications) are event driven.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's warm up with a ''tiny'' toy event driven Haskell application.<br />
In this case, an event driven calculator that can add numbers and exit.<br />
Not very exciting but it is useful for introducing a number of key concepts.<br />
<br />
I will in the following use the term "Domain" to stand for the application state. Fell free to use "Shipping" instead of Domain if your application area is shipping or "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model].<br />
<br />
Here is the Domain for the calculator application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
data Domain =<br />
Domain Int<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
The calculator state simply keeps track of the current value.<br />
<br />
The next step is to define the events that the user can generate:<br />
<br />
<haskell><br />
data Event =<br />
EventAdd Int<br />
| EventExit<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
In this case all the user can do is to add and exit.<br />
<br />
With those two definition, we can now write the "domain update" function.<br />
It simply takes the current state of the domain and an event as input<br />
and outputs the updated domain:<br />
<br />
<haskell><br />
dmUpdate :: Domain -> Event -> Domain<br />
<br />
dmUpdate (Domain v) (EventAdd a) = Domain (v + a)<br />
<br />
dmUpdate dm _ = dm<br />
</haskell><br />
<br />
For this tiny toy example all we can do is to react to the EventAdd event<br />
and calculate the new value.<br />
<br />
The next step is to write the UI. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back (More on this later):<br />
<br />
<haskell><br />
uiUpdate :: Domain -> IO [Event]<br />
<br />
uiUpdate (Domain v) = do<br />
putStrLn $ "Value is now: " ++ show v<br />
if v < 3 then<br />
return [EventAdd 1]<br />
else<br />
return [EventExit]<br />
</haskell><br />
<br />
For this tiny toy example the UI will not even read from stdin.<br />
It instead return EventAdd events until the Domain state value is >= 3.<br />
After which it generates the EventExit event. Yes it is just a tiny toy example :-)<br />
<br />
Given ''dmUpdate'' and ''uiUpdate'' we can now write what is traditionally called the "Event Loop". The event loop is the beating heart of an event driven application:<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run _ (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (dmUpdate dm e) es<br />
</haskell><br />
<br />
For this tiny toy example, the event loop simply asks the UI for new events.<br />
And updates the domain when events are available. It exits when EventExit is received from the UI.<br />
<br />
And here is the main function to bootstrap the event loop:<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run (Domain 0) []<br />
</haskell><br />
<br />
''main'' simply creates a new domain (Domain 0) and calls ''run'' with an empty event list to get started.<br />
<br />
The result of running the application is:<br />
<br />
<haskell><br />
Value is now: 0<br />
Value is now: 1<br />
Value is now: 2<br />
Value is now: 3<br />
</haskell><br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However a number of key choices have been made that will profoundly shape how the application scales from this tiny application to "Enterprise" level:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
''dmUpdate'' is not generating any events.<br />
However in a more realistic application, updating the domain will typically result in additional events being generated.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
The idea is to keep as much of the code UI independent.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
Events can (should) be ''asynchronous''.<br />
<br />
And by the way, this is ''not'' MVC/MVP as will be shown later :-)<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring (Dashboard)<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server (Haste etc.)<br />
* Humble "File in Directory" Events<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58529Real World Applications/Event Driven Applications2014-07-04T08:50:05Z<p>Mbrodersen: /* Events in Haskell */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application/architecture is an application/architecture that is driven by internal/external events. Most non-trivial applications/architectures (from Operating Systems to Web Servers and Enterprise applications) are event driven.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's warm up with a ''tiny'' toy event driven Haskell application.<br />
In this case, an event driven calculator that can add numbers and exit.<br />
Not very exciting but it is useful for introducing a number of key concepts.<br />
<br />
I will in the following use the term "Domain" to stand for the application state. Fell free to use "Shipping" instead of Domain if your application area is shipping or "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model].<br />
<br />
Here is the Domain for the calculator application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
data Domain =<br />
Domain Int<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
The calculator state simply keeps track of the current value.<br />
<br />
The next step is to define the events that the user can generate:<br />
<br />
<haskell><br />
data Event =<br />
EventAdd Int<br />
| EventExit<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
In this case all the user can do is to add and exit.<br />
<br />
With those two definition, we can now write the "domain update" function.<br />
It simply takes the current state of the domain and an event as input<br />
and outputs the updated domain:<br />
<br />
<haskell><br />
dmUpdate :: Domain -> Event -> Domain<br />
<br />
dmUpdate (Domain v) (EventAdd a) = Domain (v + a)<br />
<br />
dmUpdate dm _ = dm<br />
</haskell><br />
<br />
For this tiny toy example all we can do is to react to the EventAdd event<br />
and calculate the new value.<br />
<br />
The next step is to write the UI. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back (More on this later):<br />
<br />
<haskell><br />
uiUpdate :: Domain -> IO [Event]<br />
<br />
uiUpdate (Domain v) = do<br />
putStrLn $ "Value is now: " ++ show v<br />
if v < 3 then<br />
return [EventAdd 1]<br />
else<br />
return [EventExit]<br />
</haskell><br />
<br />
For this tiny toy example the UI will not even read from stdin.<br />
It instead return EventAdd events until the Domain state value is >= 3.<br />
After which it generates the EventExit event. Yes it is just a tiny toy example :-)<br />
<br />
Given ''dmUpdate'' and ''uiUpdate'' we can now write what is traditionally called the "Event Loop". The event loop is the beating heart of an event driven application:<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run _ (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (dmUpdate dm e) es<br />
</haskell><br />
<br />
For this tiny toy example, the event loop simply asks the UI for new events.<br />
And updates the domain when events are available. It exits when EventExit is received from the UI.<br />
<br />
And here is the main function to bootstrap the event loop:<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run (Domain 0) []<br />
</haskell><br />
<br />
''main'' simply creates a new domain (Domain 0) and calls ''run'' with an empty event list to get started.<br />
<br />
The result of running the application is:<br />
<br />
<haskell><br />
Value is now: 0<br />
Value is now: 1<br />
Value is now: 2<br />
Value is now: 3<br />
</haskell><br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However a number of key choices have been made that will profoundly shape how the application scales from this tiny application to "Enterprise" level:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
Events can (should) be ''asynchronous''.<br />
<br />
And by the way, this is ''not'' MVC/MVP as will be shown later :-)<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring (Dashboard)<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server (Haste etc.)<br />
* Humble "File in Directory" Events<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58528Real World Applications/Event Driven Applications2014-07-04T08:49:43Z<p>Mbrodersen: /* Events in Haskell */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application/architecture is an application/architecture that is driven by internal/external events. Most non-trivial applications/architectures (from Operating Systems to Web Servers and Enterprise applications) are event driven.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><code><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</code></haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's warm up with a ''tiny'' toy event driven Haskell application.<br />
In this case, an event driven calculator that can add numbers and exit.<br />
Not very exciting but it is useful for introducing a number of key concepts.<br />
<br />
I will in the following use the term "Domain" to stand for the application state. Fell free to use "Shipping" instead of Domain if your application area is shipping or "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model].<br />
<br />
Here is the Domain for the calculator application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
data Domain =<br />
Domain Int<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
The calculator state simply keeps track of the current value.<br />
<br />
The next step is to define the events that the user can generate:<br />
<br />
<haskell><br />
data Event =<br />
EventAdd Int<br />
| EventExit<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
In this case all the user can do is to add and exit.<br />
<br />
With those two definition, we can now write the "domain update" function.<br />
It simply takes the current state of the domain and an event as input<br />
and outputs the updated domain:<br />
<br />
<haskell><br />
dmUpdate :: Domain -> Event -> Domain<br />
<br />
dmUpdate (Domain v) (EventAdd a) = Domain (v + a)<br />
<br />
dmUpdate dm _ = dm<br />
</haskell><br />
<br />
For this tiny toy example all we can do is to react to the EventAdd event<br />
and calculate the new value.<br />
<br />
The next step is to write the UI. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back (More on this later):<br />
<br />
<haskell><br />
uiUpdate :: Domain -> IO [Event]<br />
<br />
uiUpdate (Domain v) = do<br />
putStrLn $ "Value is now: " ++ show v<br />
if v < 3 then<br />
return [EventAdd 1]<br />
else<br />
return [EventExit]<br />
</haskell><br />
<br />
For this tiny toy example the UI will not even read from stdin.<br />
It instead return EventAdd events until the Domain state value is >= 3.<br />
After which it generates the EventExit event. Yes it is just a tiny toy example :-)<br />
<br />
Given ''dmUpdate'' and ''uiUpdate'' we can now write what is traditionally called the "Event Loop". The event loop is the beating heart of an event driven application:<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run _ (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (dmUpdate dm e) es<br />
</haskell><br />
<br />
For this tiny toy example, the event loop simply asks the UI for new events.<br />
And updates the domain when events are available. It exits when EventExit is received from the UI.<br />
<br />
And here is the main function to bootstrap the event loop:<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run (Domain 0) []<br />
</haskell><br />
<br />
''main'' simply creates a new domain (Domain 0) and calls ''run'' with an empty event list to get started.<br />
<br />
The result of running the application is:<br />
<br />
<haskell><br />
Value is now: 0<br />
Value is now: 1<br />
Value is now: 2<br />
Value is now: 3<br />
</haskell><br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However a number of key choices have been made that will profoundly shape how the application scales from this tiny application to "Enterprise" level:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
Events can (should) be ''asynchronous''.<br />
<br />
And by the way, this is ''not'' MVC/MVP as will be shown later :-)<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring (Dashboard)<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server (Haste etc.)<br />
* Humble "File in Directory" Events<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58527Real World Applications/Event Driven Applications2014-07-04T08:49:17Z<p>Mbrodersen: /* Events in Haskell */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application/architecture is an application/architecture that is driven by internal/external events. Most non-trivial applications/architectures (from Operating Systems to Web Servers and Enterprise applications) are event driven.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<code><haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell></code><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's warm up with a ''tiny'' toy event driven Haskell application.<br />
In this case, an event driven calculator that can add numbers and exit.<br />
Not very exciting but it is useful for introducing a number of key concepts.<br />
<br />
I will in the following use the term "Domain" to stand for the application state. Fell free to use "Shipping" instead of Domain if your application area is shipping or "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model].<br />
<br />
Here is the Domain for the calculator application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
data Domain =<br />
Domain Int<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
The calculator state simply keeps track of the current value.<br />
<br />
The next step is to define the events that the user can generate:<br />
<br />
<haskell><br />
data Event =<br />
EventAdd Int<br />
| EventExit<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
In this case all the user can do is to add and exit.<br />
<br />
With those two definition, we can now write the "domain update" function.<br />
It simply takes the current state of the domain and an event as input<br />
and outputs the updated domain:<br />
<br />
<haskell><br />
dmUpdate :: Domain -> Event -> Domain<br />
<br />
dmUpdate (Domain v) (EventAdd a) = Domain (v + a)<br />
<br />
dmUpdate dm _ = dm<br />
</haskell><br />
<br />
For this tiny toy example all we can do is to react to the EventAdd event<br />
and calculate the new value.<br />
<br />
The next step is to write the UI. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back (More on this later):<br />
<br />
<haskell><br />
uiUpdate :: Domain -> IO [Event]<br />
<br />
uiUpdate (Domain v) = do<br />
putStrLn $ "Value is now: " ++ show v<br />
if v < 3 then<br />
return [EventAdd 1]<br />
else<br />
return [EventExit]<br />
</haskell><br />
<br />
For this tiny toy example the UI will not even read from stdin.<br />
It instead return EventAdd events until the Domain state value is >= 3.<br />
After which it generates the EventExit event. Yes it is just a tiny toy example :-)<br />
<br />
Given ''dmUpdate'' and ''uiUpdate'' we can now write what is traditionally called the "Event Loop". The event loop is the beating heart of an event driven application:<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run _ (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (dmUpdate dm e) es<br />
</haskell><br />
<br />
For this tiny toy example, the event loop simply asks the UI for new events.<br />
And updates the domain when events are available. It exits when EventExit is received from the UI.<br />
<br />
And here is the main function to bootstrap the event loop:<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run (Domain 0) []<br />
</haskell><br />
<br />
''main'' simply creates a new domain (Domain 0) and calls ''run'' with an empty event list to get started.<br />
<br />
The result of running the application is:<br />
<br />
<haskell><br />
Value is now: 0<br />
Value is now: 1<br />
Value is now: 2<br />
Value is now: 3<br />
</haskell><br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However a number of key choices have been made that will profoundly shape how the application scales from this tiny application to "Enterprise" level:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
Events can (should) be ''asynchronous''.<br />
<br />
And by the way, this is ''not'' MVC/MVP as will be shown later :-)<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring (Dashboard)<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server (Haste etc.)<br />
* Humble "File in Directory" Events<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58526Real World Applications/Event Driven Applications2014-07-04T08:46:33Z<p>Mbrodersen: /* A Tiny Event Driven Haskell Application */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application/architecture is an application/architecture that is driven by internal/external events. Most non-trivial applications/architectures (from Operating Systems to Web Servers and Enterprise applications) are event driven.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's warm up with a ''tiny'' toy event driven Haskell application.<br />
In this case, an event driven calculator that can add numbers and exit.<br />
Not very exciting but it is useful for introducing a number of key concepts.<br />
<br />
I will in the following use the term "Domain" to stand for the application state. Fell free to use "Shipping" instead of Domain if your application area is shipping or "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model].<br />
<br />
Here is the Domain for the calculator application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
data Domain =<br />
Domain Int<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
The calculator state simply keeps track of the current value.<br />
<br />
The next step is to define the events that the user can generate:<br />
<br />
<haskell><br />
data Event =<br />
EventAdd Int<br />
| EventExit<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
In this case all the user can do is to add and exit.<br />
<br />
With those two definition, we can now write the "domain update" function.<br />
It simply takes the current state of the domain and an event as input<br />
and outputs the updated domain:<br />
<br />
<haskell><br />
dmUpdate :: Domain -> Event -> Domain<br />
<br />
dmUpdate (Domain v) (EventAdd a) = Domain (v + a)<br />
<br />
dmUpdate dm _ = dm<br />
</haskell><br />
<br />
For this tiny toy example all we can do is to react to the EventAdd event<br />
and calculate the new value.<br />
<br />
The next step is to write the UI. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back (More on this later):<br />
<br />
<haskell><br />
uiUpdate :: Domain -> IO [Event]<br />
<br />
uiUpdate (Domain v) = do<br />
putStrLn $ "Value is now: " ++ show v<br />
if v < 3 then<br />
return [EventAdd 1]<br />
else<br />
return [EventExit]<br />
</haskell><br />
<br />
For this tiny toy example the UI will not even read from stdin.<br />
It instead return EventAdd events until the Domain state value is >= 3.<br />
After which it generates the EventExit event. Yes it is just a tiny toy example :-)<br />
<br />
Given ''dmUpdate'' and ''uiUpdate'' we can now write what is traditionally called the "Event Loop". The event loop is the beating heart of an event driven application:<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run _ (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (dmUpdate dm e) es<br />
</haskell><br />
<br />
For this tiny toy example, the event loop simply asks the UI for new events.<br />
And updates the domain when events are available. It exits when EventExit is received from the UI.<br />
<br />
And here is the main function to bootstrap the event loop:<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run (Domain 0) []<br />
</haskell><br />
<br />
''main'' simply creates a new domain (Domain 0) and calls ''run'' with an empty event list to get started.<br />
<br />
The result of running the application is:<br />
<br />
<haskell><br />
Value is now: 0<br />
Value is now: 1<br />
Value is now: 2<br />
Value is now: 3<br />
</haskell><br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However a number of key choices have been made that will profoundly shape how the application scales from this tiny application to "Enterprise" level:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
Events can (should) be ''asynchronous''.<br />
<br />
And by the way, this is ''not'' MVC/MVP as will be shown later :-)<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring (Dashboard)<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server (Haste etc.)<br />
* Humble "File in Directory" Events<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58525Real World Applications/Event Driven Applications2014-07-04T08:45:30Z<p>Mbrodersen: /* A Tiny Event Driven Haskell Application */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application/architecture is an application/architecture that is driven by internal/external events. Most non-trivial applications/architectures (from Operating Systems to Web Servers and Enterprise applications) are event driven.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's warm up with a ''tiny'' toy event driven Haskell application.<br />
In this case, an event driven calculator that can add numbers and exit.<br />
Not very exciting but it is useful for introducing a number of key concepts.<br />
<br />
I will in the following use the term "Domain" to stand for the application state. Fell free to use "Shipping" instead of Domain if your application area is shipping or "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model].<br />
<br />
Here is the Domain for the calculator application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
data Domain =<br />
Domain Int<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
The calculator state simply keeps track of the current value.<br />
<br />
The next step is to define the events that the user can generate:<br />
<br />
<haskell><br />
data Event =<br />
EventAdd Int<br />
| EventExit<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
In this case all the user can do is to add and exit.<br />
<br />
With those two definition, we can now write the "domain update" function.<br />
It simply takes the current state of the domain and an event as input<br />
and outputs the updated domain:<br />
<br />
<haskell><br />
dmUpdate :: Domain -> Event -> Domain<br />
<br />
dmUpdate (Domain v) (EventAdd a) = Domain (v + a)<br />
<br />
dmUpdate dm _ = dm<br />
</haskell><br />
<br />
For this tiny toy example all we can do is to react to the EventAdd event<br />
and calculate the new value.<br />
<br />
The next step is to write the UI. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back (More on this later):<br />
<br />
<haskell><br />
uiUpdate :: Domain -> IO [Event]<br />
<br />
uiUpdate (Domain v) = do<br />
putStrLn $ "Value is now: " ++ show v<br />
if v < 3 then<br />
return [EventAdd 1]<br />
else<br />
return [EventExit]<br />
</haskell><br />
<br />
For this tiny toy example the UI will not even read from stdin.<br />
It instead return EventAdd events until the Domain state value is >= 3.<br />
After which it generates the EventExit event. Yes it is just a tiny toy example :-)<br />
<br />
Given ''uiUpdate'' to show the current domain state and to generate events, we can now write the "Event Loop". The event loop is the beating heart of an event driven application:<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run _ (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (dmUpdate dm e) es<br />
</haskell><br />
<br />
For this tiny toy example, the event loop simply asks the UI for new events.<br />
And updates the domain when events are available. It exits when EventExit is received from the UI.<br />
<br />
And here is the main function to bootstrap the event loop:<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run (Domain 0) []<br />
</haskell><br />
<br />
''main'' simply creates a new domain (Domain 0) and calls ''run'' with an empty event list to get started.<br />
<br />
The result of running the application is:<br />
<br />
<haskell><br />
Value is now: 0<br />
Value is now: 1<br />
Value is now: 2<br />
Value is now: 3<br />
</haskell><br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However a number of key choices have been made that will profoundly shape how the application scales from this tiny application to "Enterprise" level:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
Events can (should) be ''asynchronous''.<br />
<br />
And by the way, this is ''not'' MVC/MVP as will be shown later :-)<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring (Dashboard)<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server (Haste etc.)<br />
* Humble "File in Directory" Events<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58524Real World Applications/Event Driven Applications2014-07-04T08:43:23Z<p>Mbrodersen: /* A Tiny Event Driven Haskell Application */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application/architecture is an application/architecture that is driven by internal/external events. Most non-trivial applications/architectures (from Operating Systems to Web Servers and Enterprise applications) are event driven.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's warm up with a ''tiny'' toy event driven Haskell application.<br />
In this case, an event driven calculator that can add numbers and exit.<br />
Not very exciting but it is useful for introducing a number of key concepts.<br />
<br />
I will in the following use the term "Domain" to stand for the application state. Fell free to use "Shipping" instead of Domain if your application area is shipping or "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model].<br />
<br />
Here is the Domain for the calculator application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
data Domain =<br />
Domain Int<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
The calculator state simply keeps track of the current value.<br />
<br />
The next step is to define the events that the user can generate:<br />
<br />
<haskell><br />
data Event =<br />
EventAdd Int<br />
| EventExit<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
In this case all the user can do is to add and exit.<br />
<br />
With those two definition, we can now write the "domain update" function.<br />
It simply takes the current state of the domain and an event as input<br />
and outputs the updated domain:<br />
<br />
<haskell><br />
dmUpdate :: Domain -> Event -> Domain<br />
<br />
dmUpdate (Domain v) (EventAdd a) = Domain (v + a)<br />
<br />
dmUpdate dm _ = dm<br />
</haskell><br />
<br />
For this tiny toy example all we can do is to react to the EventAdd event<br />
and calculate the new value.<br />
<br />
The next step is to write the UI. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back (More on this later):<br />
<br />
<haskell><br />
uiUpdate :: Domain -> IO [Event]<br />
<br />
uiUpdate (Domain v) = do<br />
putStrLn $ "Value is now: " ++ show v<br />
if v < 3 then<br />
return [EventAdd 1]<br />
else<br />
return [EventExit]<br />
</haskell><br />
<br />
For this tiny toy example the UI will not even read from stdin.<br />
It instead will generate EventAdd events until the Domain state value is >= 3 and then generate the EventExit event. Yes it is just a tiny toy example :-)<br />
<br />
Given ''uiUpdate'' to show the current domain state and to generate events, we can now write the "Event Loop". The event loop is the beating heart of an event driven application:<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run _ (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (dmUpdate dm e) es<br />
</haskell><br />
<br />
For this tiny toy example, the event loop simply asks the UI for new events.<br />
And updates the domain when events are available. It exits when EventExit is received from the UI.<br />
<br />
And here is the main function to bootstrap the event loop:<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run (Domain 0) []<br />
</haskell><br />
<br />
''main'' simply creates a new domain (Domain 0) and calls ''run'' with an empty event list to get started.<br />
<br />
The result of running the application is:<br />
<br />
<haskell><br />
Value is now: 0<br />
Value is now: 1<br />
Value is now: 2<br />
Value is now: 3<br />
</haskell><br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However a number of key choices have been made that will profoundly shape how the application scales from this tiny application to "Enterprise" level:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
Events can (should) be ''asynchronous''.<br />
<br />
And by the way, this is ''not'' MVC/MVP as will be shown later :-)<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring (Dashboard)<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server (Haste etc.)<br />
* Humble "File in Directory" Events<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58523Real World Applications/Event Driven Applications2014-07-04T08:42:06Z<p>Mbrodersen: Major rewrite</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application/architecture is an application/architecture that is driven by internal/external events. Most non-trivial applications/architectures (from Operating Systems to Web Servers and Enterprise applications) are event driven.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's warm up with a ''tiny'' toy event driven Haskell application.<br />
In this case, an event driven calculator that can add numbers and exit.<br />
Not very exciting but it is useful for introducing a number of key concepts.<br />
<br />
I will in the following use the term "Domain" to stand for the application state. Fell free to use "Shipping" instead of Domain if your application area is shipping or "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model].<br />
<br />
Here is the Domain for the calculator application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
data Domain =<br />
Domain Int<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
The calculator state simply keeps track of the current value.<br />
<br />
The next step is to define the events that the user generates:<br />
<br />
<haskell><br />
data Event =<br />
EventAdd Int<br />
| EventExit<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
In this case all the user can do is to add and exit.<br />
<br />
With those two definition, we can now write the "domain update" function.<br />
It simply takes the current state of the domain and an event as input<br />
and outputs the updated domain:<br />
<br />
<haskell><br />
dmUpdate :: Domain -> Event -> Domain<br />
<br />
dmUpdate (Domain v) (EventAdd a) = Domain (v + a)<br />
<br />
dmUpdate dm _ = dm<br />
</haskell><br />
<br />
For this tiny toy example all we can do is to react to the EventAdd event<br />
and calculate the new value.<br />
<br />
The next step is to write the UI. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back (More on this later):<br />
<br />
<haskell><br />
uiUpdate :: Domain -> IO [Event]<br />
<br />
uiUpdate (Domain v) = do<br />
putStrLn $ "Value is now: " ++ show v<br />
if v < 3 then<br />
return [EventAdd 1]<br />
else<br />
return [EventExit]<br />
</haskell><br />
<br />
For this tiny toy example the UI will not even read from stdin.<br />
It instead will generate EventAdd events until the Domain state value is >= 3 and then generate the EventExit event. Yes it is just a tiny toy example :-)<br />
<br />
Given ''uiUpdate'' to show the current domain state and to generate events, we can now write the "Event Loop". The event loop is the beating heart of an event driven application:<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run _ (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (dmUpdate dm e) es<br />
</haskell><br />
<br />
For this tiny toy example, the event loop simply asks the UI for new events.<br />
And updates the domain when events are available. It exits when EventExit is received from the UI.<br />
<br />
And here is the main function to bootstrap the event loop:<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run (Domain 0) []<br />
</haskell><br />
<br />
''main'' simply creates a new domain (Domain 0) and calls ''run'' with an empty event list to get started.<br />
<br />
The result of running the application is:<br />
<br />
<haskell><br />
Value is now: 0<br />
Value is now: 1<br />
Value is now: 2<br />
Value is now: 3<br />
</haskell><br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However a number of key choices have been made that will profoundly shape how the application scales from this tiny application to "Enterprise" level:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
Events can (should) be ''asynchronous''.<br />
<br />
And by the way, this is ''not'' MVC/MVP as will be shown later :-)<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring (Dashboard)<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server (Haste etc.)<br />
* Humble "File in Directory" Events<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58522Real World Applications/Event Driven Applications2014-07-04T08:23:33Z<p>Mbrodersen: Changed tiny code example</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application/architecture is an application/architecture that is driven by internal/external events. Most non-trivial applications/architectures (from Operating Systems to Web Servers and Enterprise applications) are event driven.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's warm up with a ''tiny'' toy event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
</haskell><br />
<br />
<haskell><br />
data Domain = Domain Int deriving(Eq,Show)<br />
</haskell><br />
<br />
<haskell><br />
data Event =<br />
EventAdd Int<br />
| EventExit<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
<haskell><br />
dmUpdate :: Domain -> Event -> Domain<br />
</haskell><br />
<br />
<haskell><br />
dmUpdate (Domain v) (EventAdd a) = Domain (v + a)<br />
<br />
dmUpdate dm _ = dm<br />
</haskell><br />
<br />
<haskell><br />
uiUpdate :: Domain -> IO [Event]<br />
</haskell><br />
<br />
<haskell><br />
uiUpdate (Domain v) = do<br />
putStrLn $ "Value is now: " ++ show v<br />
if v < 3 then<br />
return [EventAdd 1]<br />
else<br />
return [EventExit]<br />
</haskell><br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
</haskell><br />
<br />
<haskell><br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
</haskell><br />
<br />
<haskell><br />
run _ (EventExit:_) =<br />
return ()<br />
</haskell><br />
<br />
<haskell><br />
run dm (e:es) =<br />
run (dmUpdate dm e) es<br />
</haskell><br />
<br />
<haskell><br />
main :: IO ()<br />
main = run (Domain 0) []<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
The main function simply starts the event loop (run):<br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However a number of key choices have been made that will profoundly shape how the application scales from this tiny application to "Enterprise" level:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
Events can (should) be ''asynchronous''.<br />
<br />
And by the way, this is ''not'' MVC/MVP as will be shown later :-)<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring (Dashboard)<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server (Haste etc.)<br />
* Humble "File in Directory" Events<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58513Real World Applications/Event Driven Applications2014-07-02T14:21:45Z<p>Mbrodersen: /* Growing the Application */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application/architecture is an application/architecture that is driven by internal/external events. Most non-trivial applications/architectures (from Operating Systems to Web Servers and Enterprise applications) are event driven.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's warm up with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However a number of key choices have been made that will profoundly shape how the application scales from this tiny application to "Enterprise" level:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
Events can (should) be ''asynchronous''.<br />
<br />
And by the way, this is ''not'' MVC/MVP as will be shown later :-)<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring (Dashboard)<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server (Haste etc.)<br />
* Humble "File in Directory" Events<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58512Real World Applications/Event Driven Applications2014-07-02T14:20:31Z<p>Mbrodersen: /* Consequences */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application/architecture is an application/architecture that is driven by internal/external events. Most non-trivial applications/architectures (from Operating Systems to Web Servers and Enterprise applications) are event driven.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's warm up with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However a number of key choices have been made that will profoundly shape how the application scales from this tiny application to "Enterprise" level:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
Events can (should) be ''asynchronous''.<br />
<br />
And by the way, this is ''not'' MVC/MVP as will be shown later :-)<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring (Dashboard)<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server<br />
* Humble "File in Directory" Events<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58511Real World Applications/Event Driven Applications2014-07-02T14:13:47Z<p>Mbrodersen: /* A Tiny Event Driven Haskell Application */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application/architecture is an application/architecture that is driven by internal/external events. Most non-trivial applications/architectures (from Operating Systems to Web Servers and Enterprise applications) are event driven.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's warm up with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However a number of key choices have been made that will profoundly shape how the application scales from this tiny application to "Enterprise" level:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
And by the way, this is ''not'' MVC/MVP as will be shown later :-)<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring (Dashboard)<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server<br />
* Humble "File in Directory" Events<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58510Real World Applications/Event Driven Applications2014-07-02T14:11:37Z<p>Mbrodersen: /* Introduction */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application/architecture is an application/architecture that is driven by internal/external events. Most non-trivial applications/architectures (from Operating Systems to Web Servers and Enterprise applications) are event driven.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However a number of key choices have been made that will profoundly shape how the application scales from this tiny application to "Enterprise" level:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
And by the way, this is ''not'' MVC/MVP as will be shown later :-)<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring (Dashboard)<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server<br />
* Humble "File in Directory" Events<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications&diff=58509Real World Applications2014-07-02T14:09:00Z<p>Mbrodersen: /* Event Driven Applications */</p>
<hr />
<div>== Introduction ==<br />
<br />
It is not always clear how to scale up from small "batch oriented" Haskell applications to large scale "Real World/Enterprise" Haskell systems. In other words, how to create large-scale systems that support complex business processes, information flows, reporting, data analytics etc. using Haskell.<br />
<br />
The following articles show how to attack this problem.<br />
<br />
== Event Driven Applications ==<br />
<br />
An event driven application/architecture is an application/architecture that is driven by internal/external events. Most non-trivial applications/architectures (from Operating Systems to Web Servers and Enterprise applications) are event driven.<br />
<br />
Read this: [[/Event Driven Applications/]]<br />
<br />
== Your Contribution Here ==<br />
<br />
Please contribute additional/alternative ways to structure large scale Haskell applications here.<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications&diff=58508Real World Applications2014-07-02T14:08:36Z<p>Mbrodersen: /* Event Driven Applications */</p>
<hr />
<div>== Introduction ==<br />
<br />
It is not always clear how to scale up from small "batch oriented" Haskell applications to large scale "Real World/Enterprise" Haskell systems. In other words, how to create large-scale systems that support complex business processes, information flows, reporting, data analytics etc. using Haskell.<br />
<br />
The following articles show how to attack this problem.<br />
<br />
== Event Driven Applications ==<br />
<br />
An event driven application/architecture is an application/architecture that is driven by internal/external events. Most non-trivial applications/architectures (from Operating Systems to Web Servers and Enterprise applications) are event driven.<br />
<br />
More here: [[/Event Driven Applications/]]<br />
<br />
== Your Contribution Here ==<br />
<br />
Please contribute additional/alternative ways to structure large scale Haskell applications here.<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications&diff=58507Real World Applications2014-07-02T14:08:09Z<p>Mbrodersen: /* Event Driven Applications */</p>
<hr />
<div>== Introduction ==<br />
<br />
It is not always clear how to scale up from small "batch oriented" Haskell applications to large scale "Real World/Enterprise" Haskell systems. In other words, how to create large-scale systems that support complex business processes, information flows, reporting, data analytics etc. using Haskell.<br />
<br />
The following articles show how to attack this problem.<br />
<br />
== Event Driven Applications ==<br />
<br />
An event driven application/architecture is an application/architecture that is driven by internal/external events. Most non-trivial applications/architectures (from Operating Systems to Enterprise applications) are event driven.<br />
<br />
More here: [[/Event Driven Applications/]]<br />
<br />
== Your Contribution Here ==<br />
<br />
Please contribute additional/alternative ways to structure large scale Haskell applications here.<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications&diff=58506Real World Applications2014-07-02T14:05:58Z<p>Mbrodersen: /* Event Driven Applications */</p>
<hr />
<div>== Introduction ==<br />
<br />
It is not always clear how to scale up from small "batch oriented" Haskell applications to large scale "Real World/Enterprise" Haskell systems. In other words, how to create large-scale systems that support complex business processes, information flows, reporting, data analytics etc. using Haskell.<br />
<br />
The following articles show how to attack this problem.<br />
<br />
== Event Driven Applications ==<br />
<br />
An event driven application/architecture is an application/architecture that is driven by internal/external events.<br />
<br />
More here: [[/Event Driven Applications/]]<br />
<br />
== Your Contribution Here ==<br />
<br />
Please contribute additional/alternative ways to structure large scale Haskell applications here.<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58505Real World Applications/Event Driven Applications2014-07-02T14:05:16Z<p>Mbrodersen: /* Introduction */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application/architecture is an application/architecture that is driven by internal/external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However a number of key choices have been made that will profoundly shape how the application scales from this tiny application to "Enterprise" level:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
And by the way, this is ''not'' MVC/MVP as will be shown later :-)<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring (Dashboard)<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server<br />
* Humble "File in Directory" Events<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications&diff=58504Real World Applications2014-07-02T14:03:28Z<p>Mbrodersen: /* Event Driven Applications */</p>
<hr />
<div>== Introduction ==<br />
<br />
It is not always clear how to scale up from small "batch oriented" Haskell applications to large scale "Real World/Enterprise" Haskell systems. In other words, how to create large-scale systems that support complex business processes, information flows, reporting, data analytics etc. using Haskell.<br />
<br />
The following articles show how to attack this problem.<br />
<br />
== Event Driven Applications ==<br />
<br />
An event driven application/system is here defined to be an application/system that reacts to internal/external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
More here: [[/Event Driven Applications/]]<br />
<br />
== Your Contribution Here ==<br />
<br />
Please contribute additional/alternative ways to structure large scale Haskell applications here.<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58503Real World Applications/Event Driven Applications2014-07-02T14:02:51Z<p>Mbrodersen: /* Introduction */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to internal/external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However a number of key choices have been made that will profoundly shape how the application scales from this tiny application to "Enterprise" level:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
And by the way, this is ''not'' MVC/MVP as will be shown later :-)<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring (Dashboard)<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server<br />
* Humble "File in Directory" Events<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications&diff=58502Real World Applications2014-07-02T14:02:19Z<p>Mbrodersen: /* Event Driven Applications */</p>
<hr />
<div>== Introduction ==<br />
<br />
It is not always clear how to scale up from small "batch oriented" Haskell applications to large scale "Real World/Enterprise" Haskell systems. In other words, how to create large-scale systems that support complex business processes, information flows, reporting, data analytics etc. using Haskell.<br />
<br />
The following articles show how to attack this problem.<br />
<br />
== Event Driven Applications ==<br />
<br />
An event driven application/system is here defined to be an application/system that reacts to internal/external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
More here: [[/Event Driven Applications/]]<br />
<br />
== Your Contribution Here ==<br />
<br />
Please contribute additional/alternative ways to structure large scale Haskell applications here.<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications&diff=58501Real World Applications2014-07-02T14:00:20Z<p>Mbrodersen: /* Introduction */</p>
<hr />
<div>== Introduction ==<br />
<br />
It is not always clear how to scale up from small "batch oriented" Haskell applications to large scale "Real World/Enterprise" Haskell systems. In other words, how to create large-scale systems that support complex business processes, information flows, reporting, data analytics etc. using Haskell.<br />
<br />
The following articles show how to attack this problem.<br />
<br />
== Event Driven Applications ==<br />
<br />
An event driven application/system is here defined to be an application/system that reacts to external events.<br />
<br />
Examples would be:<br />
<br />
* A text editor that reacts to user events (key pressed, mouse moved).<br />
* A web server reacting to IO events (message arrived, image compression done).<br />
* A commercial game reacting to simulated physics events and user input.<br />
* A report ready for distribution.<br />
* A loan application having been accepted.<br />
<br />
More here: [[/Event Driven Applications/]]<br />
<br />
== Your Contribution Here ==<br />
<br />
Please contribute additional/alternative ways to structure large scale Haskell applications here.<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications&diff=58500Real World Applications2014-07-02T14:00:03Z<p>Mbrodersen: /* Introduction */</p>
<hr />
<div>== Introduction ==<br />
<br />
It is not always clear how to scale up from small "batch oriented" Haskell applications to large scale "Real World/Enterprise" Haskell systems. In other words, how to create large-scale systems that support complex business processes, information flows, reporting, data analytics etc. using Haskell.<br />
<br />
The following articles show a number of different ways to attack this problem.<br />
<br />
== Event Driven Applications ==<br />
<br />
An event driven application/system is here defined to be an application/system that reacts to external events.<br />
<br />
Examples would be:<br />
<br />
* A text editor that reacts to user events (key pressed, mouse moved).<br />
* A web server reacting to IO events (message arrived, image compression done).<br />
* A commercial game reacting to simulated physics events and user input.<br />
* A report ready for distribution.<br />
* A loan application having been accepted.<br />
<br />
More here: [[/Event Driven Applications/]]<br />
<br />
== Your Contribution Here ==<br />
<br />
Please contribute additional/alternative ways to structure large scale Haskell applications here.<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications&diff=58499Real World Applications2014-07-02T13:59:49Z<p>Mbrodersen: /* Introduction */</p>
<hr />
<div>== Introduction ==<br />
<br />
It is not always clear how to scale up from small "batch oriented" Haskell applications to large scale "Real World/Enterprise" Haskell systems. In other words, how to create large-scale systems that support complex business processes, information flows, reporting, data analytics etc. using Haskell.<br />
<br />
The following articles shows a number of different ways to attack this problem.<br />
<br />
== Event Driven Applications ==<br />
<br />
An event driven application/system is here defined to be an application/system that reacts to external events.<br />
<br />
Examples would be:<br />
<br />
* A text editor that reacts to user events (key pressed, mouse moved).<br />
* A web server reacting to IO events (message arrived, image compression done).<br />
* A commercial game reacting to simulated physics events and user input.<br />
* A report ready for distribution.<br />
* A loan application having been accepted.<br />
<br />
More here: [[/Event Driven Applications/]]<br />
<br />
== Your Contribution Here ==<br />
<br />
Please contribute additional/alternative ways to structure large scale Haskell applications here.<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications&diff=58498Real World Applications2014-07-02T13:59:22Z<p>Mbrodersen: /* Introduction */</p>
<hr />
<div>== Introduction ==<br />
<br />
It is not always clear how to scale up from small "batch oriented" Haskell applications to large scale "Real World/Enterprise" Haskell systems. In other words, how to create large-scale systems that support complex business processes, information flows, reporting, data analytics etc. using Haskell.<br />
<br />
The following articles discuss different ways to attack this problem.<br />
<br />
== Event Driven Applications ==<br />
<br />
An event driven application/system is here defined to be an application/system that reacts to external events.<br />
<br />
Examples would be:<br />
<br />
* A text editor that reacts to user events (key pressed, mouse moved).<br />
* A web server reacting to IO events (message arrived, image compression done).<br />
* A commercial game reacting to simulated physics events and user input.<br />
* A report ready for distribution.<br />
* A loan application having been accepted.<br />
<br />
More here: [[/Event Driven Applications/]]<br />
<br />
== Your Contribution Here ==<br />
<br />
Please contribute additional/alternative ways to structure large scale Haskell applications here.<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58497Real World Applications/Event Driven Applications2014-07-02T13:58:02Z<p>Mbrodersen: /* Consequences */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However a number of key choices have been made that will profoundly shape how the application scales from this tiny application to "Enterprise" level:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
And by the way, this is ''not'' MVC/MVP as will be shown later :-)<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring (Dashboard)<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server<br />
* Humble "File in Directory" Events<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58496Real World Applications/Event Driven Applications2014-07-02T13:57:28Z<p>Mbrodersen: /* Consequences */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However a number of key choices have been made that will profoundly shape how the application scales from this tiny application to "Enterprise" level:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
And by the way, this is ''NOT'' MVC (more like Mediator) :-)<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring (Dashboard)<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server<br />
* Humble "File in Directory" Events<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58495Real World Applications/Event Driven Applications2014-07-02T13:56:29Z<p>Mbrodersen: /* Consequences */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However a number of key choices have been made that will profoundly shape how the application scales from this tiny application to "Enterprise" level:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring (Dashboard)<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server<br />
* Humble "File in Directory" Events<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58494Real World Applications/Event Driven Applications2014-07-02T13:55:21Z<p>Mbrodersen: /* Consequences */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However a number of key choices have been made that will profoundly shape how the application will scale from this tiny application to "Enterprise" level:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring (Dashboard)<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server<br />
* Humble "File in Directory" Events<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58493Real World Applications/Event Driven Applications2014-07-02T13:54:17Z<p>Mbrodersen: /* Growing the Application */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring (Dashboard)<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server<br />
* Humble "File in Directory" Events<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58492Real World Applications/Event Driven Applications2014-07-02T13:52:19Z<p>Mbrodersen: /* Growing the Application */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring<br />
* Automatic Server Scaling<br />
* Complex Event Processing<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58491Real World Applications/Event Driven Applications2014-07-02T13:51:16Z<p>Mbrodersen: /* Introduction */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale, high volume, distributed, fault tolerant "Enterprise" scale applications.<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring<br />
* Automatic Server Scaling<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58490Real World Applications/Event Driven Applications2014-07-02T13:48:36Z<p>Mbrodersen: /* Introduction */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse Management System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale "Enterprise" applications (dealing with high level, distributed, high volume, fault tolerant business events).<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring<br />
* Automatic Server Scaling<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58489Real World Applications/Event Driven Applications2014-07-02T13:48:16Z<p>Mbrodersen: /* Introduction */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A robot has reached its destination (Real Time Warehouse System).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale "Enterprise" applications (dealing with high level, distributed, high volume, fault tolerant business events).<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring<br />
* Automatic Server Scaling<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58488Real World Applications/Event Driven Applications2014-07-02T13:46:58Z<p>Mbrodersen: /* Growing the Application */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale "Enterprise" applications (dealing with high level, distributed, high volume, fault tolerant business events).<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read on:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring<br />
* Automatic Server Scaling<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58487Real World Applications/Event Driven Applications2014-07-02T13:46:24Z<p>Mbrodersen: /* Growing the Application */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale "Enterprise" applications (dealing with high level, distributed, high volume, fault tolerant business events).<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read this:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Performance Monitoring<br />
* Automatic Server Scaling<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58486Real World Applications/Event Driven Applications2014-07-02T13:45:52Z<p>Mbrodersen: /* Growing the Application */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale "Enterprise" applications (dealing with high level, distributed, high volume, fault tolerant business events).<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read this:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* (Multiple) Databases (Separating Online and Reporting)<br />
* Client/Server<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58485Real World Applications/Event Driven Applications2014-07-02T13:45:02Z<p>Mbrodersen: /* Growing the Application */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale "Enterprise" applications (dealing with high level, distributed, high volume, fault tolerant business events).<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read this:<br />
<br />
* Simple File Storage<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Databases<br />
* Client/Server<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58484Real World Applications/Event Driven Applications2014-07-02T13:43:18Z<p>Mbrodersen: /* A Tiny Event Driven Haskell Application */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale "Enterprise" applications (dealing with high level, distributed, high volume, fault tolerant business events).<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is what is traditionally called the "Event Loop". This is the beating heart of the application. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read this:<br />
<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Databases<br />
* Client/Server<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58483Real World Applications/Event Driven Applications2014-07-02T13:42:09Z<p>Mbrodersen: /* A Tiny Event Driven Haskell Application */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale "Enterprise" applications (dealing with high level, distributed, high volume, fault tolerant business events).<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- A (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is where everything happens. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read this:<br />
<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Databases<br />
* Client/Server<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58482Real World Applications/Event Driven Applications2014-07-02T13:41:37Z<p>Mbrodersen: /* Introduction */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale "Enterprise" applications (dealing with high level, distributed, high volume, fault tolerant business events).<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- The (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is where everything happens. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read this:<br />
<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Databases<br />
* Client/Server<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58481Real World Applications/Event Driven Applications2014-07-02T13:40:43Z<p>Mbrodersen: /* Introduction */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show a way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale "Enterprise" applications (dealing with high level business events).<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- The (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is where everything happens. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read this:<br />
<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Databases<br />
* Client/Server<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58480Real World Applications/Event Driven Applications2014-07-02T13:38:52Z<p>Mbrodersen: /* Introduction */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to all crew (Airline Management System).<br />
* An Illegal Trade Pattern has been detected (Trading Fraud Detection System).<br />
* A simulated car has hits another simulated car (Commercial Racing Game).<br />
* A HTML message has been received (Web Server).<br />
* A key has been pressed (Text Editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show one way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale "Enterprise" applications (dealing with high level business events).<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- The (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is where everything happens. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read this:<br />
<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Databases<br />
* Client/Server<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58479Real World Applications/Event Driven Applications2014-07-02T13:37:56Z<p>Mbrodersen: /* Introduction */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events are:<br />
<br />
* A Loan Application has been accepted/rejected (commercial business).<br />
* A new Rostering Schedule is ready for distribution to crew (airline system).<br />
* An Illegal Trade Pattern has been detected (fraud detection system).<br />
* A simulated car has hits another simulated car (commercial racing game).<br />
* A HTML message has been received (web server).<br />
* A key has been pressed (text editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show one way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale "Enterprise" applications (dealing with high level business events).<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- The (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is where everything happens. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read this:<br />
<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Databases<br />
* Client/Server<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58478Real World Applications/Event Driven Applications2014-07-02T13:36:21Z<p>Mbrodersen: /* Introduction */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events would be:<br />
<br />
* A loan application has been accepted/rejected (commercial business).<br />
* A new rostering schedule is ready for distribution to crew (airline system).<br />
* An illegal trade pattern has been detected (fraud detection system).<br />
* A simulated car has hits another simulated car (commercial racing game).<br />
* A HTML message has been received (web server).<br />
* A key has been pressed (text editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show one way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale "Enterprise" applications (dealing with high level business events).<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- The (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is where everything happens. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read this:<br />
<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Databases<br />
* Client/Server<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58477Real World Applications/Event Driven Applications2014-07-02T13:34:24Z<p>Mbrodersen: /* Growing the Application */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events would be:<br />
<br />
* A loan application has been accepted/rejected (commercial business).<br />
* A new rostering schedule is ready for distribution to crew (airline system).<br />
* A simulated car has hits another simulated car (commercial racing game).<br />
* A HTML message has been received (web server).<br />
* A key has been pressed (text editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show one way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale "Enterprise" applications (dealing with high level business events).<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- The (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is where everything happens. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read this:<br />
<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Databases<br />
* Client/Server<br />
* Reporting<br />
* Business Workflow<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58476Real World Applications/Event Driven Applications2014-07-02T13:33:57Z<p>Mbrodersen: /* Growing the Application */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events would be:<br />
<br />
* A loan application has been accepted/rejected (commercial business).<br />
* A new rostering schedule is ready for distribution to crew (airline system).<br />
* A simulated car has hits another simulated car (commercial racing game).<br />
* A HTML message has been received (web server).<br />
* A key has been pressed (text editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show one way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale "Enterprise" applications (dealing with high level business events).<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- The (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is where everything happens. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read this:<br />
<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Databases<br />
* Client/Server<br />
* Reporting<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
* Interop with non-Haskell applications<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58475Real World Applications/Event Driven Applications2014-07-02T13:32:57Z<p>Mbrodersen: /* Growing the Application */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events would be:<br />
<br />
* A loan application has been accepted/rejected (commercial business).<br />
* A new rostering schedule is ready for distribution to crew (airline system).<br />
* A simulated car has hits another simulated car (commercial racing game).<br />
* A HTML message has been received (web server).<br />
* A key has been pressed (text editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show one way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale "Enterprise" applications (dealing with high level business events).<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- The (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is where everything happens. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
So how do we grow this tiny application to "Enterprise" scale? Read this:<br />
<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Databases<br />
* Client/Server<br />
* Reporting<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58474Real World Applications/Event Driven Applications2014-07-02T13:31:59Z<p>Mbrodersen: /* Consequences */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events would be:<br />
<br />
* A loan application has been accepted/rejected (commercial business).<br />
* A new rostering schedule is ready for distribution to crew (airline system).<br />
* A simulated car has hits another simulated car (commercial racing game).<br />
* A HTML message has been received (web server).<br />
* A key has been pressed (text editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show one way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale "Enterprise" applications (dealing with high level business events).<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- The (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is where everything happens. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI.<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain.<br />
Try that with your average application.<br />
<br />
Domain is ''pure''.<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI.<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based.<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Databases<br />
* Client/Server<br />
* Reporting<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersenhttps://wiki.haskell.org/index.php?title=Real_World_Applications/Event_Driven_Applications&diff=58473Real World Applications/Event Driven Applications2014-07-02T13:31:26Z<p>Mbrodersen: /* Consequences */</p>
<hr />
<div>== Introduction ==<br />
<br />
An event driven application is an application that reacts to external events.<br />
<br />
Examples of events would be:<br />
<br />
* A loan application has been accepted/rejected (commercial business).<br />
* A new rostering schedule is ready for distribution to crew (airline system).<br />
* A simulated car has hits another simulated car (commercial racing game).<br />
* A HTML message has been received (web server).<br />
* A key has been pressed (text editor).<br />
<br />
The examples demonstrate that events can be anything from high level business events ("A loan application accepted/rejected") to low level events ("User pressed key").<br />
<br />
In the following, I will show one way to architecture a Haskell system so that it can scale from small "toy" applications (dealing with low level IO events) to large scale "Enterprise" applications (dealing with high level business events).<br />
<br />
Please note that the following is not the only way to attack the problem.<br />
So please contribute your (clearly superior of course) alternative way to do it here: [https://www.haskell.org/haskellwiki/Real_World_Applications Real World Applications]<br />
<br />
== Events in Haskell ==<br />
<br />
In the following, I define an "Event" to be a value describing something that has happened in the past.<br />
And yes this should really be called an "Event Notification" but life is too short :-)<br />
<br />
Here is a straightforward way to define Events in Haskell:<br />
<br />
<haskell><br />
data Event =<br />
EventUserExit -- User wants to exit<br />
| EventUserSave -- User wants to save<br />
| EventUserSaveAs String<br />
| EventUserUndo -- User wants to undo<br />
| EventUserRedo -- User wants to redo<br />
deriving(Eq,Show)<br />
</haskell><br />
<br />
Events can be high level or low level depending on how "low level" in the system you are operating.<br />
Within a UI sub-system the events are typically low level (key pressed, window closed).<br />
In a large scale distributed system the events are typically high level business events (EventCustomerCreated <details>).<br />
<br />
== A ''Tiny'' Event Driven Haskell Application ==<br />
<br />
Let's begin with a ''tiny'' event driven Haskell application:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Control.Monad (when)<br />
<br />
import Domain -- The (pure) "domain model" is defined here<br />
import Event -- The (pure) events<br />
import UI -- The (non-pure) UI (User Interface) is defined here<br />
</haskell><br />
<br />
I am here using the term "Domain" to abstract away from the actual application domain. Fell free to use "Shipping" instead of Domain if your application area is shipping containers and "Game" if your domain is a game application. More info here: [http://en.wikipedia.org/wiki/Domain_model Domain Model]<br />
<br />
The Event module defines the events that both the Domain module and the UI module need to agree on.<br />
<br />
The UI module contains some sort of User Interface. For now it doesn't really matter how the UI is implemented. All that matters is that it can somehow present the Domain to a user and get user events back. More on this later.<br />
<br />
<haskell><br />
main :: IO ()<br />
main = run newDomain []<br />
</haskell><br />
<br />
The main function simply starts the event loop (run):<br />
<br />
<haskell><br />
run :: Domain -> [Event] -> IO ()<br />
<br />
run dm [] = do<br />
events <- uiUpdate dm<br />
run dm events<br />
<br />
run dm (EventExit:_) =<br />
return ()<br />
<br />
run dm (e:es) =<br />
run (domainUpdate dm e) es<br />
</haskell><br />
<br />
"run" is where everything happens. The UI updates itself and returns one or more events. While there are still events to be processed, the domain will be updated one event at a time.<br />
<br />
== Consequences ==<br />
<br />
The tiny application above is simple. However the way it is structured profoundly shapes how the application will scale:<br />
<br />
UI depends on Domain - Domain does ''not'' depend on UI<br />
This is the complete opposite of how most applications are (wrongly) developed.<br />
<br />
UI can be swapped without changing Domain<br />
Try that with your average application.<br />
<br />
Domain is ''pure''<br />
All the goodness of functional programming.<br />
<br />
Domain can be tested without the UI<br />
No need to setup Database to test.<br />
<br />
The Domain API is ''Value'' based not ''API'' based<br />
Events can be queued, recorded, distributed and replayed.<br />
<br />
== Growing the Application ==<br />
<br />
* Logging<br />
* Testing<br />
* Crash Recovery<br />
* Undo/Redo<br />
* Time<br />
* UI<br />
* Databases<br />
* Client/Server<br />
* Reporting<br />
* Remove Control<br />
* Event Sourcing<br />
* Event Bus<br />
* Security (Event Pattern Based)<br />
<br />
== Questions and feedback ==<br />
<br />
If you have any questions or suggestions, feel free to [mailto:mb@mbrodersen.com mail] me.<br />
<br />
[[Category:Applications]]</div>Mbrodersen