Ctrl-c during running build also kills daemon

$ gradle -v

Gradle 2.4

Build time:   2015-05-05 08:09:24 UTC
Build number: none
Revision:     5c9c3bc20ca1c281ac7972643f1e2d190f2c943c

Groovy:       2.3.10
Ant:          Apache Ant(TM) version 1.9.4 compiled on April 29 2014
JVM:          1.8.0_40 (Oracle Corporation 25.40-b25)
OS:           Mac OS X 10.10.3 x86_64

A typical scenario for Spring Boot users is to launch the application using gradle bootRun. The build remains in a perpetually running state, e.g. you’ll see:

> Building 80% > :bootRun

until the application is killed, usually with a ^C.

If no Gradle Daemon had been running previously, one will see the typical message on first invocation of bootRun:

$ gradle bootRun
Starting a new Gradle Daemon for this build (subsequent builds will be faster).

However, when the bootRun task is killed via ^C, the associated GradleDaemon process gets killed as well. This is of course undesirable given subsequent gradle bootRun invocations must incur the overhead of launching a new daemon process.

A typical workflow is to run gradle bootRun, make changes to code, ^C and re-run gradle bootRun to pick up the new changes. Anyone developing a Spring Boot-based application would go through this cycle dozens of times per day, so the overhead of killing and re-creating the daemon is really felt. Indeed, this problem virtually eliminates the benefits of the daemon altogether.

I do not recall this being a problem until relatively recently. That is, I recall building Spring Boot-based applications in the past, and using gradle bootRun as described above without seeing the daemon process killed and re-launched on each invocation.

I thought this behavior might be new to Gradle 2.4, but upon reverting my build to Gradle 2.3, I see the same issue. What is different is that Gradle 2.4 emits the “Starting a new Gradle Daemon” message, whereas versions 2.3 and earlier did not. Perhaps this has always been a problem, and I’m just now “feeling” it simply because I see the message and know that it should not be so.

In any case, this seems like a bug. Can killing a running build be decoupled from killing its daemon?


1 Like

It’s always been this way “by design”, but we want to move away from it so the daemon isn’t killed so often. I think there are cases where we don’t propagate the ctrl+c, but that’s by luck.

If you look at what we’re doing for continuous mode in 2.5, we’re adding ctrl+d to exit the Gradle process without killing the daemon. We have a similar problem as bootRun with our Play application support (playRun), which uses the same mechanism (ctrl+d). I think we’ll eventually do something like this generically, but we need to provide an alternative way for existing build scripts to read stdin before we capture input all of the time.

Thanks, Sterling. Sending an alternative signal would be one way to go, although most folks will probably never discover that there’s an option to kill with ^C vs ^D.

Perhaps kill semantics could actually be passed along by the tasks themselves? i.e. the bootRun, playRun tasks set a property that informs the client not to propagate kill signals to the daemon? This would allow for a “works correctly out of the box” experience. This, in conjunction with the ^D support you mention would allow for quite a bit of flexibility.


@Chris_Beams at this stage, we don’t plan to change the semantics of ctrl-c (i.e. kill this build), but offer a separate mechanism for cancelling the build. You can already do this with the Tooling API, but we’re yet to expose this to the CLI. We made some steps towards this in 2.5, but there’s a few pieces to go.

We may end up coopting ctrl-c in the future to mean something like “try to cancel but kill if non responsive” but that’s not the plan right now.

Thanks, Luke. I suppose anything that’s reliable and convenient from the CLI will do. Let me know if there’s an issue I can follow.

Any progress here? This bug is pretty annoying.
I tried to use continuous build (to use ctrl-d as an interceptor), but it had no effect cause build in my case is actually never complete (I’m running finagle server with JavaExec task and my build always remains running in something like 81%)

I have this issue as well. Is this a normal use case for Gradle? I’m pretty new so I’m not too familiar how everything works but this is fairly annoying if you’re constantly building your project.

I’m having this same problem. It seems to make the daemon completely useless from the CLI. We’re 10 revisions since 2.5, and it seems no work has been done in this regard since? As soon as I ^C gradle bootRun it kills the daemon. ^D seems to have no effect on the running daemon. Also, most daemons exit once launched, but this on doesn’t seem to do that.

$ gradle -v

Gradle 2.14.1

Build time:   2016-07-18 06:38:37 UTC
Revision:     d9e2113d9fb05a5caabba61798bdb8dfdca83719

Groovy:       2.4.4
Ant:          Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM:          1.8.0_45 (Oracle Corporation 25.45-b02)
OS:           Mac OS X 10.11.6 x86_64

This issue has been fixed with Gradle 3.2-rc1. Would you mind giving it a shot? For reference please also see GRADLE-3083.

I’ve spoken with @bmuschko about this, and I’m not hopeful our recent changes will help in this specific case. What we have implemented for 3.2 is the solution described by Luke above - when ctrl-c is pressed, we attempt to cancel the build. This solution works for the vast majority of cases, but it does rely on build cancellation to be successful and one case where it isn’t successful is when the currently running task never completes (which is what is being described here). What will happen now is that we’ll receive the ctrl-c, try to cancel the build, the currently running task will not complete, and eventually we’ll just give up on it as we have no guarantee it will ever finish.

What we’ll need to do to fix this issue is improve build cancellation so that it can notify running tasks that the build has been canceled and that they should complete early. So in this case the “:bootRun” task would receive a notification and would stop what it’s doing, clean up, and finish, allowing the cancellation to be successful.

Unfortunately, I can’t move to 3.x. I’m using Spring-Boot, and it’s only compatible with 2.x.