| @@ -213,7 +213,7 @@ void State::clearBusy(Connection & conn, time_t stopTime) | ||||
| } | ||||
|  | ||||
|  | ||||
| int State::allocBuildStep(pqxx::work & txn, Build::ptr build) | ||||
| unsigned int State::allocBuildStep(pqxx::work & txn, Build::ptr build) | ||||
| { | ||||
|     /* Acquire an exclusive lock on BuildSteps to ensure that we don't | ||||
|        race with other threads creating a step of the same build. */ | ||||
| @@ -224,10 +224,10 @@ int State::allocBuildStep(pqxx::work & txn, Build::ptr build) | ||||
| } | ||||
|  | ||||
|  | ||||
| int State::createBuildStep(pqxx::work & txn, time_t startTime, Build::ptr build, Step::ptr step, | ||||
| unsigned int State::createBuildStep(pqxx::work & txn, time_t startTime, Build::ptr build, Step::ptr step, | ||||
|     const std::string & machine, BuildStatus status, const std::string & errorMsg, BuildID propagatedFrom) | ||||
| { | ||||
|     int stepNr = allocBuildStep(txn, build); | ||||
|     unsigned int stepNr = allocBuildStep(txn, build); | ||||
|  | ||||
|     txn.parameterized | ||||
|         ("insert into BuildSteps (build, stepnr, type, drvPath, busy, startTime, system, status, propagatedFrom, errorMsg, stopTime, machine) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)") | ||||
| @@ -254,7 +254,7 @@ int State::createBuildStep(pqxx::work & txn, time_t startTime, Build::ptr build, | ||||
|  | ||||
|  | ||||
| void State::finishBuildStep(pqxx::work & txn, time_t startTime, time_t stopTime, unsigned int overhead, | ||||
|     BuildID buildId, int stepNr, const std::string & machine, BuildStatus status, | ||||
|     BuildID buildId, unsigned int stepNr, const std::string & machine, BuildStatus status, | ||||
|     const std::string & errorMsg, BuildID propagatedFrom) | ||||
| { | ||||
|     assert(startTime); | ||||
| @@ -420,20 +420,21 @@ void State::logCompressor() | ||||
|     while (true) { | ||||
|         try { | ||||
|  | ||||
|             Path logPath; | ||||
|             CompressionItem item; | ||||
|             { | ||||
|                 auto logCompressorQueue_(logCompressorQueue.lock()); | ||||
|                 while (logCompressorQueue_->empty()) | ||||
|                     logCompressorQueue_.wait(logCompressorWakeup); | ||||
|                 logPath = logCompressorQueue_->front(); | ||||
|                 item = logCompressorQueue_->front(); | ||||
|                 logCompressorQueue_->pop(); | ||||
|             } | ||||
|  | ||||
|             if (!pathExists(logPath)) continue; | ||||
|             if (!pathExists(item.logPath)) continue; | ||||
|  | ||||
|             printMsg(lvlChatty, format("compressing log file ‘%1%’") % logPath); | ||||
|             printMsg(lvlChatty, format("compressing log file ‘%1%’") % item.logPath); | ||||
|  | ||||
|             Path tmpPath = logPath + ".bz2.tmp"; | ||||
|             Path dstPath = item.logPath + ".bz2"; | ||||
|             Path tmpPath = dstPath + ".tmp"; | ||||
|  | ||||
|             AutoCloseFD fd = open(tmpPath.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644); | ||||
|  | ||||
| @@ -442,7 +443,7 @@ void State::logCompressor() | ||||
|             Pid pid = startProcess([&]() { | ||||
|                 if (dup2(fd, STDOUT_FILENO) == -1) | ||||
|                     throw SysError("cannot dup output pipe to stdout"); | ||||
|                 execlp("bzip2", "bzip2", "-c", logPath.c_str(), nullptr); | ||||
|                 execlp("bzip2", "bzip2", "-c", item.logPath.c_str(), nullptr); | ||||
|                 throw SysError("cannot start bzip2"); | ||||
|             }); | ||||
|  | ||||
| @@ -450,13 +451,18 @@ void State::logCompressor() | ||||
|  | ||||
|             if (res != 0) | ||||
|                 throw Error(format("bzip2 returned exit code %1% while compressing ‘%2%’") | ||||
|                     % res % logPath); | ||||
|                     % res % item.logPath); | ||||
|  | ||||
|             if (rename(tmpPath.c_str(), (logPath + ".bz2").c_str()) != 0) | ||||
|             if (rename(tmpPath.c_str(), dstPath.c_str()) != 0) | ||||
|                 throw SysError(format("renaming ‘%1%’") % tmpPath); | ||||
|  | ||||
|             if (unlink(logPath.c_str()) != 0) | ||||
|                 throw SysError(format("unlinking ‘%1%’") % logPath); | ||||
|             if (unlink(item.logPath.c_str()) != 0) | ||||
|                 throw SysError(format("unlinking ‘%1%’") % item.logPath); | ||||
|  | ||||
|             /* Run plugins. We do this after log compression to ensure | ||||
|                that the log file doesn't change while the plugins may | ||||
|                be accessing it. */ | ||||
|             enqueueNotificationItem({NotificationItem::Type::StepFinished, item.id, {}, item.stepNr, dstPath}); | ||||
|  | ||||
|         } catch (std::exception & e) { | ||||
|             printMsg(lvlError, format("log compressor: %1%") % e.what()); | ||||
| @@ -483,9 +489,22 @@ void State::notificationSender() | ||||
|             printMsg(lvlChatty, format("sending notification about build %1%") % item.id); | ||||
|  | ||||
|             Pid pid = startProcess([&]() { | ||||
|                 Strings argv({"hydra-notify", item.type == NotificationItem::Type::Started ? "build-started" : "build-finished", std::to_string(item.id)}); | ||||
|                 for (auto id : item.dependentIds) | ||||
|                     argv.push_back(std::to_string(id)); | ||||
|                 Strings argv; | ||||
|                 switch (item.type) { | ||||
|                     case NotificationItem::Type::BuildStarted: | ||||
|                         argv = {"hydra-notify", "build-started", std::to_string(item.id)}; | ||||
|                         for (auto id : item.dependentIds) | ||||
|                             argv.push_back(std::to_string(id)); | ||||
|                         break; | ||||
|                     case NotificationItem::Type::BuildFinished: | ||||
|                         argv = {"hydra-notify", "build-finished", std::to_string(item.id)}; | ||||
|                         for (auto id : item.dependentIds) | ||||
|                             argv.push_back(std::to_string(id)); | ||||
|                         break; | ||||
|                     case NotificationItem::Type::StepFinished: | ||||
|                         argv = {"hydra-notify", "step-finished", std::to_string(item.id), std::to_string(item.stepNr), item.logPath}; | ||||
|                         break; | ||||
|                 }; | ||||
|                 execvp("hydra-notify", (char * *) stringsToCharPtrs(argv).data()); // FIXME: remove cast | ||||
|                 throw SysError("cannot start hydra-notify"); | ||||
|             }); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user