8 var spawn = require(
'child_process' ).spawn;
9 var emitter = require(
'events' ).EventEmitter;
10 var fs = require(
'fs' );
11 var os = require(
'os');
12 var arc =
new emitter( );
13 var xml = require(
'xml2js' );
14 var parser =
new xml.Parser( {explicitArray:
false});
15 var xmlrpc = require(
'xmlrpc' );
18 var Status =
function ( partition ) {
19 this.state =
"Shutdown";
20 this.runNumber = 1000;
21 this.systemPID = null;
22 this.systemRunning =
false;
23 this.systemOutputBuffer =
"";
24 this.systemErrorBuffer =
"";
25 this.commandPID = null;
26 this.commandRunning =
false;
27 this.commandOutputBuffer =
"";
28 this.commandErrorBuffer =
"";
29 this.stopPending =
false;
30 this.WFPlotsUpdated = Date.now( );
33 this.partition = partition;
35 this.okToStartOnMon =
false;
39 var configuration = {};
40 configuration.artdaqDir =
"~/artdaq-demo-base";
41 configuration.setupScript =
"setupARTDAQDEMO";
42 configuration.runValue = 0;
45 function readConfiguration( systemStatus ) {
46 var fileName = __dirname +
"/../../artdaq-configuration/server/" + systemStatus.config;
47 console.log(
"Going to read configuration " + fileName );
48 if ( fs.existsSync( fileName ) ) {
50 var config =
"" + fs.readFileSync( fileName );
52 parser.parseString( config,
function(err,result) {xmlObj = result;});
53 configuration.xmlObj = xmlObj;
54 configuration.artdaqDir = xmlObj[
'artdaq-configuration'].artdaqDir;
55 configuration.setupScript = xmlObj[
'artdaq-configuration'].setupScript;
56 configuration.runValue = xmlObj[
'artdaq-configuration'].dataLogger.runValue;
60 console.log(
"Configuration file not found!" );
64 arc.MasterInitFunction =
function ( workerData ) {
66 output.p0 =
new Status( 0 );
67 output.p1 =
new Status( 1 );
68 output.p2 =
new Status( 2 );
69 output.p3 =
new Status( 3 );
74 output.p0onmon =
false;
75 output.p1onmon =
false;
76 output.p2onmon =
false;
77 output.p3onmon =
false;
79 if ( !fs.existsSync( __dirname +
"/../client/P0" ) ) {
80 fs.mkdirSync( __dirname +
"/../client/P0" );
82 if ( !fs.existsSync( __dirname +
"/../client/P1" ) ) {
83 fs.mkdirSync( __dirname +
"/../client/P1" );
85 if ( !fs.existsSync( __dirname +
"/../client/P2" ) ) {
86 fs.mkdirSync( __dirname +
"/../client/P2" );
88 if ( !fs.existsSync( __dirname +
"/../client/P3" ) ) {
89 fs.mkdirSync( __dirname +
"/../client/P3" );
92 fs.chmodSync( __dirname +
"/runARTDAQ.sh",
'777' );
93 fs.chmodSync( __dirname +
"/killArtdaq.sh",
'777' );
94 fs.chmodSync( __dirname +
"/cleanupArtdaq.sh",
'777' );
96 workerData[
"artdaq-runcontrol"] = output;
99 function checkCommand( systemStatus ) {
100 if ( systemStatus.commandPID !== null ) {
102 process.kill( systemStatus.commandPID,0 );
103 systemStatus.commandRunning =
true;
105 systemStatus.commandRunning =
false;
106 systemStatus.commandPID = null;
109 systemStatus.commandRunning =
false;
113 function checkSystem( systemStatus ) {
114 if ( systemStatus.systemPID !== null ) {
116 process.kill( systemStatus.systemPID,0 );
117 systemStatus.systemRunning =
true;
119 systemStatus.systemRunning =
false;
120 systemStatus.systemPID = null;
123 systemStatus.systemRunning =
false;
127 function startCommand( args,systemStatus ) {
128 if ( readConfiguration( systemStatus ) ) {
129 var port = ( systemStatus.partition * 100 ) + 5600;
130 var configName = configuration.artdaqDir +
"/P" + systemStatus.partition +
"Config.xml";
131 fs.createReadStream(__dirname +
"/../../artdaq-configuration/server/" + systemStatus.config).pipe(fs.createWriteStream(configName));
132 var commandArray = [systemStatus.config,configName,port,
"manageSystem.sh",
"-C", configName].concat( args );
133 systemStatus.commandErrorBuffer =
"";
134 systemStatus.commandOutputBuffer =
"";
135 var out = fs.openSync( __dirname +
"/../client/P" + systemStatus.partition +
"/comm.out.log",
'w' );
136 var err = fs.openSync( __dirname +
"/../client/P" + systemStatus.partition +
"/comm.err.log",
'w' );
137 console.log(
"Spawning: " + __dirname +
"/runARTDAQ.sh " + commandArray );
138 var command = spawn( __dirname +
"/runARTDAQ.sh",commandArray,{ detached:
true, stdio: [
'ignore',out,err] } );
148 systemStatus.commandPID = command.pid;
150 systemStatus.commandRunning =
true;
151 checkCommand( systemStatus );
153 console.log(
"CANNOT READ CONFIGURATION. COMMAND NOT STARTED!!!!" );
157 function startSystem( systemStatus ) {
158 if ( readConfiguration( systemStatus ) ) {
159 console.log(
"Starting System, Partition " + systemStatus.partition );
160 var port = ( systemStatus.partition * 100 ) + 5600;
162 var logRoot = configuration.xmlObj[
'artdaq-configuration'].logDir;
163 var eventBuilderHostnames = configuration.xmlObj[
'artdaq-configuration'].eventBuilders.hostnames.hostname;
164 var aggregatorHostname = configuration.xmlObj[
'artdaq-configuration'].dataLogger.hostname;
165 var boardReaderHostnames = configuration.xmlObj[
'artdaq-configuration'].boardReaders.boardReader.hostname;
167 console.log(
"Making PMT Log Directories");
168 spawn(
"/bin/mkdir", [
"-p",
"-m",
"0777",logRoot +
"/pmt"]);
169 spawn(
"/bin/mkdir", [
"-p",
"-m",
"0777",logRoot +
"/masterControl"]);
170 if(aggregatorHostname !=
"localhost" && aggregatorHostname != os.hostname()) {
171 spawn(
"/usr/bin/ssh", [aggregatorHostname,
"/bin/mkdir -p -m 0777 " + logRoot +
"/aggregator"]);
173 spawn(
"/bin/mkdir", [
"-p",
"-m",
"0777",logRoot +
"/aggregator"]);
175 for(var hn in eventBuilderHostnames) {
176 if(hn !=
"localhost" && hn != os.hostname()) {
177 spawn(
"/usr/bin/ssh", [hn,
"/bin/mkdir -p -m 0777 " + logRoot +
"/eventbuilder"]);
179 spawn(
"/bin/mkdir", [
"-p",
"-m",
"0777",logRoot +
"/eventbuilder"]);
182 for(var hn in boardReaderHostnames) {
183 if(hn !=
"localhost" && hn != os.hostname()) {
184 spawn(
"/usr/bin/ssh", [hn,
"/bin/mkdir -p -m 0777 " + logRoot +
"/boardreader"]);
186 spawn(
"/bin/mkdir", [
"-p",
"-m",
"0777",logRoot +
"/boardreader"]);
190 var configName = configuration.artdaqDir +
"/P" + systemStatus.partition +
"Config.xml";
191 fs.createReadStream(__dirname +
"/../../artdaq-configuration/server/" + systemStatus.config).pipe(fs.createWriteStream(configName));
192 var displayNumber = process.env.DISPLAY;
194 var commandArray = [systemStatus.config, configName,port,
"pmt.rb",
"-p", port,
"-C",configName,
"--logpath", logRoot,
"--display", displayNumber];
196 var out = fs.openSync( __dirname +
"/../client/P" + systemStatus.partition +
"/out.log",
'w' );
197 var err = fs.openSync( __dirname +
"/../client/P" + systemStatus.partition +
"/err.log",
'w' );
198 systemStatus.systemErrorBuffer =
"";
199 systemStatus.systemOutputBuffer =
"";
200 console.log(
"Spawning: " + __dirname +
"/runARTDAQ.sh " + commandArray.join(
' ' ) );
201 var system = spawn( __dirname +
"/runARTDAQ.sh",commandArray,{ detached:
true, stdio: [
'ignore',out,err] } );
202 systemStatus.systemPID = system.pid;
204 systemStatus.systemRunning =
true;
205 console.log(
"Command Spawned" );
207 systemStatus.state =
"Started";
209 console.log(
"CANNOT READ CONFIGURATION. COMMAND NOT STARTED!!!!" );
213 function initialize( systemStatus ) {
214 if ( systemStatus.commandRunning ) {
215 setTimeout(
function () { initialize( systemStatus ); } );
218 var onmonDir = __dirname +
"/../client/P" + systemStatus.partition +
"/artdaqdemo_onmon.root";
219 var args = [
"-M", onmonDir,
"init"];
220 startCommand( args,systemStatus );
221 systemStatus.state =
"Initialized";
225 function startRun( systemStatus ) {
226 if ( systemStatus.commandRunning ) {
227 setTimeout(
function () { startRun( systemStatus ); },500 );
230 var args = [
"-N",systemStatus.runNumber,
"start"];
231 startCommand( args,systemStatus );
232 systemStatus.state =
"Running";
233 if ( readConfiguration( systemStatus ) && configuration.runValue > 0 ) {
234 systemStatus.stopPending =
true;
235 startCommand( [
"stop"],systemStatus );
240 function pauseRun( systemStatus ) {
241 if ( systemStatus.commandRunning ) {
242 setTimeout(
function () { pauseRun( systemStatus ); },500 );
245 var args = [
"pause"];
246 startCommand( args,systemStatus );
247 systemStatus.state =
"Paused";
251 function resumeRun( systemStatus ) {
252 if ( systemStatus.commandRunning ) {
253 setTimeout(
function () { resumeRun( systemStatus ); },500 );
256 var args = [
"resume"];
257 startCommand( args,systemStatus );
258 systemStatus.state =
"Running";
262 function endRun( systemStatus ) {
263 if ( systemStatus.commandRunning ) {
264 setTimeout(
function () { endRun( systemStatus ); },500 );
268 startCommand( args,systemStatus );
269 systemStatus.state =
"Initialized";
273 function killSystem( systemStatus ) {
274 checkCommand( systemStatus );
275 if ( !systemStatus.commandRunning ) {
276 checkSystem( systemStatus );
277 if ( systemStatus.systemRunning ) {
278 console.log(
"Killing System, PID: " + systemStatus.systemPID );
279 spawn( __dirname +
'/killArtdaq.sh',[systemStatus.systemPID] );
280 setTimeout(
function () { killSystem( systemStatus ); },1000 );
283 console.log(
"Command running, spinning..." );
284 setTimeout(
function () { killSystem( systemStatus ); },1000 );
288 function shutdownSystem( systemStatus ) {
289 if ( systemStatus.commandRunning ) {
290 setTimeout(
function () { shutdownSystem( systemStatus ); },500 );
293 console.log(
"Shutting down system, Partition " + systemStatus.partition );
294 var args = [
"shutdown"];
295 startCommand( args,systemStatus );
296 spawn( __dirname +
'/cleanupArtdaq.sh',[__dirname,systemStatus.partition] );
297 systemStatus.state =
"Shutdown";
300 setTimeout(
function () { killSystem( systemStatus ); },4000 );
303 function getStatus( systemStatuses,partition ) {
304 var systemStatus = systemStatuses[
"p" + partition];
306 systemStatus.okToStartOnMon = systemStatuses[
"p" + partition +
"onmon"];
307 while(systemStatuses[
"p"+partition+
"evt"].length > 120) {
308 systemStatuses[
"p"+partition+
"evt"].shift();
311 checkCommand( systemStatus );
312 checkSystem( systemStatus );
313 if ( fs.existsSync( __dirname +
"/../client/P" + systemStatus.partition +
"/artdaqdemo_onmon.root" ) ) {
314 var stats = fs.statSync( __dirname +
"/../client/P" + systemStatus.partition +
"/artdaqdemo_onmon.root" );
315 var statSize = stats.size;
316 if ( statSize !== systemStatus.WFFileSize ) {
317 systemStatus.WFFileSize = statSize;
318 systemStatus.WFPlotsUpdated = Date.now( );
319 console.log(
"Plots Updated at " + systemStatus.WFPlotsUpdated );
321 if ( stats.mtime - systemStatus.WFFileMtime ) {
322 systemStatus.WFFileMtime = stats.mtime;
323 systemStatus.WFPlotsUpdated = Date.now( );
324 console.log(
"Plots Updated at " + systemStatus.WFPlotsUpdated );
327 systemStatus.WFPlotsUpdated = null;
329 if ( fs.existsSync( __dirname +
"/../client/P" + systemStatus.partition +
"/out.log" ) ) {
330 systemStatus.systemOutputBuffer =
"" + fs.readFileSync( __dirname +
"/../client/P" + systemStatus.partition +
"/out.log" );
332 if ( fs.existsSync( __dirname +
"/../client/P" + systemStatus.partition +
"/err.log" ) ) {
333 systemStatus.systemErrorBuffer =
"" + fs.readFileSync( __dirname +
"/../client/P" + systemStatus.partition +
"/err.log" );
335 if ( fs.existsSync( __dirname +
"/../client/P" + systemStatus.partition +
"/comm.out.log" ) ) {
336 systemStatus.commandOutputBuffer =
"" + fs.readFileSync( __dirname +
"/../client/P" + systemStatus.partition +
"/comm.out.log" );
338 if ( fs.existsSync( __dirname +
"/../client/P" + systemStatus.partition +
"/comm.err.log" ) ) {
339 systemStatus.commandErrorBuffer =
"" + fs.readFileSync( __dirname +
"/../client/P" + systemStatus.partition +
"/comm.err.log" );
341 if ( systemStatus.stopPending && !systemStatus.commandRunning ) {
342 systemStatus.state =
"Initialized";
344 systemStatuses[
"p"+partition] = systemStatus;
345 arc.emit(
'message', {name:
"artdaq-runcontrol",data:systemStatus, target:
"p"+partition} );
347 arc.emit(
'end',JSON.stringify( systemStatus ) );
350 arc.GET_P0 =
function ( systemStatuses ) {
351 getStatus( systemStatuses,0 );
354 arc.GET_P1 =
function ( systemStatuses ) {
355 getStatus( systemStatuses,1 );
358 arc.GET_P2 =
function ( systemStatuses ) {
359 getStatus( systemStatuses,2 );
362 arc.GET_P3 =
function ( systemStatuses ) {
363 getStatus( systemStatuses,3 );
366 arc.RO_GetEvent =
function( POST, systemStatuses ){
369 var events = systemStatuses[
"p"+POST.partition+
"evt"];
373 if(POST.event == 0 || POST.event < events[0].event) {
374 var data = events[0];
376 data.lastEvent = events[events.length - 1].event;
377 return JSON.stringify(data);
379 for(var event in events) {
382 if(events[event].event == POST.event) {
384 var data = events[event];
385 data.lastEvent = events[events.length - 1].event;
386 return JSON.stringify(data);
389 if(POST.event < events[events.length -1 ].event) {
398 arc.RW_GetEvent =
function( POST, systemStatuses) {
399 return arc.RO_GetEvent(POST, systemStatuses);
402 arc.RW_Start =
function ( POST,systemStatuses ) {
403 systemStatuses[
"p" + POST.partition +
"evt"] = [];
404 systemStatuses[
"p" + POST.partition].config = POST.config;
405 if ( systemStatuses[
"p" + POST.partition].state ===
"Shutdown" ) {
406 startSystem( systemStatuses[
"p" + POST.partition] );
408 getStatus( systemStatuses,POST.partition );
411 arc.RW_Init =
function ( POST,systemStatuses ) {
412 systemStatuses[
"p" + POST.partition].config = POST.config;
413 if ( systemStatuses[
"p" + POST.partition].state ===
"Started" ) {
414 initialize( systemStatuses[
"p" + POST.partition] );
416 getStatus( systemStatuses,POST.partition );
419 arc.RW_Run =
function ( POST,systemStatuses ) {
420 systemStatuses[
"p" + POST.partition].config = POST.config;
421 systemStatuses[
"p" + POST.partition].runNumber = POST.runNumber;
422 if ( systemStatuses[
"p" + POST.partition].state ===
"Initialized" ) {
423 startRun( systemStatuses[
"p" + POST.partition] );
425 getStatus( systemStatuses,POST.partition );
428 arc.RW_Pause =
function ( POST,systemStatuses ) {
429 systemStatuses[
"p" + POST.partition].config = POST.config;
430 if ( systemStatuses[
"p" + POST.partition].state ===
"Running" ) {
431 pauseRun( systemStatuses[
"p" + POST.partition] );
433 getStatus( systemStatuses,POST.partition );
436 arc.RW_Resume =
function ( POST,systemStatuses ) {
437 systemStatuses[
"p" + POST.partition].config = POST.config;
438 if ( systemStatuses[
"p" + POST.partition].state ===
"Paused" ) {
439 resumeRun( systemStatuses[
"p" + POST.partition] );
441 getStatus( systemStatuses,POST.partition );
444 arc.RW_End =
function ( POST,systemStatuses ) {
445 systemStatuses[
"p" + POST.partition +
"onmon"] =
false;
446 systemStatuses[
"p" + POST.partition].config = POST.config;
447 if ( systemStatuses[
"p" + POST.partition].state ===
"Running" || systemStatuses[
"p" + POST.partition].state ===
"Paused" ) {
448 endRun( systemStatuses[
"p" + POST.partition] );
450 getStatus( systemStatuses,POST.partition );
453 arc.RW_Shutdown =
function ( POST,systemStatuses ) {
454 systemStatuses[
"p" + POST.partition].config = POST.config;
455 if ( systemStatuses[
"p" + POST.partition].state ===
"Started" || systemStatuses[
"p" + POST.partition].state ===
"Initialized" || systemStatuses[
"p" + POST.partition].state ===
"Paused" ) {
456 shutdownSystem( systemStatuses[
"p" + POST.partition] );
458 getStatus( systemStatuses,POST.partition );
461 module.exports =
function ( module_holder ) {
462 module_holder[
"artdaq-runcontrol"] = arc;