Finalized error propagation and debug level setting code.
This commit is contained in:
parent
75c5af4575
commit
1174773244
5 changed files with 91 additions and 38 deletions
|
@ -287,6 +287,7 @@ void createAccount (std::string account){
|
|||
|
||||
///\brief The main entry point for the controller.
|
||||
int main(int argc, char ** argv){
|
||||
|
||||
Controller::Storage = JSON::fromFile("config.json");
|
||||
JSON::Value stored_port = JSON::fromString("{\"long\":\"port\", \"short\":\"p\", \"arg\":\"integer\", \"help\":\"TCP port to listen on.\"}");
|
||||
stored_port["default"] = Controller::Storage["config"]["controller"]["port"];
|
||||
|
@ -353,6 +354,18 @@ int main(int argc, char ** argv){
|
|||
//Input custom config here
|
||||
Controller::Storage = JSON::fromFile(Controller::conf.getString("configFile"));
|
||||
|
||||
{
|
||||
//spawn thread that reads stderr of process
|
||||
int pipeErr[2];
|
||||
if (pipe(pipeErr) >= 0){
|
||||
dup2(pipeErr[1], STDERR_FILENO);//cause stderr to write to the pipe
|
||||
close(pipeErr[1]);//close the unneeded pipe file descriptor
|
||||
tthread::thread msghandler(Controller::handleMsg, (void*)(((char*)0) + pipeErr[0]));
|
||||
msghandler.detach();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (Controller::conf.getOption("debug",true).size() > 1){
|
||||
Controller::Storage["config"]["debug"] = Controller::conf.getInteger("debug");
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <mist/procs.h>
|
||||
#include <mist/timing.h>
|
||||
#include <mist/tinythread.h>
|
||||
#include <mist/defines.h>
|
||||
#include "controller_storage.h"
|
||||
#include "controller_connectors.h"
|
||||
|
||||
|
@ -38,18 +39,28 @@ namespace Controller {
|
|||
|
||||
static inline void builPipedPart(JSON::Value & p, char * argarr[], int & argnum, JSON::Value & argset){
|
||||
for (JSON::ObjIter it = argset.ObjBegin(); it != argset.ObjEnd(); ++it){
|
||||
if (it->second.isMember("option") && p.isMember(it->first)){
|
||||
if (it->second.isMember("type")){
|
||||
if (it->second["type"].asStringRef() == "str" && !p[it->first].isString()){
|
||||
p[it->first] = p[it->first].asString();
|
||||
if (it->second.isMember("option")){
|
||||
if (p.isMember(it->first)){
|
||||
if (it->second.isMember("type")){
|
||||
if (it->second["type"].asStringRef() == "str" && !p[it->first].isString()){
|
||||
p[it->first] = p[it->first].asString();
|
||||
}
|
||||
if ((it->second["type"].asStringRef() == "uint" || it->second["type"].asStringRef() == "int") && !p[it->first].isInt()){
|
||||
p[it->first] = p[it->first].asString();
|
||||
}
|
||||
}
|
||||
if ((it->second["type"].asStringRef() == "uint" || it->second["type"].asStringRef() == "int") && !p[it->first].isInt()){
|
||||
p[it->first] = JSON::Value(p[it->first].asInt()).asString();
|
||||
if (p[it->first].asStringRef().size() > 0){
|
||||
argarr[argnum++] = (char*)(it->second["option"].c_str());
|
||||
argarr[argnum++] = (char*)(p[it->first].c_str());
|
||||
}
|
||||
}else{
|
||||
if (it->first == "debug"){
|
||||
static std::string debugLvlStr;
|
||||
debugLvlStr = JSON::Value((long long)Util::Config::printDebugLevel).asString();
|
||||
argarr[argnum++] = (char*)(it->second["option"].c_str());
|
||||
argarr[argnum++] = (char*)debugLvlStr.c_str();
|
||||
DEVEL_MSG("Setting debug for %s to %s", p["connector"].asStringRef().c_str(), debugLvlStr.c_str());
|
||||
}
|
||||
}
|
||||
if (p[it->first].asStringRef().size() > 0){
|
||||
argarr[argnum++] = (char*)(it->second["option"].c_str());
|
||||
argarr[argnum++] = (char*)(p[it->first].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -73,24 +84,6 @@ namespace Controller {
|
|||
if (pipedCapa.isMember("optional")){builPipedPart(p, argarr, argnum, pipedCapa["optional"]);}
|
||||
}
|
||||
|
||||
void handleMsg(void * err){
|
||||
char buf[1024];
|
||||
FILE * output = fdopen((long long int)err, "r");
|
||||
while (fgets(buf, 1024, output)){
|
||||
unsigned int i = 0;
|
||||
while (i < 9 && buf[i] != ' '){
|
||||
++i;
|
||||
}
|
||||
if(i < 9){
|
||||
buf[i] = 0;
|
||||
Log(buf,buf+i+1);
|
||||
}else{
|
||||
printf("%s\n",buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///\brief Checks current protocol coguration, updates state of enabled connectors if neccesary.
|
||||
///\param p An object containing all protocols.
|
||||
///\param capabilities An object containing the detected capabilities.
|
||||
|
@ -109,14 +102,18 @@ namespace Controller {
|
|||
long long counter = 0;
|
||||
|
||||
for (JSON::ArrIter ait = p.ArrBegin(); ait != p.ArrEnd(); ait++){
|
||||
( *ait).removeMember("online");
|
||||
std::string prevOnline = ( *ait)["online"].asString();
|
||||
#define connName (*ait)["connector"].asStringRef()
|
||||
if ( !(*ait).isMember("connector") || connName == ""){
|
||||
( *ait)["online"] = "Missing connector name";
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !capabilities["connectors"].isMember(connName)){
|
||||
Log("WARN", connName + " connector is enabled but doesn't exist on system! Ignoring connector.");
|
||||
( *ait)["online"] = "Not installed";
|
||||
if (( *ait)["online"].asString() != prevOnline){
|
||||
Log("WARN", connName + " connector is enabled but doesn't exist on system! Ignoring connector.");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -126,13 +123,17 @@ namespace Controller {
|
|||
for (JSON::ObjIter it = connCapa["required"].ObjBegin(); it != connCapa["required"].ObjEnd(); ++it){
|
||||
if ( !(*ait).isMember(it->first) || (*ait)[it->first].asStringRef().size() < 1){
|
||||
gotAll = false;
|
||||
Log("WARN", connName + " connector is missing required parameter " + it->first + "! Ignoring connector.");
|
||||
( *ait)["online"] = "Invalid configuration";
|
||||
if (( *ait)["online"].asString() != prevOnline){
|
||||
Log("WARN", connName + " connector is missing required parameter " + it->first + "! Ignoring connector.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!gotAll){continue;}
|
||||
}
|
||||
|
||||
( *ait).removeMember("online");
|
||||
/// \todo Check dependencies?
|
||||
|
||||
new_connectors[counter] = (*ait).toString();
|
||||
|
@ -164,9 +165,9 @@ namespace Controller {
|
|||
err = -1;
|
||||
Util::Procs::StartPiped(toConn(iter->first), argarr, &zero, &out, &err);//redirects output to out. Must make a new pipe, redirect std err
|
||||
if(err != -1){
|
||||
//spawn new thread where err is read, it reads err until there is nothing more to be read
|
||||
tthread::thread * msghandler = new tthread::thread(handleMsg, (void*)err);
|
||||
msghandler->detach();
|
||||
//spawn thread that reads stderr of process
|
||||
tthread::thread msghandler(Controller::handleMsg, (void*)(((char*)0) + err));
|
||||
msghandler.detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,4 +39,32 @@ namespace Controller {
|
|||
return File.good();
|
||||
}
|
||||
|
||||
/// Handles output of a Mist application, detecting and catching debug messages.
|
||||
/// Debug messages are automatically converted into Log messages.
|
||||
/// Closes the file descriptor on read error.
|
||||
/// \param err File descriptor of the stderr output of the process to monitor.
|
||||
void handleMsg(void * err){
|
||||
char buf[1024];
|
||||
FILE * output = fdopen((long long int)err, "r");
|
||||
while (fgets(buf, 1024, output)){
|
||||
unsigned int i = 0;
|
||||
while (i < 9 && buf[i] != '|' && buf[i] != 0){
|
||||
++i;
|
||||
}
|
||||
unsigned int j = i;
|
||||
while (j < 1024 && buf[j] != '\n' && buf[j] != 0){
|
||||
++j;
|
||||
}
|
||||
buf[j] = 0;
|
||||
if(i < 9){
|
||||
buf[i] = 0;
|
||||
Log(buf,buf+i+1);
|
||||
}else{
|
||||
printf("%s", buf);
|
||||
}
|
||||
}
|
||||
fclose(output);
|
||||
close((long long int)err);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,4 +14,6 @@ namespace Controller {
|
|||
/// Write contents to Filename.
|
||||
bool WriteFile(std::string Filename, std::string contents);
|
||||
|
||||
void handleMsg(void * err);
|
||||
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace Controller {
|
|||
///\param name The name of the stream
|
||||
///\param data The corresponding configuration values.
|
||||
void startStream(std::string name, JSON::Value & data){
|
||||
std::string prevState = data["error"].asStringRef();
|
||||
data["online"] = (std::string)"Checking...";
|
||||
data.removeMember("error");
|
||||
std::string URL;
|
||||
|
@ -45,8 +46,10 @@ namespace Controller {
|
|||
URL = data["source"].asString();
|
||||
}
|
||||
if (URL == ""){
|
||||
Log("STRM", "Error for stream " + name + "! Source parameter missing.");
|
||||
data["error"] = "Stream offline: Missing source parameter!";
|
||||
if (data["error"].asStringRef() != prevState){
|
||||
Log("STRM", "Error for stream " + name + "! Source parameter missing.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (URL.substr(0, 4) == "push"){
|
||||
|
@ -71,8 +74,10 @@ namespace Controller {
|
|||
data.removeMember("error");
|
||||
struct stat fileinfo;
|
||||
if (stat(URL.c_str(), &fileinfo) != 0 || S_ISDIR(fileinfo.st_mode)){
|
||||
Log("BUFF", "Warning for VoD stream " + name + "! File not found: " + URL);
|
||||
data["error"] = "Stream offline: Not found: " + URL;
|
||||
if (data["error"].asStringRef() != prevState){
|
||||
Log("BUFF", "Warning for VoD stream " + name + "! File not found: " + URL);
|
||||
}
|
||||
data["online"] = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -89,8 +94,10 @@ namespace Controller {
|
|||
}
|
||||
if ( !getMeta && data.isMember("meta") && data["meta"].isMember("tracks")){
|
||||
if ( !data["meta"] || !data["meta"]["tracks"]){
|
||||
Log("WARN", "Source file " + URL + " seems to be corrupt.");
|
||||
data["error"] = "Stream offline: Corrupt file?";
|
||||
if (data["error"].asStringRef() != prevState){
|
||||
Log("WARN", "Source file " + URL + " seems to be corrupt.");
|
||||
}
|
||||
data["online"] = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -118,8 +125,10 @@ namespace Controller {
|
|||
tmp_cmd[1] = (char*)URL.c_str();
|
||||
data["meta"] = JSON::fromString(Util::Procs::getOutputOf(tmp_cmd));
|
||||
if ( !data["meta"] || !data["meta"].isMember("tracks") || !data["meta"]["tracks"]){
|
||||
Log("WARN", "Source file " + URL + " seems to be corrupt.");
|
||||
data["error"] = "Stream offline: Corrupt file?";
|
||||
if (data["error"].asStringRef() != prevState){
|
||||
Log("WARN", "Source file " + URL + " seems to be corrupt.");
|
||||
}
|
||||
data["online"] = 0;
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue