How to allow for a slow-starting dependency service in systemd

Sometimes a service will start and fork - giving systemd the illusion that it's ready - even though it hasn't finished "warming up". In this particular instance I'm using ApacheDS to provide LDAP services. When this unit is started, checking "systemctl status apacheds" will show it's running, along with the single log line:

Apr 04 15:34:33 daisy systemd[1]: Started Apache Directory Server.

But...it's not serving yet. Until a port test (like "lsof -i :389" or "netstat -pan | grep :389 | grep LISTEN") reveals that there's an active listener there's no available LDAP.

Whether it should do so or not - this takes about 2 minutes to fully startup. My question isn't whether or not ApacheDS is broken or should be replaced - it's how to deal with slow initializing services in systemd.

Is there a way of putting such a test into systemd, either to tell it to wait until valid to show the apacheds service as started, or giving it as a pre-condition for dependent services, without having them simply fail and still refuse to start?

Here's a working test script:

#!/bin/bash
TRIES=30
WAIT=10

while /bin/netstat -an | /bin/grep \:10389 | /bin/grep LISTEN ; [ $? -ne 0 ]; do
    let TRIES-=1
    if [ $TRIES -gt 1 ]; then
            sleep $WAIT
    fi
done

Solution 1:

You can add an ExecStartPost=foo to the unit file where foo is a script that checks (and rechecks) until the service is available.

Edit: you may need to increase TimeoutStartSec as well. The default is 90s.