class TaskJuggler::Tj3Daemon
Public Class Methods
new()
click to toggle source
Calls superclass method
TaskJuggler::Tj3AppBase::new
# File lib/taskjuggler/apps/Tj3Daemon.rb, line 26 def initialize super @mandatoryArgs = '[<tjp file> [<tji file> ...] ...]' @mhi = MessageHandlerInstance.instance @mhi.logFile = File.join(Dir.getwd, "/#{AppConfig.appName}.log") @mhi.appName = AppConfig.appName # By default show only warnings and more serious messages. @mhi.outputLevel = :warning @daemonize = true @uriFile = File.join(Dir.getwd, '.tj3d.uri') @port = nil @webServer = false @webServerPort = 8080 @webdPidFile = File.join(Dir.getwd, ".tj3webd-#{$$}.pid").untaint end
Public Instance Methods
appMain(files)
click to toggle source
# File lib/taskjuggler/apps/Tj3Daemon.rb, line 85 def appMain(files) broker = ProjectBroker.new @rc.configure(self, 'global') @rc.configure(@mhi, 'global.log') @rc.configure(broker, 'global') @rc.configure(broker, 'daemon') # Set some config variables if corresponding data was provided via the # command line. broker.port = @port if @port broker.uriFile = @uriFile.untaint broker.projectFiles = sortInputFiles(files) unless files.empty? broker.daemonize = @daemonize # Create log files for standard IO for each child process if the daemon # is not disconnected from the terminal. broker.logStdIO = !@daemonize if @webServer webdCommand = "tj3webd --webserver-port #{@webServerPort} " + "--pidfile #{@webdPidFile}" # Also start the web server as a separate process. We keep the PID, so # we can terminate that process again when we exit the daemon. begin `#{webdCommand}` rescue error('tj3webd_start_failed', "Could not start tj3webd: #{$!}") end info('web_server_started', "Web server started as '#{webdCommand}'") end broker.start if @webServer pid = nil begin # Read the PID of the web server from the PID file. File.open(@webdPidFile, 'r') do |f| pid = f.read.to_i end rescue warning('cannot_read_webd_pidfile', "Cannot read tj3webd PID file (#{@webdPidFile}): #{$!}") end # If we have started the web server, we are also trying to terminate # that process again. begin Process.kill("TERM", pid) rescue warning('tj3webd_term_failed', "Could not terminate web server: #{$!}") end info('web_server_terminated', "Web server with PID #{pid} terminated") end 0 end
processArguments(argv)
click to toggle source
Calls superclass method
TaskJuggler::Tj3AppBase#processArguments
# File lib/taskjuggler/apps/Tj3Daemon.rb, line 43 def processArguments(argv) super do @opts.banner.prepend(<<'EOT' The TaskJuggler daemon can be used to quickly generate reports for a number of scheduled projects that are resident in memory. Once the daemon has been started tj3client can be used to control it. EOT ) @opts.on('-d', '--dont-daemonize', format("Don't put program into daemon mode. Keep it " + 'connected to the terminal and show debug output.')) do @daemonize = false end @opts.on('-p', '--port <NUMBER>', Integer, format('Use the specified TCP/IP port to serve tj3client ' + 'requests (Default: 8474).')) do |arg| @port = arg end @opts.on('--logfile <FILE NAME>', String, format('Log daemon messages to the specified file.')) do |arg| @mhi.logFile = arg end @opts.on('--urifile <FILE NAME>', String, format('If the port is 0, use this file to store the URI ' + 'of the server.')) do |arg| @uriFile = arg end @opts.on('-w', '--webserver', format('Start a web server that serves the reports of ' + 'the loaded projects.')) do @webServer = true end @opts.on('--webserver-port <NUMBER>', Integer, format('Use the specified TCP/IP port to serve web browser ' + 'requests (Default: 8080).')) do |arg| @webServerPort = arg end end end
Private Instance Methods
sortInputFiles(files)
click to toggle source
Sort the provided input files into groups of projects. Each *.tjp file starts a new project. A *.tjp file may be followed by any number of *.tji files. The result is an Array of projects. Each consists of an Array like this: [ <working directory>, <tjp file> (, <tji file> …) ].
# File lib/taskjuggler/apps/Tj3Daemon.rb, line 148 def sortInputFiles(files) projects = [] project = nil files.each do |file| if file[-4..-1] == '.tjp' # The project master file determines the working directory. If it's # an absolute file name, that directory will become the working # directory. If it's a relative file name, the current working # directory will be kept. if file[0] == '/' # Absolute file name workingDir = File.dirname(file) fileName = File.basename(file) else # Relative file name workingDir = Dir.getwd fileName = file end project = [ workingDir, fileName ] projects << project elsif file[-4..-1] == '.tji' # .tji files are optional. But if they are specified, they must # always follow the master file in the list. if project.nil? error('tj3d_tji_before_tjp', "You must specify a '.tjp' file before the '.tji' files") end project << file else error('tj3d_no_file_Ext', "Project files must have a '.tjp' or '.tji' extension") end end projects end