Skip to content
This repository has been archived by the owner on Mar 20, 2021. It is now read-only.

Commit

Permalink
Merge pull request #20 from szeiger/wip/multiple-instances
Browse files Browse the repository at this point in the history
Allow multiple concurrent devbox instances
  • Loading branch information
szeiger committed Aug 19, 2020
2 parents e03acfb + 3a026bd commit 8c26aa0
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 37 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ To prepare an assembly jar, ready to be tested and deployed in the universe/
$ ./mill launcher.assembly
```

The result can be found in `out/launcher/assembly/dest/out.jar`

## Tests

To run all tests (takes a long time):
Expand Down
21 changes: 14 additions & 7 deletions devbox/src/DevboxMain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ object DevboxMain {

prepResult.exitCode == 0
},
connect
(_ => connect)
)
}
System.exit(0)
Expand All @@ -123,7 +123,7 @@ object DevboxMain {
throw e
}

def main0(urlOpt: Option[String], config: Config, prepareWithlogs: (String => Unit) => Boolean, connect: Seq[String]) = {
def main0(urlOpt: Option[String], config: Config, prepareWithlogs: (String => Unit) => Boolean, connect: Option[Int] => Seq[String]) = {
implicit val ac = new castor.Context.Test(
castor.Context.Simple.executionContext,
e => {
Expand Down Expand Up @@ -152,11 +152,12 @@ object DevboxMain {
implicit lazy val logger: devbox.logger.SyncLogger = new devbox.logger.SyncLogger.Impl(
n => logFileBase / s"$logFileName$n.$logFileExt",
50 * 1024 * 1024,
new castor.ProxyActor((_: Unit) => AgentReadWriteActor.ForceRestart(), syncer.agentActor)
new castor.ProxyActor((_: Unit) => AgentReadWriteActor.ForceRestart(), syncer.agentActor),
urlOpt.map(url => s"$url:")
)

lazy val syncer = new Syncer(
new ReliableAgent(
new ReliableAgent[Option[Int]](
log => {
val res = prepareWithlogs(log)
if (config.proxyGit) {
Expand All @@ -170,11 +171,17 @@ object DevboxMain {
s => os.home / ".devbox" / s"cmdproxy$s.log",
1024 * 1024,
)
server.foreach(_.socket.close())
server = Some(new ProxyServer(dirMapping))
var port = 0
server.foreach { s =>
val p = s.socket.getLocalPort
if(p > 0) port = p // make sure to rebind to same port
s.socket.close()
}
server = Some(new ProxyServer(dirMapping, port))
server.foreach(_.start())
}
res
if(res) Some(server.map(_.socket.getLocalPort))
else None
},
connect,
os.pwd
Expand Down
2 changes: 1 addition & 1 deletion devbox/src/cmdproxy/ProxyMain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ object ProxyMain {
1024 * 1024
)

new ProxyServer(dirMapping = Seq.empty)(logger).start()
new ProxyServer(dirMapping = Seq.empty, ProxyServer.DEFAULT_PORT)(logger).start()
}
}
2 changes: 1 addition & 1 deletion devbox/src/cmdproxy/ProxyServer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ object Request {
* the end of the output stream
*/
class ProxyServer(dirMapping: Seq[(os.Path, os.RelPath)],
port: Int = ProxyServer.DEFAULT_PORT)
port: Int)
(implicit logger: FileLogger) {

// this may throw when binding if the socket is used, but for the moment we just assume there is no other
Expand Down
9 changes: 6 additions & 3 deletions devbox/src/logger/SyncLogger.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ object SyncLogger{

class Impl(val dest: String => os.Path,
val rotationSize: Long,
onClick: => castor.Actor[Unit])
onClick: => castor.Actor[Unit],
titleOpt: Option[String])
(implicit ac: castor.Context) extends castor.SimpleActor[Msg] with SyncLogger {

def init() = this.send(Init())
Expand Down Expand Up @@ -67,7 +68,7 @@ object SyncLogger{
val consoleLogger = new ConsoleLogger(dest, rotationSize)
val statusActor = new StatusActor(
imageName => IconHandler.icon.setImage(IconHandler.images(imageName)),
tooltip => IconHandler.icon.setToolTip(fansi.Str(tooltip).plainText)
tooltip => IconHandler.setToolTip(fansi.Str(tooltip).plainText)
)

def run(msg: Msg) = if (!closed) msg match{
Expand Down Expand Up @@ -135,10 +136,12 @@ object SyncLogger{

val icon = new java.awt.TrayIcon(images("blue-sync"))

icon.setToolTip("Devbox Initializing")
setToolTip("Devbox Initializing")

val tray = java.awt.SystemTray.getSystemTray()

def setToolTip(s: String) =
icon.setToolTip(titleOpt.map(_ + "\n").getOrElse("") + s)

icon.addMouseListener(new MouseListener {
def mouseClicked(e: MouseEvent): Unit = onClick.send(())
Expand Down
16 changes: 9 additions & 7 deletions devbox/src/syncer/AgentApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,21 @@ trait AgentApi {
def start(logPrepOutput: String => Unit): Boolean
}

class ReliableAgent(prepareWithLogs: (String => Unit) => Boolean,
cmd: Seq[String],
class ReliableAgent[T](prepareWithLogs: (String => Unit) => Option[T],
cmd: T => Seq[String],
cwd: os.Path) extends AgentApi {
var process: os.SubProcess = _

override def start(logPrepOutput: String => Unit): Boolean = {
assert(process == null)

val prepPassed = prepareWithLogs(logPrepOutput)

if (prepPassed) process = os.proc(cmd).spawn(cwd = cwd)

prepPassed
prepareWithLogs(logPrepOutput) match {
case Some(prepRes) =>
process = os.proc(cmd(prepRes)).spawn(cwd = cwd)
true
case _ =>
false
}
}
def stderr = process.stderr
def stdout = process.stdout
Expand Down
3 changes: 2 additions & 1 deletion devbox/test/src/devbox/DevboxTestMain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ object DevboxTestMain {
implicit lazy val logger: devbox.logger.SyncLogger.Impl = new devbox.logger.SyncLogger.Impl(
n => os.pwd / "out" / "scratch" / config.label / s"log$n.txt",
5 * 1024 * 1024,
new castor.ProxyActor((_: Unit) => AgentReadWriteActor.ForceRestart(), syncer.agentActor)
new castor.ProxyActor((_: Unit) => AgentReadWriteActor.ForceRestart(), syncer.agentActor),
None
)
lazy val syncer = instantiateSyncer(
src, dest,
Expand Down
9 changes: 5 additions & 4 deletions devbox/test/src/devbox/DevboxTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ object DevboxTests extends TestSuite{
implicit lazy val logger: SyncLogger.Impl = new SyncLogger.Impl(
n => logFileBase / s"$logFileName$n.$logFileExt",
5 * 1024 * 1024,
new castor.ProxyActor((_: Unit) => AgentReadWriteActor.ForceRestart(), syncer.agentActor)
new castor.ProxyActor((_: Unit) => AgentReadWriteActor.ForceRestart(), syncer.agentActor),
None
)

lazy val syncer = instantiateSyncer(
Expand Down Expand Up @@ -268,9 +269,9 @@ object DevboxTests extends TestSuite{
logger: SyncLogger) = {

val syncer = new Syncer(
new ReliableAgent(
log => /*do nothing*/true,
Seq(
new ReliableAgent[Unit](
log => /*do nothing*/ Some(()),
_ => Seq(
"java", "-cp",
System.getenv("AGENT_EXECUTABLE"), "devbox.agent.DevboxAgentMain",
"--ignore-strategy", ignoreStrategy,
Expand Down
28 changes: 15 additions & 13 deletions launcher/src/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ object Main {
println(s"Unknown arguments: ${remaining.mkString(", ")}")
System.exit(1)
}
val portFwdArgs =
if (config.proxyGit)
Seq("-R", s"${ProxyServer.DEFAULT_PORT}:localhost:${ProxyServer.DEFAULT_PORT}")
else
def portFwdArgs(port: Option[Int]): Seq[String] = port match {
case Some(p) if(config.proxyGit) =>
Seq("-R", s"${ProxyServer.DEFAULT_PORT}:localhost:$p")
case _ =>
Seq()
}
devbox.DevboxMain.main0(
Some(ensureInstanceRunning.url),
config,
Expand All @@ -58,15 +59,16 @@ object Main {

prepResult.exitCode == 0
},
Seq(
"ssh", "-C",
"-o", "ExitOnForwardFailure=yes",
"-o", "ServerAliveInterval=4",
"-o", "ServerAliveCountMax=4") ++
portFwdArgs ++ Seq(
ensureInstanceRunning.url,
s"java -cp ~/.devbox/agent.jar devbox.agent.DevboxAgentMain --log-path ~/.devbox/log.txt --ignore-strategy gitignore --proxy-git-commands ${config.proxyGit}"
)
{ (port: Option[Int]) => Seq(
"ssh", "-C",
"-o", "ExitOnForwardFailure=yes",
"-o", "ServerAliveInterval=4",
"-o", "ServerAliveCountMax=4"
) ++ portFwdArgs(port) ++ Seq(
ensureInstanceRunning.url,
s"java -cp ~/.devbox/agent.jar devbox.agent.DevboxAgentMain --log-path ~/.devbox/log.txt --ignore-strategy gitignore --proxy-git-commands ${config.proxyGit}"
)
}
)
}
}
Expand Down

0 comments on commit 8c26aa0

Please sign in to comment.