See [the demo](https://github.com/jamesdabbs/yesod-worker-demo) for an example site with workers set up. # Usage ## Define your Job type ``` -- Up to you where this goes, so long as it's importable data AppJob = CountJob Int | UserJob ``` ## Include a queue in your foundation data type ``` -- Foundation.hs import Yesod.Worker (JobQueue, YesodWorker(..), defaultRunW) data App = App { settings :: AppConfig DefaultEnv Extra ... , appQueue :: JobQueue AppJob } ``` ## Specify how to run your jobs ``` -- Foundation.hs (provided you don't want to orphan the instance) instance YesodWorker App where type Job = AppJob queue = appQueue runW = defaultRunW persistConfig connPool -- Dummy implementations, obviously these would depend on your app perform (CountJob n) = void . forM [1..n] $ \k -> do lift . putStrLn . show $ k lift $ threadDelay 1000000 perform UserJob = do -- Note that you can run SQL using the `runW` helper n <- runW $ count ([] :: [Filter User]) lift . putStrLn $ "There are " ++ (show n) ++ " users" ``` ## Start the queue on app boot ``` -- Application.hs import Yesod.Worker (emptyQueue, spawnWorkers) makeFoundation conf = do ... q <- emptyQueue let foundation = App conf ... q spawnWorkers foundation ... ``` ## Queue up a job ``` import Yesod.Worker (enqueue) getWhateverR = do enqueue $ CountJob 10 ... ``` # TODO * Simplify installation? * Include job subsite for viewing queue and worker status * Swappable queue backends (for e.g. Redis) * Improve error handling / job failures / worker restarts * Allow multiple queues with customizable priority