Implementing exec task as daemon


I am attempting to implement a task that follows the ExecSpec, but rather than wait for the process to exit it should wait for a ready condition and proceed with build once ready. Ideally this process would remain active with the gradle daemon, baring that should cleanly exit at the end of the build.

I am most of the way there with this:

class DaemonExec extends AbstractExecTask<DaemonExec> implements ExecSpec {

    private final DaemonExecActionFactory execActionFactory = objectFactory.newInstance(DaemonExecActionFactory)

    private final DaemonExecAction execAction = execActionFactory.newDecoratedDaemonExecAction()

    private final Property<ExecResult> execResult =

    public DaemonExec() {


    protected ObjectFactory getObjectFactory() {
        throw new UnsupportedOperationException()
    void processReadyWhen(Closure<Boolean> closure) {

    protected void exec() {
class DefaultDaemonExecAction extends DefaultExecHandleBuilder implements ExecAction, DaemonExecAction {

    private static ExecResult waitForReady(final ExecHandle execHandle, final Closure<Boolean> readyCondition = null) {
        if(readyCondition) {
            final ReentrantLock lock = new ReentrantLock()
            final Condition stateChanged = lock.newCondition()

            try {
                //TODO stream stdout to readyCondition, unlock when returns true
                while (!execHandle.getState().isTerminal()) {
                    try {
                    } catch (InterruptedException e) {
                        throw UncheckedException.throwAsUncheckedException(e)
            } finally {

            //TODO we need to figure out how to return a valid 
            //     ExecResult which has not yet exited

        return execHandle.start().waitForFinish()

    private Closure<Boolean> readyCondition = null

    DefaultDaemonExecAction(PathToFileResolver fileResolver, Executor executor, BuildCancellationToken buildCancellationToken) {
        super(fileResolver, executor, buildCancellationToken)

    public ExecResult execute() {
        final ExecHandle execHandle = build()
        final ExecResult execResult = waitForReady(execHandle, readyCondition)
        // TODO defer assertion until process exits
        if (!isIgnoreExitValue()) {
        return execResult

    void readyWhen(Closure<Boolean> closure) {
        readyCondition = closure

So far so good, this works just like Exec when no readyCondition is used. The remaining implementation is uninteresting, but can be found at [1] if interested.

What is unclear to me is how I should go about returning an ExecResult from waitForReady, which has not yet exited. Is this even possible? I was hoping that by implementing the task in the same fashion as Exec I could piggyback off the gradle daemon to handle the process thread.

Any ideas how to achieve this, or am I just opening up a bunch of footguns?

Cheers, and thanks for your time!


[1] - Full Source