Search code examples
shake-build-system

Using persistent services with Shake


We've got a Shake build system where some rules talk to a Postgres database, as a persistent background service. How can we use Shake to ensure that the service is started if required, and shut down after Shake completes?

In particular, we don't want to start the service if no rules make use of it, and if it is used, we don't want it started/stopped multiple times during the run.


Solution

  • One way to implement this pattern in Shake is:

    rules = do
        startService <- newCache $ \() -> do
            ... start the service here ...
            runAfter $ ... shut down the service here ...
    
        "*.txt" %> \out -> do
            startService ()
            ... use the service here ...
    

    We create a cached item called startService. Using newCache the operation will be performed at most once, only if required. We can start the service however makes sense (even potentially building the service first). We use runAfter to shut the service, which will be run after Shake completes its execution.

    To ensure the the service is available in any rule it is required we first call startService ().

    As a related feature, if you have a rule where you don't want a persistent service, but just to batch up operations, see the batch function.