@@ -7,6 +7,7 @@ import com.sun.jdi.VirtualMachine
77import com.sun.jdi.connect.AttachingConnector
88import kotlinx.coroutines.CoroutineScope
99import kotlinx.coroutines.Dispatchers
10+ import kotlinx.coroutines.delay
1011import kotlinx.coroutines.launch
1112import org.gradle.tooling.BuildLauncher
1213import org.gradle.tooling.GradleConnector
@@ -15,6 +16,8 @@ import org.gradle.tooling.events.problems.ProblemEvent
1516import org.gradle.tooling.events.task.TaskFinishEvent
1617import org.gradle.tooling.events.task.TaskStartEvent
1718import processing.app.Messages
19+ import kotlin.time.Duration.Companion.seconds
20+ import kotlin.time.TimeSource
1821
1922// TODO: Capture and filter gradle output
2023open abstract class GradleJob {
@@ -75,6 +78,7 @@ open abstract class GradleJob{
7578 when (event.descriptor.name) {
7679 " :run" -> {
7780 state.value = State .RUNNING
81+ Messages .log(" Start run" )
7882 }
7983 }
8084
@@ -99,22 +103,36 @@ open abstract class GradleJob{
99103
100104 private fun BuildLauncher.addDebugging (): BuildLauncher {
101105 this .addProgressListener(ProgressListener { event ->
102- if (event !is TaskStartEvent ) return @ProgressListener
103- if (event.descriptor.name != " :run" ) return @ProgressListener
106+ if (event !is TaskStartEvent ) return @ProgressListener
107+ if (event.descriptor.name != " :run" ) return @ProgressListener
104108
105- // TODO: Why doesn't the debugger attach if not run with a debugger itself?
106109 try {
107- Messages .log(" Attaching to VM" )
110+ val port = service?.debugPort.toString()
111+ Messages .log(" Attaching to VM $port " )
108112 val connector = Bootstrap .virtualMachineManager().allConnectors()
109113 .firstOrNull { it.name() == " com.sun.jdi.SocketAttach" }
110114 as AttachingConnector ?
111115 ? : throw IllegalStateException (" No socket attach connector found" )
112116 val args = connector.defaultArguments()
113- args[" port" ]?.setValue(service?.debugPort.toString())
114- val sketch = connector.attach(args)
115- vm.value = sketch
116- Messages .log(" Attached to VM: ${sketch.name()} " )
117- }catch (e: Exception ){
117+ args[" port" ]?.setValue(port)
118+
119+ // Try to attach the debugger, retrying if it fails
120+ scope.launch {
121+ val start = TimeSource .Monotonic .markNow()
122+ while (start.elapsedNow() < 10 .seconds) {
123+ try {
124+ val sketch = connector.attach(args)
125+ vm.value = sketch
126+ break
127+ Messages .log(" Attached to VM: ${sketch.name()} " )
128+ } catch (e: Exception ) {
129+ Messages .log(" Error while attaching to VM: ${e.message} ... Retrying" )
130+ }
131+ delay(250 )
132+ }
133+ if (vm.value == null ) throw IllegalStateException (" Failed to attach to VM after 10 seconds" )
134+ }
135+ } catch (e: Exception ) {
118136 Messages .log(" Error while attaching to VM: ${e.message} " )
119137 }
120138 })
0 commit comments