How to make a blogger like application using HappS v0.9
HAppS is designed to eliminate as much of the drudgery and error
associated with building, updating, and scaling web apps as
possible. Follow the insructions below to build a web app quickly and
easily that scales to millions of users without downtime and that
you can change without downtime.
- Install required software
- GHC 6.6 or higher
- SearchPath
- darcs
- XSLT
You can use the very fast xsltproc which comes
default installed on most linux and mac distributions but only
supports xslt1.0 or Saxon 8.9 which
supports the much nicer XSLT2.0, but at least in the Java version has high startup
overhead. If you use saxon, code assumes java is on your path
and net.sf.saxon.Transform is on your Java claspath.
(it would be really nice if some wrote a saxon server so
java doesn't need to get invoked to style every page)
The actual code is using the new HAppS darcs repos
- http://happs.org/HAppS/HAppS-Data - marshalling haskell types to/from XML and pairs
- http://happs.org/HAppS/HAppS-IxSet - relational operations on haskell data types
- http://happs.org/HAppS/HAppS-State - ACID operations on your haskell state type
- http://happs.org/HAppS/HAppS-Server - HTTP, SMTP, and UDP server libraries
- http://happs.org/HAppS/HAppS-Util - Utility code shared by all these libs
- http://happs.org/HAppS/HAppS-Begin - Example app and skeleton from which to build your app
-
darcs get http://happs.org/HAppS/HAppS-Begin MyAppDir
In the new MyAppDir directory you should find:
- ./public: static files served to the public.
- ./xslt: the xslt files used to style outbound xml into html
- ./deploy: deployment scripts for your app
- ./haskell: haskell source for your app
- Main.hs: Dispatch code for your app including the HTTP hierarchy
- Types.hs: Types used by your app
- State.hs: Representation and query/update functions for
your application state. Typically a container for your
Types. There should also be a State dir with prior versions of your state from which you may need to migrate.
- Control.hs: IO used to interact with state
- HAppS.hs: A single module to import all of HAppS that you want
To start everything do:
cd MyAppDir
sp runhaskell -ihaskell haskell/Main.hs
Now you can access files in the directory on port 8000.
Use http://localhost:8000/. Also try
http://localhost:8000/index.html.
Add a -http-port=1234 to serve instead on 1234.
To get auto-restart going, darcs get HAppS-Deploy into the current directory and
run 'sh ./HAppS-Deploy/dev-start.sh', and see the documentation below.
TBD: Add a -fcgi-port=1234 to serve via fastcgi if you want to run
happs behind apache or lighttpd. (The FCGI lib is in
HAppS-Server. Someone just needs to hook this up.)
- Develop your app by modifying the code in this repo. It should provide
you with a good base. If you need to change the way things look, edit the xslt in
the xslt directory. Note: the repo defaults to using xslt1.0 because xsltproc
is default installed on most machines. We recommend using xslt2 if you want more elegance
and control of rendering.
- Migrations: As you modify your code you will want to change the shape of various types
involved with state. Use the example in State.hs so that you never end up with
serialized state that you can't migrate to the current version.
Note: this is very new code! be careful!
- Auto-restart: Automatically restart the app when you change the source.
As you develop you may want to see how things look. Use the function in deploy
to turn on auto-restart so you don't have to go through a whole compile cycle
every time you want to see what your app is doing.
dev-start.sh spawns off buildloop.sh and apploop.sh
buildloop.sh runs find to check for any files in ./haskell/ that are newer than the executable. If there are new files, it calls SearchPath to get the latest sources and rebuild the application.
If no sources are updated, ghc does not create a new binary.
The code in Daemonize.hs exits when the modification time of the compiled binary is later than the start time of the program.
apploop.sh is an infinite loop that calls the program again when it stops.
So when your sources change, searchpath pulls the updates and rebuilds, the program kills itself when it detects a new binary, and the apploop starts that new binary.
You can hit control-c twice to exit dev-start.sh and the subshells.
- TBDEverything below needs to be done.
- Deploy to staging servers
!!! only some of this is implemented
- Set upan ssh authorize key on a set of boxes that can run a process on port 80.
- Set up DNS load balancing on those boxes
- Make a .deploy/staging file enumerating the boxes
- sp runhaskell HAppS.Util.Deploy staging
!! add http-port and fcg-port if you are deploying in virtual host environments
!! experiment with modifying state and not handling the change and republishing
!! notice that you can an error message but staging continues to run
!! add some narrative about daemonize and how to use it
- Test Peformance as well as behavior !!! document
- Deploy to live
Same as with staging except use a live file instead of staging.
Note, that if you need more servers just add servers. HAppS takes care of
multimaster replication so everything stays in sync. !!! this will be working soon.
- Sharding your app if you are update bound. Replcating your servers
helps with reliability and scaling reads. If you have a lot of updates then
you need to shard. Basically this means telling happs how to split your state
by "subject". And then telling it which state commands have which subject.