(((•)))
tech.interfluidity.com
a notebook by steve randy waldman
→ See also top, archive, subscribe, drafts blog, interfluidity main
2023-08-30 ⇒

# Suppressing bloop for scala-cli managed services

I am a huge fan of scala-cli.

Among its many virtues, it reproduces the ergonomics of an interpreted language for compiled, super typesafe, Scala. (Java too!)

Recently, I've written custom services that I execute using `scala-cli run`, and then deploy directly as systemd units.

Here's a snippet of how I used to do this:

    ...

    [Service]
    Type=simple
    User=unify-rss
    Group=unify-rss
    WorkingDirectory=/home/unify-rss/development/gitproj/unify-rss
    ExecStart=scala-cli run main
    ...

I noticed, however, where I expected one long-running java process for a service's dedicated user, I ended up with two! In addition to my own application, a service called `bloop.Bloop` was running as well.

JVMs are not exactly lightweight, and I don't want double the fun when running a service.

bloop is a Scala build service that many different editors, build systems, and other tools use to efficiently, incrementally, compile and run scala code. It runs as a persistent background process, which external tools tools can trigger with commands to build or execute the codebase, recompiling only what is necessary given what has changed.

This is great for fast iteration during development, but unwieldy (and potentially increases a threat surface area) during deployment of persistent services.

Fortunately, `scala-cli`, you can turn `bloop` off. `scala-cli` then falls back to the plain old Scala compiler to rebuild your application. It retains its core ergonomics: You can edit, then run, without any sort of compile / assemble / publish ceremony. The first run after a change might take a bit longer than it would have with `bloop`.

Here is a snippet (slightly simplified) of my current systemd unit.

    ...

    [Service]
    Type=simple
    User=unify-rss
    Group=unify-rss
    WorkingDirectory=/home/unify-rss/development/gitproj/unify-rss
    ExecStart=scala-cli run --server=false main
    ...

Note the `--server=false` argument to `scala-cli run`.

Executing the service works just the same as before, rebuilding if necessary. But now no `bloop` service squanders precious server-side memory.

My application is small enough that the additional build time is not an issue. The only visible difference when running `scala-cli` is that, when `bloop` is enabled and something has changed, I would see a message like

    Compiling project (Scala 3.3.0, JVM)
    Compiled project (Scala 3.3.0, JVM)

With the `--server=false` flag gone (it defaults to true), that message disappears.

But changes still recompile, and everything works great.

Note: the `--server=false` argument has to come after the `run` subcommand. Otherwise...

    $ scala-cli --server=false run main
    [error]  run is not a scala-cli sub-command and it is not a valid path to an input file or directory.
    Try viewing the relevant help to see the list of available sub-commands and options.
      scala-cli --help

The error message is unhelpfully mistaken. `run` in fact is a valid `scala-cli` subcommand. But `--server` is not a valid command-line option to the base `scala-cli` command, it is a valid command-line option to `scala-cli run`.

    $ scala-cli --version
    Scala CLI version: 1.0.4
    Scala version (default): 3.3.0

← Getting started with HedgeDoc
↑↑↑
Taking control of podcasts via RSS →