From c75ea4553c001d566df19fbf411cbbdb341a01c5 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Tue, 2 Jul 2019 16:13:30 -0400 Subject: [PATCH] 2019-07-02 Fred Gleason * Fixed a bug in rdpadengined(8) that prevented exited scripts from being restarted in response to a 'ModifyAction' notification. --- ChangeLog | 3 ++ rdpadengined/rdpadengined.cpp | 68 +++++++++++++++++++++++------------ rdpadengined/rdpadengined.h | 5 +-- 3 files changed, 51 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index b05d9cf9..412ca952 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18854,3 +18854,6 @@ omitted from the HTML version of the Operations Guide. 2019-07-02 Fred Gleason * Implemented the '%v'/'%V' metadata wildcards for PyPAD. +2019-07-02 Fred Gleason + * Fixed a bug in rdpadengined(8) that prevented exited scripts + from being restarted in response to a 'ModifyAction' notification. diff --git a/rdpadengined/rdpadengined.cpp b/rdpadengined/rdpadengined.cpp index 0d9a76f4..49dc0b3f 100644 --- a/rdpadengined/rdpadengined.cpp +++ b/rdpadengined/rdpadengined.cpp @@ -130,13 +130,12 @@ void MainObject::ripcConnectedData(bool state) // Start Scripts // sql=QString("select ")+ - "ID," // 00 - "SCRIPT_PATH " // 01 + "ID " // 00 "from PYPAD_INSTANCES where "+ "STATION_NAME=\""+RDEscapeString(rda->station()->name())+"\""; q=new RDSqlQuery(sql); while(q->next()) { - StartScript(q->value(0).toUInt(),q->value(1).toString()); + StartScript(q->value(0).toUInt()); } delete q; } @@ -150,16 +149,16 @@ void MainObject::notificationReceivedData(RDNotification *notify) if(notify->type()==RDNotification::PypadType) { int id=notify->id().toUInt(); switch(notify->action()) { - case RDNotification::AddAction: - sql=QString("select SCRIPT_PATH from PYPAD_INSTANCES where ")+ + case RDNotification::AddAction: + sql=QString("select ID from PYPAD_INSTANCES where ")+ QString().sprintf("ID=%u && ",id)+ "STATION_NAME=\""+RDEscapeString(rda->station()->name())+"\""; q=new RDSqlQuery(sql); if(q->first()) { - StartScript(id,q->value(0).toString()); + StartScript(id); } delete q; - break; + break; case RDNotification::DeleteAction: pad_instances.value(id)->setPrivateData((void *)true); // No Restart @@ -167,7 +166,12 @@ void MainObject::notificationReceivedData(RDNotification *notify) break; case RDNotification::ModifyAction: - KillScript(id); + if(ScriptIsActive(id)) { + KillScript(id); + } + else { + StartScript(id); + } break; case RDNotification::NoAction: @@ -198,11 +202,10 @@ void MainObject::instanceFinishedData(int id) if(proc->process()->exitCode()==0) { SetRunStatus(id,false); bool no_restart=(bool)proc->privateData(); - QString script_path=proc->arguments().at(0); proc->deleteLater(); pad_instances.remove(id); if(!no_restart) { - StartScript(id,script_path); + StartScript(id); } } else { @@ -240,20 +243,39 @@ void MainObject::exitData() } -void MainObject::StartScript(unsigned id,const QString &script_path) +bool MainObject::ScriptIsActive(unsigned id) const { - RDProcess *proc=new RDProcess(id,this); - pad_instances[id]=proc; - connect(proc,SIGNAL(started(int)),this,SLOT(instanceStartedData(int))); - connect(proc,SIGNAL(finished(int)),this,SLOT(instanceFinishedData(int))); - QStringList args; - args.push_back(script_path); - args.push_back("localhost"); - args.push_back(QString().sprintf("%u",RD_PAD_CLIENT_TCP_PORT)); - args.push_back(QString().sprintf("$%u",id)); - pad_instances.value(id)->start(RD_PYPAD_PYTHON_PATH,args); - rda->syslog(LOG_INFO,"starting: "+proc->program()+" "+ - proc->arguments().join(" ").toUtf8()); + bool ret=false; + + if(pad_instances.value(id)!=NULL) { + ret=pad_instances.value(id)->process()->state()!=QProcess::NotRunning; + } + + return ret; +} + + +void MainObject::StartScript(unsigned id) +{ + QString sql=QString("select SCRIPT_PATH from PYPAD_INSTANCES where ")+ + QString().sprintf("ID=%u && ",id)+ + "STATION_NAME=\""+RDEscapeString(rda->station()->name())+"\""; + RDSqlQuery *q=new RDSqlQuery(sql); + if(q->first()) { + RDProcess *proc=new RDProcess(id,this); + pad_instances[id]=proc; + connect(proc,SIGNAL(started(int)),this,SLOT(instanceStartedData(int))); + connect(proc,SIGNAL(finished(int)),this,SLOT(instanceFinishedData(int))); + QStringList args; + args.push_back(q->value(0).toString()); + args.push_back("localhost"); + args.push_back(QString().sprintf("%u",RD_PAD_CLIENT_TCP_PORT)); + args.push_back(QString().sprintf("$%u",id)); + pad_instances.value(id)->start(RD_PYPAD_PYTHON_PATH,args); + rda->syslog(LOG_INFO,"starting: "+proc->program()+" "+ + proc->arguments().join(" ").toUtf8()); + } + delete q; } diff --git a/rdpadengined/rdpadengined.h b/rdpadengined/rdpadengined.h index 5d6bf076..776a563a 100644 --- a/rdpadengined/rdpadengined.h +++ b/rdpadengined/rdpadengined.h @@ -2,7 +2,7 @@ // // Rivendell PAD Consolidation Server // -// (C) Copyright 2018 Fred Gleason +// (C) Copyright 2018-2019 Fred Gleason // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as @@ -46,7 +46,8 @@ class MainObject : public QObject void exitData(); private: - void StartScript(unsigned id,const QString &script_path); + bool ScriptIsActive(unsigned id) const; + void StartScript(unsigned id); void KillScript(unsigned id); void SetRunStatus(unsigned id,bool state,int exit_code=0, const QString &err_text=QString()) const;