Skip to content

Commit 8b96112

Browse files
committed
Merge branch '2.3.x' into 2.4.x
Conflicts: grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/fork/ForkedGrailsProcess.groovy
2 parents cab2242 + 0f3a777 commit 8b96112

File tree

1 file changed

+76
-22
lines changed

1 file changed

+76
-22
lines changed

grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/fork/ForkedGrailsProcess.groovy

Lines changed: 76 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import org.codehaus.groovy.grails.cli.support.PluginPathDiscoverySupport
4343
abstract class ForkedGrailsProcess {
4444

4545
public static final String DEBUG_FORK = "grails.debug.fork"
46+
public static final String PARENT_PROCESS_PORT = "grails.fork.parent.process.port"
4647
public static final int DEFAULT_DAEMON_PORT = 8091
4748
public static final String DEFAULT_DEBUG_ARGS = "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"
4849

@@ -292,31 +293,41 @@ abstract class ForkedGrailsProcess {
292293
if (daemon && !connectedToDaemon) {
293294
GrailsConsole.instance.updateStatus("Running without daemon...")
294295
}
295-
String classpathString = getBoostrapClasspath(executionContext)
296-
String additionalClasspath = System.getProperty('GRAILS_ADDITIONAL_CLASSPATH')
297-
if(additionalClasspath) {
298-
classpathString = classpathString + File.pathSeparator + additionalClasspath
299-
}
300-
List<String> cmd = buildProcessCommand(executionContext, classpathString)
301296

302-
def processBuilder = new ProcessBuilder()
303-
processBuilder
304-
.directory(executionContext.getBaseDir())
305-
.redirectErrorStream(false)
306-
.command(cmd)
297+
ServerSocket parentAvailabilityServer = new ServerSocket(0)
298+
def parentPort = parentAvailabilityServer.localPort
299+
System.setProperty(PARENT_PROCESS_PORT, String.valueOf(parentPort))
307300

308-
def process = processBuilder.start()
301+
try {
302+
String classpathString = getBoostrapClasspath(executionContext)
303+
List<String> cmd = buildProcessCommand(executionContext, classpathString)
309304

310-
if (isForkingReserveEnabled()) {
311-
List<String> reserveCmd = buildProcessCommand(executionContext, classpathString, true)
312-
forkReserveProcess(reserveCmd, executionContext)
313-
}
314-
else if(shouldRunWithDaemon()) {
315-
GrailsConsole.instance.updateStatus("Starting daemon...")
316-
forkDaemon(executionContext)
317-
}
318305

319-
return attachOutputListener(process)
306+
def processBuilder = new ProcessBuilder()
307+
processBuilder
308+
.directory(executionContext.getBaseDir())
309+
.redirectErrorStream(false)
310+
.command(cmd)
311+
312+
def process = processBuilder.start()
313+
314+
if (isForkingReserveEnabled()) {
315+
List<String> reserveCmd = buildProcessCommand(executionContext, classpathString, true)
316+
forkReserveProcess(reserveCmd, executionContext)
317+
}
318+
else if(shouldRunWithDaemon()) {
319+
GrailsConsole.instance.updateStatus("Starting daemon...")
320+
forkDaemon(executionContext)
321+
}
322+
323+
return attachOutputListener(process)
324+
} finally {
325+
try {
326+
parentAvailabilityServer?.close()
327+
} catch (e) {
328+
// ignore
329+
}
330+
}
320331
}
321332
else {
322333
return null
@@ -478,6 +489,11 @@ abstract class ForkedGrailsProcess {
478489

479490
@CompileStatic
480491
protected List<String> buildProcessCommand(ExecutionContext executionContext, String classpathString, boolean isReserve = false, boolean isDaemon = false) {
492+
String additionalClasspath = System.getProperty('GRAILS_ADDITIONAL_CLASSPATH')
493+
if(additionalClasspath) {
494+
classpathString = classpathString + File.pathSeparator + additionalClasspath
495+
}
496+
481497
File tempFile = storeExecutionContext(executionContext)
482498
final javaHomeEnv = System.getenv("JAVA_HOME")
483499

@@ -501,7 +517,8 @@ abstract class ForkedGrailsProcess {
501517
cmd.addAll(["-Xmx${maxMemory}M".toString(), "-Xms${minMemory}M".toString()])
502518
if(!(System.getProperty("java.version") =~ /1.[89]./)) {
503519
cmd.add("-XX:MaxPermSize=${maxPerm}m".toString())
504-
}
520+
}
521+
cmd << "-D${PARENT_PROCESS_PORT}=${System.getProperty(PARENT_PROCESS_PORT)}".toString()
505522
cmd.addAll(["-Dgrails.fork.active=true",
506523
"-Dgrails.build.execution.context=${tempFile.canonicalPath}".toString(), "-cp", classpathString])
507524

@@ -744,9 +761,46 @@ abstract class ForkedGrailsProcess {
744761

745762
BuildSettingsHolder.settings = buildSettings
746763
configureFork(buildSettings)
764+
startParentPortMonitor()
765+
747766
buildSettings
748767
}
749768

769+
protected void startParentPortMonitor() {
770+
def parentProcessPort = System.getProperty(PARENT_PROCESS_PORT)
771+
if (parentProcessPort) {
772+
Thread.start {
773+
def portInt = parentProcessPort.toInteger()
774+
while (true) {
775+
sleep(15000)
776+
if (!isServerRunning(portInt)) {
777+
// parent process killed, so bail out too
778+
GrailsConsole.getInstance().addStatus("Parent process shutdown. Exiting...")
779+
System.exit(1)
780+
}
781+
}
782+
}
783+
}
784+
}
785+
786+
/**
787+
* @return Whether the server is running
788+
*/
789+
boolean isServerRunning(int port) {
790+
Socket socket = null
791+
try {
792+
socket = new Socket("localhost", port)
793+
return socket.isConnected()
794+
} catch (e) {
795+
return false
796+
}
797+
finally {
798+
try {
799+
socket?.close()
800+
} catch (Throwable e) {
801+
}
802+
}
803+
}
750804
protected void configureFork(BuildSettings buildSettings) {
751805
final runConfig = buildSettings.forkSettings.run
752806
if (runConfig instanceof Map)

0 commit comments

Comments
 (0)