Skip to content

Instantly share code, notes, and snippets.

@nafg
Created September 26, 2023 21:34
Show Gist options
  • Save nafg/719d53a0807f7bcfcbc3481e5cc046d2 to your computer and use it in GitHub Desktop.
Save nafg/719d53a0807f7bcfcbc3481e5cc046d2 to your computer and use it in GitHub Desktop.
package kupasyomtov.igudbneitorah.scripts
import bleep.commands.Compile
import bleep.internal.{TransitiveProjects, jvmRunCommand}
import bleep.model.{CrossProjectName, ProjectName}
import bleep.{BleepFileWatching, BleepScript, Commands, FileWatching, PathOps, Started}
import java.io.File
import java.nio.file.Files
import scala.jdk.CollectionConverters.*
import scala.jdk.OptionConverters.RichOptional
object RunBg extends BleepScript("runBackground") {
override def run(started: Started, commands: Commands, args: List[String]): Unit = {
val projectName = "main"
val pidFile = started.buildPaths.buildsDir / s"$projectName.pid"
val project = CrossProjectName(ProjectName(projectName), None)
var process: Option[Process] = None
def terminateProcessHandle(p: ProcessHandle): Unit = {
val desc = s"[${p.pid()}] ${p.info().commandLine().orElse("")}"
val children = p.children().toList.asScala
p.destroy()
if (p.isAlive) {
println(s"Waiting for $desc to terminate")
val start = System.currentTimeMillis()
while (p.isAlive && System.currentTimeMillis() - start < 20000) {
Thread.sleep(100)
}
if (p.isAlive) {
println(s"Killing $desc")
p.destroyForcibly()
}
}
children.foreach(terminateProcessHandle)
}
def terminate(): Unit = {
val pid =
try
Option.when(Files.exists(pidFile)) {
Files.readString(pidFile).toInt
}
catch {
case e: Throwable =>
println(s"Error reading pid file $pidFile")
e.printStackTrace()
None
}
pid.flatMap(ProcessHandle.of(_).toScala).foreach(terminateProcessHandle)
process.foreach(p => terminateProcessHandle(p.toHandle))
}
def runApp(): Unit =
Compile(watch = false, Array(project)).run(started) match {
case Left(value) =>
value.printStackTrace()
case Right(()) =>
terminate()
println("here")
val value = jvmRunCommand(started.bloopProject(project), started.resolvedJvm, project, None, args)
value.left.foreach(_.printStackTrace())
val command = value.orThrow
// println(command.mkString(" "))
val p =
new ProcessBuilder(command*)
.directory(new File(sys.env("PWD")))
.inheritIO()
.start()
Files.writeString(pidFile, p.pid().toString)
process = Some(p)
}
val watcher = BleepFileWatching.projects(started, TransitiveProjects(started.build, Array(project))) { projects =>
println("changed: " + projects)
runApp()
}
try {
runApp()
watcher.run(FileWatching.StopWhen.OnStdInput)
} finally terminate()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment