Normally, when a Gradle daemon becomes idle, it li...
# community-support
m
Normally, when a Gradle daemon becomes idle, it lingers for only 10s if another compatible daemon exists. Is there an easy way to bump up that particular 10s to say 10 minutes? Note, this 10s linger is a different parameter from the default 3h linger idle time. Alternatively, can I keep 10 compatible idle daemons, instead of just 1?
v
Are you sure that not the OS RAM is low, causing the daemon to be shut down?
m
I want to start 10+ microservices in IntelliJ, each in their own process with their own classpath. To do so, the IDE insists on using a daemon for each service, even when using Application RunConfigs. The startup is slow due to the need to spawn so many daemons, but it eventually works, meaning the desktop doesn't run out of RAM in the process. However, on stopping a service, its expensive daemon stops within 10s, so restarting a service is as costly as the initial start. This is not much of a problem when stopping/restarting 1 service, but it is a problem when stopping/restarting many/all. I'm looking for a way to have these expensive daemons linger for more than the 10s when compatible daemons exist. When using Gradle RunConfigs, I can trick the daemons to be incompatible by injecting a custom tmpdir in each, so that they die by the other longer idle linger setting. However, I can't run in debug mode and use breakpoints when using Gradle RunConfigs, so I'm trying to use Application RunConfigs instead.
v
Ah, hm, seems to not be configurable from a cursory look: https://github.com/gradle/gradle/blob/master/platforms/core-runtime/launcher/src/m[…]org/gradle/launcher/daemon/server/MasterExpirationStrategy.java If a compatible daemon is found, the daemon is expired after 10 seconds if it is not the most-recently used one.
So you probably have to ensure the daemons are not compatible by setting one of the immutable properties that causes a new daemon to be used like different memory settings.
m
Wouldn't it be possible to have a single build spawn the services? Or maybe not use Gradle to start them, but only to build the scripts to run them?
v
Single build spawning the services is probably problematic if you want targetedly start specific services from IDE and debug those services. The latter might work when turning off "Build and run using: Gradle" to "Build and run using: IntellliJ IDEA", and then configuring a "before launch" task to make Gradle build the code, but then you probably have the same problem regarding startup-time for the compilation part, and additionally have to make sure the startup configuration is the same Gradle would use.
m
My desired state is to have 10x services started, each in their own separate JVM process, with logs visible from the IDE, and possibly a subset of them with debug agents available, so that devs can use breakpoints. I'm trying to use the idea-ext plugin, configuring RunConfigs in Gradle buildscript, as more stable than committing IDE files. Initially, I tried individual per-service Gradle RunConfigs, there we get per-service daemons, I can make them non-idempotent (reducing restart time), but I can't use breakpoints. Actually, I hit some deeper issues, where starting in debug mode and pausing makes the IDE pause the Gradle daemon instead of the service, etc. I even managed to kill the daemon without killing the service, getting into an undesirable state where the IDE has no idea the service is running. Next, I tried to pivot to Application RunConfigs. Surprisingly, the IDE still uses Gradle to spawn each of those services, I don't know why they do that. Here, I can use breakpoints, but per OP, restarting is very expensive. I guess I can still try JarApplication RunConfigs to see if the IDE still spawns daemons, though I don't see why it would not. So, "single build spawning" is not really part of the target, but having the services run in isolated JVMs is. I know how to spawn the services from scripts, but once they are up, how can I make the IDE aware of them? I see the IDE also has RemoteJvmDebug RunConfigs (not in idea-ext), I suppose that could be used for attaching a debugger. But how could I simply have the logs flow into an IDE window if starting via external scripts.
v
where starting in debug mode and pausing makes the IDE pause the Gradle daemon instead of the service, etc.
Iirc you debug both by default, build script and actual project. And iirc there are two thing you could do. You could disable the Gradle debugging, so that only the actual project is debugged. Or you could configure IJ so that you get two debugger windows iirc. But I might also remember wrongly and it just changed at some point how it is displayed without option to configure it. 🤷‍♂️
Next, I tried to pivot to Application RunConfigs. Surprisingly, the IDE still uses Gradle to spawn each of those services, I don't know why they do that.
I told you why and how to change it above. 😉
I suppose that could be used for attaching a debugger. But how could I simply have the logs flow into an IDE window if starting via external scripts.
If you log into files, you can configure the run configuration to show these log files. If you only log to stdout, you cannot.
image.png
image.png
m
Surprisingly, I had better luck with JAR Application RC! Unlike Application RC, the former doesn't spawn a Gradle daemon unless it has a Gradle task as a before hook. So I can spawn 10x services without paying for 10x daemons, at the expense of using only external (Maven-like) consistency: The JAR Application will use whatever jar happens to be there, without any implicit (Gradle-like) up-to-date checks. In my use case, those checks are very expensive to the usability of the local env. FTR, I tried some of the "Gradle" options of Gradle RC mentioned in the thread above, such as unchecking "Debug Gradle scripts", checking or not checking "Run as test", but in none of the combinations do I see the debug agent JVM arg in the resulting service process. So for now, I think it's impossible to use breakpoints in the service when starting via a Gradle RC. I also tried "Build and run with: IJ" but that doesn't solve anything, starting 10x services still requires 10x daemons.
v
Surprisingly, I had better luck with JAR Application RC! Unlike Application RC, the former doesn't spawn a Gradle daemon unless it has a Gradle task as a before hook.
How is that surprising? That is just like it is. As I said, the "normal" application also does not spawn any Gradle daemons if you change the mentioned setting. Just normally Gradle knows better than IJ how to build and run things. But if you change that setting, it is like in former times and like when using JAR Application RC.
I also tried "Build and run with: IJ" but that doesn't solve anything, starting 10x services still requires 10x daemons
Well, then you obviously did it wrongly. 🙂 If you for example have a Gradle run configuration to start the service that setting of course is irrelevant.