def do_GET(self): if (self.path == '/sentinel'): self.send_response(200) self.end_headers() return elif (self.path != '/'): self.send_response(404) self.end_headers() return self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() print >> self.wfile, "<html>" print >> self.wfile, "<head>" print >> self.wfile, " <title>Myriad Parallel Data Generator » % s</title>" % (self.server.datasetID) print >> self.wfile, " <script type='text/JavaScript'>" print >> self.wfile, " <!--" print >> self.wfile, " function timedRefresh(timeoutPeriod) {" print >> self.wfile, " setTimeout('location.reload(true);', timeoutPeriod);" print >> self.wfile, " }" print >> self.wfile, " // -->" print >> self.wfile, " </script>" print >> self.wfile, "</head>" print >> self.wfile, "<body style='margin: 0; padding: 2ex 2em; font-size: 14px;' onload='javascript:timedRefresh(%d);'>" % (self.GET_REFRESH) print >> self.wfile, "<div id='header' style='text-align: center;'>" print >> self.wfile, " <h1 style='color: #333; font-size: 2em; margin: 0 0 0.5ex 0; padding: 0;'>Myriad Parallel Data Generator</h1>" print >> self.wfile, " <h2 style='color: #333; font-size: 1.5em; margin: 0 0 3ex 0; padding: 0;'>Job coordinator for dataset »%s« </h2>" % (self.server.datasetID) print >> self.wfile, "</div>" print >> self.wfile, "<table style='width: 100%; border: 1px solid #999;' cellspacing='5' cellpadding='0'>" print >> self.wfile, "<thead>" print >> self.wfile, "<tr>" print >> self.wfile, " <td style='width: 10%; background: #454545; color: #fafafa; padding: 0.5ex'>Node #</td>" print >> self.wfile, " <td style='width: 20%; background: #454545; color: #fafafa; padding: 0.5ex'>Hostname</td>" print >> self.wfile, " <td style='width: 35%; background: #454545; color: #fafafa; padding: 0.5ex'>Progress</td>" print >> self.wfile, " <td style='width: 15%; background: #454545; color: #fafafa; padding: 0.5ex'>Status</td>" print >> self.wfile, " <td style='width: 10%; background: #454545; color: #fafafa; padding: 0.5ex'>Attempt #</td>" print >> self.wfile, " <td style='width: 10%; background: #454545; color: #fafafa; padding: 0.5ex'>Time</td>" print >> self.wfile, "</tr>" print >> self.wfile, "</thead>" print >> self.wfile, "<tbody>" for n in self.server.nodes: print >> self.wfile, "<tr>" print >> self.wfile, " <td style='background: #fafafa; color: #454545; padding: 0.5ex'>%05d</td>" % (n.id) print >> self.wfile, " <td style='background: #fafafa; color: #454545; padding: 0.5ex'>%s</td>" % (n.host) print >> self.wfile, " <td style='background: #fafafa; color: #454545; padding: 0.5ex'><span style='float: left; width: 15%%;'>%02d%%</span><span style='float: left; width: %d%%; border-left: 1px solid #666; background: #666; color: #666; overflow: hidden;'>»</span></td>" % (100 * n.progress, 80 * n.progress) print >> self.wfile, " <td style='background: #fafafa; color: #454545; padding: 0.5ex'>%s</td>" % (DGenNode.STATUS_STRING[n.status]) print >> self.wfile, " <td style='background: #fafafa; color: #454545; padding: 0.5ex'>%d</td>" % (n.attempt) print >> self.wfile, " <td style='background: #fafafa; color: #454545; padding: 0.5ex'>%s</td>" % (timeutil.formatTime(n.lastBeat - n.started)) print >> self.wfile, "</tr>" print >> self.wfile, "</tbody>" print >> self.wfile, "</table>" print >> self.wfile, "<body>" print >> self.wfile, "</html>"
def run(self): ''' Srart the distributed generation process using the specified dgen configName. ''' self.started = datetime.datetime.now() server = None monitor = None try: if (self.cleanup): slaves = self.config.slaves(self.configName) self.log.info("~" * 55) self.log.info("Myriad Parallel Data Generator (Version %s)", self.VERSION) self.log.info("~" * 55) self.log.info("cleaning configuration `%s`", self.configName) for h in slaves: DGenHost(h).clean(self) else: master = self.config.master(self.configName) nodes = self.config.nodes(self.configName) self.log.info("~" * 55) self.log.info("Myriad Parallel Data Generator (Version %s)", self.VERSION) self.log.info("~" * 55) self.log.info("running configuration `%s` with scaling factor %.3f", self.configName, self.sf) self.dgenMaster = master self.dgenNodes = [ DGenNode(n) for n in nodes ] self.log.info("starting heartbeat server on address `%s:%d`", self.dgenMaster.name, self.dgenMaster.coorServerPort) server = HeartbeatServer(self.datasetID, self.dgenNodes, ('0.0.0.0', self.dgenMaster.coorServerPort)) # start node monitor self.log.info("starting node monitor thread") monitor = NodeMonitor(self, server) monitor.start() # start server loop serverThread = Thread(target=server.serveLoop) serverThread.start() self.log.info("starting %d generator nodes", len(self.dgenNodes)) self.startNodes() # wait for server thread to finish (timeout and loop needed for KeyboardInterrupt) while(serverThread.isAlive()): serverThread.join(3.0) # wait for monitor thread monitor.join() if (monitor.exception): self.log.error("interrupting generation process after failure in node %d ", monitor.exception.id) raise monitor.exception # abort all running nodes self.abortAllNodes() self.finished = datetime.datetime.now() self.log.info("generator process finished in %s seconds", timeutil.formatTime(self.finished - self.started)) except KeyboardInterrupt: self.log.warning("execution interrupted by user") if (monitor != None): monitor.shutdown() self.abortAllNodes() raise except NodeFailureException, e: self.abortAllNodes() if (monitor != None): monitor.shutdown() self.error(str(e), False) raise