index: update a status file while indexing

This commit is contained in:
Jean-Francois Dockes 2012-02-06 17:03:39 +01:00
parent 28e53931a6
commit f59e2e033a
5 changed files with 69 additions and 16 deletions

View File

@ -883,6 +883,10 @@ string RclConfig::getPidfile()
{
return path_cat(getConfDir(), "index.pid");
}
string RclConfig::getIdxStatusFile()
{
return path_cat(getConfDir(), "idxstatus.txt");
}
list<string>& RclConfig::getSkippedNames()
{

View File

@ -141,8 +141,10 @@ class RclConfig {
string getDbDir();
/** Get stoplist file name */
string getStopfile();
/** Get indexing pid file */
/** Get indexing pid file name */
string getPidfile();
/** Get indexing status file name */
string getIdxStatusFile();
/** Get list of skipped file names for current keydir */
list<string>& getSkippedNames();

View File

@ -102,6 +102,8 @@ bool ConfIndexer::index(bool resetbefore, ixType typestorun)
return false;
createAspellDict();
clearMimeHandlerCache();
if (m_updater)
m_updater->update(DbIxStatus::DBIXS_DONE, string());
return true;
}

View File

@ -36,7 +36,9 @@ class BeagleQueueIndexer;
class DbIxStatus {
public:
enum Phase {DBIXS_FILES, DBIXS_PURGE, DBIXS_STEMDB, DBIXS_CLOSING};
enum Phase {DBIXS_NONE,
DBIXS_FILES, DBIXS_PURGE, DBIXS_STEMDB, DBIXS_CLOSING,
DBIXS_DONE};
Phase phase;
string fn; // Last file processed
int docsdone; // Documents processed
@ -51,13 +53,17 @@ class DbIxStatusUpdater {
public:
DbIxStatus status;
virtual ~DbIxStatusUpdater(){}
virtual bool update() = 0;
// Convenience: change phase/fn and update
virtual bool update(DbIxStatus::Phase phase, const string& fn)
{
status.phase = phase;
status.fn = fn;
return update();
}
// To be implemented by user for sending info somewhere
virtual bool update() = 0;
};
/**

View File

@ -23,6 +23,7 @@
#include <errno.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <fcntl.h>
#include <iostream>
#include <list>
@ -76,29 +77,62 @@ static void cleanup()
// indexing routines.
int stopindexing;
// Mainly used to request indexing stop, we currently do not use the
// current file name
// Receive status updates from the ongoing indexing operation
// Also check for an interrupt request and return the info to caller which
// should subsequently orderly terminate what it is doing.
class MyUpdater : public DbIxStatusUpdater {
public:
virtual bool update() {
MyUpdater(RclConfig *config)
: m_prevphase(DbIxStatus::DBIXS_NONE)
{
m_fd = open(config->getIdxStatusFile().c_str(),
O_WRONLY|O_CREAT|O_TRUNC, 0600);
if (m_fd < 0)
LOGERR(("Can't open/create status file: [%s]\n",
config->getIdxStatusFile().c_str()));
}
virtual bool update()
{
// Update the status file. Avoid doing it too often
if (status.phase != m_prevphase || m_chron.millis() > 300) {
m_prevphase = status.phase;
m_chron.restart();
lseek(m_fd, 0, 0);
int fd1 = dup(m_fd);
FILE *fp = fdopen(fd1, "w");
fprintf(fp, "phase = %d\n", int(status.phase));
fprintf(fp, "docsdone = %d\n", status.docsdone);
fprintf(fp, "dbtotdocs = %d\n", status.dbtotdocs);
fprintf(fp, "fn = %s\n", status.fn.c_str());
ftruncate(m_fd, off_t(ftell(fp)));
// Flush data and closes fd1. m_fd still valid
fclose(fp);
}
if (stopindexing) {
return false;
}
// If we are in the monitor, we also need to check x status
// If we are in the monitor, we also need to check X11 status
// during the initial indexing pass (else the user could log
// out and the indexing would go on, not good (ie: if the user
// logs in again, the new recollindex will fail).
if ((op_flags & OPT_m) && !(op_flags & OPT_x) && !x11IsAlive()) {
LOGDEB(("X11 session went away during initial indexing pass\n"));
stopindexing = true;
return false;
LOGDEB(("X11 session went away during initial indexing pass\n"));
stopindexing = true;
return false;
}
return true;
}
private:
int m_fd;
Chrono m_chron;
DbIxStatus::Phase m_prevphase;
};
static MyUpdater updater;
static MyUpdater *updater;
static void sigcleanup(int sig)
{
@ -111,7 +145,7 @@ static void sigcleanup(int sig)
static bool makeIndexer(RclConfig *config)
{
if (!confindexer)
confindexer = new ConfIndexer(config, &updater);
confindexer = new ConfIndexer(config, updater);
if (!confindexer) {
cerr << "Cannot create indexer" << endl;
exit(1);
@ -300,6 +334,7 @@ int main(int argc, const char **argv)
}
bool rezero(op_flags & OPT_z);
Pidfile pidfile(config->getPidfile());
updater = new MyUpdater(config);
if (setpriority(PRIO_PROCESS, 0, 20) != 0) {
LOGINFO(("recollindex: can't setpriority(), errno %d\n", errno));
@ -383,8 +418,7 @@ int main(int argc, const char **argv)
}
}
}
confindexer = new ConfIndexer(config, &updater);
confindexer = new ConfIndexer(config, updater);
if (!confindexer->index(rezero, ConfIndexer::IxTAll) || stopindexing) {
LOGERR(("recollindex, initial indexing pass failed, not going into monitor mode\n"));
exit(1);
@ -412,13 +446,18 @@ int main(int argc, const char **argv)
} else {
lockorexit(&pidfile);
pidfile.write_pid();
confindexer = new ConfIndexer(config, &updater);
confindexer = new ConfIndexer(config, updater);
bool status = confindexer->index(rezero, ConfIndexer::IxTAll);
if (!status)
cerr << "Indexing failed" << endl;
if (!confindexer->getReason().empty())
cerr << confindexer->getReason() << endl;
if (updater) {
updater->status.phase = DbIxStatus::DBIXS_DONE;
updater->status.fn.clear();
updater->update();
}
return !status;
}
}