org.gridvise.logical.Launchable.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gridvise-core Show documentation
Show all versions of gridvise-core Show documentation
gridvise-core is an opensource project
The newest version!
package org.gridvise.logical
import java.lang.Boolean
import java.lang.String
import java.util.Date
import scala.collection.mutable.HashMap
import scala.collection.mutable.HashSet
import scala.sys.process.ProcessIO
import scala.sys.process.stringToProcess
import org.gridvise.logical.logbroker.LogBroker
import org.gridvise.logical.os.MachineInfo
import org.gridvise.logical.os.OSOperations
import org.gridvise.mgmtcache.coh.entity.launchable.LaunchableCache
import org.gridvise.mgmtcache.coh.entity.launchable.LaunchableKey
import org.gridvise.mgmtcache.coh.entity.threaddumps.ThreadDumpCache
import org.gridvise.mgmtcache.coh.entity.threaddumps.ThreadDumpKey
import org.gridvise.util.AsyncInvoker
import org.gridvise.util.Dictionary
import org.gridvise.xmlbindings.DictionaryEntryable
import org.slf4j.LoggerFactory
class Launchable(var launchableKey: LaunchableKey, ordinal: Integer) extends Serializable {
def logger = LoggerFactory.getLogger(this.getClass())
final var NOT_RUNNING = "not started"
final var STARTING = "starting"
final val COUNTER_VAR_PACEHOLDER = "\\$\\{GV_COUNTER\\}"
final val JVM_NAME_VAR_PACEHOLDER = "\\$\\{GV_JVM_NAME\\}"
var jvmOptions = new HashMap[String, String]()
var classPathEntries = new HashSet[String]()
var mainClass: String = _
var jvmArgs: String = _
var machineName = MachineInfo.getMachineName()
var configName: String = _
var nodeGroupName: String = _
var running: Boolean = false
var delay = -1
var gridProperties = new HashMap[String, String]()
def this(clusterId: Long, ordinal: Integer) = this(new LaunchableKey(MachineInfo.getMachineName(), clusterId), ordinal)
var processIdentifier = configName + " " + ordinal
// def act() {
// while (true) {
// receive {
// case Start => startjvm()
// }
// }
// }
// def go() {
// this.start()
// this ! start
// }
def start() {
val command = buildCommand()
if (running) {
logger.info("Already running %s".format(command))
} else {
AsyncInvoker.async {
processIdentifier = configName + " " + ordinal + STARTING
LaunchableCache.putLaunchable(this)
logger.info(command)
if (delay != -1) {
//already setting status to started so that gui shows node as green //TODO revisit
running = true
LaunchableCache.putLaunchable(this)
logger.info("Will start delayed by %s millis".format(delay))
Thread.sleep(delay)
}
logger.info("Starting now %s".format(command))
val pio = new ProcessIO(_ => (),
stdout => scala.io.Source.fromInputStream(stdout)
.getLines.foreach(l => LogBroker.handleInfoLine(getLaunchableKey(), l)),
stderr => scala.io.Source.fromInputStream(stderr)
.getLines.foreach(l => LogBroker.handleErrorLine(getLaunchableKey(), l)))
var p = command.run(pio)
//var p = command.run()
processIdentifier = configName + " " + ordinal + " (pid="+OSOperations.getProcessIdentifier(p) +")"
running = true
LaunchableCache.putLaunchable(this)
subscribeCallback(Dictionary.gridDictionary().MemberId)
subscribeCallback(Dictionary.gridDictionary().Role)
//subscribeLogBasedClusterEvent()
}
}
}
def subscribeLogBasedClusterEvent() {
Dictionary.gridDictionary().productIterator.foreach(
a => LogBroker.subscribeEventStream(launchableKey, a.asInstanceOf[DictionaryEntryable]))
}
def subscribeCallback(de: DictionaryEntryable) {
val callback = (x: String) => LaunchableCache.setGridProperty(this.getLaunchableKey(), de, x)
LogBroker.subscribeCallback(this.getLaunchableKey(), de, callback)
}
def stop() {
OSOperations.stopProcess(this.processIdentifier)
notRunning()
}
def notRunning() {
running = false
processIdentifier = configName + " " + ordinal
persistState()
}
def persistState() {
LaunchableCache.putLaunchable(this)
}
def threadDump(): ThreadDump = {
threadDump(new Date())
}
def threadDump(triggerDate: Date): ThreadDump = {
if (isRunning) {
var logSubscriber = LogBroker.subscribe(getLaunchableKey(), Dictionary.jvmDictionary().EndOfStacktrace);
OSOperations.threadDump(this.processIdentifier)
while (!logSubscriber.isComplete) {
logger.info("Waiting for log subscriber to complete")
logSubscriber.synchronized {
//FIXME what's this??
logSubscriber.wait(1000)
if (logSubscriber.out.length() == 0) {
logSubscriber.isComplete = true
}
}
}
asyncCacheThreadDump(triggerDate, logSubscriber.out)
// logSubscriber.out
} else {
// NOT_RUNNING
new ThreadDump(NOT_RUNNING, machineName, nodeGroupName, configName)
}
}
//TODO make async
def asyncCacheThreadDump(triggerDate: Date, dump: String): ThreadDump = {
var threadDumpKey = new ThreadDumpKey(this.getLaunchableKey(), triggerDate)
var td = new ThreadDump(dump, machineName, nodeGroupName, configName)
ThreadDumpCache.put(threadDumpKey, new ThreadDump(dump, machineName, nodeGroupName, configName))
td
}
def isRunning(): Boolean = running
def getLaunchableKey() = {
this.launchableKey
}
def getClusterId() = this.launchableKey.clusterId
def buildCommand(): String = {
//java -classpath C:\java\MyClasses;C:\java\OtherClasses ...
var command = OSOperations.getJavaCommand()
command += appendJVMOptions(command)
command += appendClasspathEntries(command)
command += " " + mainClass
if ("null" != jvmArgs + "") command += " " + jvmArgs
command
}
def appendClasspathEntries(command: String): String = {
//java -classpath C:\java\MyClasses;C:\java\OtherClasses ...
var cpFragment = " -classpath "
classPathEntries.foreach { cpe =>
cpFragment += (cpe + OSOperations.getClasspathSeparator())
}
removeLastCharacter(cpFragment)
}
def removeLastCharacter(in: String): String = {
in.substring(0, in.length() - 1)
}
def appendJVMOptions(command: String): String = {
var optionFragment = ""
jvmOptions.foreach {
case (key, value) => {
var v = value.replaceAll(COUNTER_VAR_PACEHOLDER, this.ordinal.toString())
v = v.replaceAll(JVM_NAME_VAR_PACEHOLDER, this.configName)
optionFragment += " " + key + v
}
}
optionFragment
}
def addGridProperty(dictionaryEntry: DictionaryEntryable, value: String) {
this.gridProperties.put(dictionaryEntry.getClass().getSimpleName(), value);
}
def getGridProperty(dictionaryEntry: DictionaryEntryable): String = {
this.gridProperties.get(dictionaryEntry.getClass().getSimpleName()).get;
}
override def toString() = "[machineName=" + machineName + ", pid=" + this.processIdentifier + ", configName=" + this.configName + ", nodeGroupName=" + this.nodeGroupName + ", clusterId=" + this.getClusterId() + ", mainClass=" + this.mainClass + ", gridProperties=" + this.gridProperties + "]\n" + this.buildCommand() + "\n\n"
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy