Add user interfaces for triggering an incremental in a running monitor

This commit is contained in:
Jean-Francois Dockes 2018-04-12 09:46:25 +02:00
parent 8559572c7e
commit 272a63104e
11 changed files with 180 additions and 50 deletions

View File

@ -90,6 +90,8 @@ index/fsfetcher.cpp \
index/fsfetcher.h \
index/fsindexer.cpp \
index/fsindexer.h \
index/idxstatus.h \
index/idxstatus.cpp \
index/mimetype.cpp \
index/mimetype.h \
index/rclmon.h \

View File

@ -1304,7 +1304,6 @@ string RclConfig::getConfdirPath(const char *varname, const char *dflt) const
}
}
return path_canon(result);
}
string RclConfig::getCacheDir() const

39
src/index/idxstatus.cpp Normal file
View File

@ -0,0 +1,39 @@
/* Copyright (C) 2017-2018 J.F.Dockes
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "idxstatus.h"
#include "rclconfig.h"
#include "conftree.h"
void readIdxStatus(RclConfig *config, DbIxStatus &status)
{
ConfSimple cs(config->getIdxStatusFile().c_str(), 1);
string val;
cs.get("phase", val);
status.phase = DbIxStatus::Phase(atoi(val.c_str()));
cs.get("fn", status.fn);
cs.get("docsdone", &status.docsdone);
cs.get("filesdone", &status.filesdone);
cs.get("fileerrors", &status.fileerrors);
cs.get("dbtotdocs", &status.dbtotdocs);
cs.get("totfiles", &status.totfiles);
string shm("0");
cs.get("hasmonitor", shm);
status.hasmonitor = stringToBool(shm);
}

56
src/index/idxstatus.h Normal file
View File

@ -0,0 +1,56 @@
/* Copyright (C) 2017-2018 J.F.Dockes
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _IDXSTATUS_H_INCLUDED_
#define _IDXSTATUS_H_INCLUDED_
#include <string>
// Current status of an indexing operation. This is updated in
// $RECOLL_CONFDIR/idxstatus.txt
class DbIxStatus {
public:
enum Phase {DBIXS_NONE,
DBIXS_FILES, DBIXS_PURGE, DBIXS_STEMDB, DBIXS_CLOSING,
DBIXS_MONITOR,
DBIXS_DONE};
Phase phase;
std::string fn; // Last file processed
int docsdone; // Documents actually updated
int filesdone; // Files tested (updated or not)
int fileerrors; // Failed files (e.g.: missing input handler).
int dbtotdocs; // Doc count in index at start
// Total files in index.This is actually difficult to compute from
// the index so it's preserved from last indexing
int totfiles;
// Is this indexer a monitoring one? This is a permanent value
// telling if option -m was set, not about what we are currently
// doing
bool hasmonitor{false};
void reset() {
phase = DBIXS_FILES;
fn.erase();
docsdone = filesdone = fileerrors = dbtotdocs = totfiles = 0;
}
DbIxStatus() {reset();}
};
class RclConfig;
extern void readIdxStatus(RclConfig *config, DbIxStatus &status);
#endif /* _IDXSTATUS_H_INCLUDED_ */

View File

@ -31,6 +31,7 @@
#endif
#include "mimehandler.h"
#include "pathut.h"
#include "idxstatus.h"
#ifdef RCL_USE_ASPELL
#include "rclaspell.h"

View File

@ -24,41 +24,13 @@
#include <vector>
#include <mutex>
using std::string;
using std::list;
using std::map;
using std::vector;
#include "rcldb.h"
#include "rcldoc.h"
#include "idxstatus.h"
class FsIndexer;
class BeagleQueueIndexer;
class DbIxStatus {
public:
enum Phase {DBIXS_NONE,
DBIXS_FILES, DBIXS_PURGE, DBIXS_STEMDB, DBIXS_CLOSING,
DBIXS_MONITOR,
DBIXS_DONE};
Phase phase;
string fn; // Last file processed
int docsdone; // Documents actually updated
int filesdone; // Files tested (updated or not)
int fileerrors; // Failed files (e.g.: missing input handler).
int dbtotdocs; // Doc count in index at start
// Total files in index.This is actually difficult to compute from
// the index so it's preserved from last indexing
int totfiles;
void reset() {
phase = DBIXS_FILES;
fn.erase();
docsdone = filesdone = fileerrors = dbtotdocs = totfiles = 0;
}
DbIxStatus() {reset();}
};
/** Callback to say what we're doing. If the update func returns false, we
* stop as soon as possible without corrupting state */
class DbIxStatusUpdater {
@ -130,14 +102,14 @@ class ConfIndexer {
static vector<string> getStemmerNames();
/** Index a list of files. No db cleaning or stemdb updating */
bool indexFiles(list<string> &files, int f = IxFNone);
bool indexFiles(std::list<std::string> &files, int f = IxFNone);
/** Update index for list of documents given as list of docs (out of query)
*/
bool updateDocs(vector<Rcl::Doc> &docs, IxFlag f = IxFNone);
/** Purge a list of files. */
bool purgeFiles(list<string> &files, int f = IxFNone);
bool purgeFiles(std::list<std::string> &files, int f = IxFNone);
/** Set in place reset mode */
void setInPlaceReset() {m_db.setInPlaceReset();}

View File

@ -58,6 +58,7 @@ using namespace std;
#endif
#include "execmd.h"
#include "checkretryfailed.h"
#include "idxstatus.h"
// Command line options
static int op_flags;
@ -141,6 +142,7 @@ class MyUpdater : public DbIxStatusUpdater {
m_file.set("dbtotdocs", status.dbtotdocs);
m_file.set("totfiles", status.totfiles);
m_file.set("fn", status.fn);
m_file.set("hasmonitor", status.hasmonitor);
m_file.holdWrites(false);
}
@ -483,12 +485,32 @@ Usage(FILE *where = stderr)
static RclConfig *config;
void lockorexit(Pidfile *pidfile)
static void lockorexit(Pidfile *pidfile, RclConfig *config)
{
pid_t pid;
if ((pid = pidfile->open()) != 0) {
cerr << "Can't become exclusive indexer: " << pidfile->getreason() <<
". Return (other pid?): " << pid << endl;
if (pid > 0) {
cerr << "Can't become exclusive indexer: " << pidfile->getreason()
<< ". Return (other pid?): " << pid << endl;
#ifndef _WIN32
// Have a look at the status file. If the other process is
// a monitor we can tell it to start an incremental pass
// by touching the configuration file
DbIxStatus status;
readIdxStatus(config, status);
if (status.hasmonitor) {
string cmd("touch ");
string path = path_cat(config->getConfDir(), "recoll.conf");
cmd += path;
system(cmd.c_str());
cerr << "Monitoring indexer process was notified of "
"indexing request\n";
}
#endif
} else {
cerr << "Can't become exclusive indexer: " << pidfile->getreason()
<< endl;
}
exit(1);
}
if (pidfile->write_pid() != 0) {
@ -688,7 +710,7 @@ int main(int argc, char **argv)
flushIdxReasons();
exit(status ? 0 : 1);
} else if (op_flags & (OPT_i|OPT_e)) {
lockorexit(&pidfile);
lockorexit(&pidfile, config);
list<string> filenames;
@ -746,7 +768,10 @@ int main(int argc, char **argv)
} else if (op_flags & OPT_m) {
if (argc != 0)
Usage();
lockorexit(&pidfile);
lockorexit(&pidfile, config);
if (updater) {
updater->status.hasmonitor = true;
}
if (!(op_flags&OPT_D)) {
LOGDEB("recollindex: daemonizing\n");
#ifndef _WIN32
@ -826,7 +851,7 @@ int main(int argc, char **argv)
cerr << "Not yet" << endl;
return 1;
} else {
lockorexit(&pidfile);
lockorexit(&pidfile, config);
makeIndexerOrExit(config, inPlaceReset);
bool status = confindexer->index(rezero, ConfIndexer::IxTAll,
indexerFlags);

View File

@ -30,24 +30,18 @@
#include "specialindex.h"
#include "readfile.h"
#include "snippets_w.h"
#include "idxstatus.h"
using namespace std;
// This is called from periodic100 if we started an indexer, or from
// the rclmain idxstatus file watcher, every time the file changes.
void RclMain::updateIdxStatus()
{
ConfSimple cs(theconfig->getIdxStatusFile().c_str(), 1);
QString msg = tr("Indexing in progress: ");
DbIxStatus status;
string val;
cs.get("phase", val);
status.phase = DbIxStatus::Phase(atoi(val.c_str()));
cs.get("fn", status.fn);
cs.get("docsdone", &status.docsdone);
cs.get("filesdone", &status.filesdone);
cs.get("fileerrors", &status.fileerrors);
cs.get("dbtotdocs", &status.dbtotdocs);
cs.get("totfiles", &status.totfiles);
readIdxStatus(theconfig, status);
QString msg = tr("Indexing in progress: ");
QString phs;
switch (status.phase) {
case DbIxStatus::DBIXS_NONE:phs=tr("None");break;
@ -153,6 +147,7 @@ void RclMain::periodic100()
} else {
Pidfile pidfile(theconfig->getPidfile());
pid_t pid = pidfile.open();
fileBumpIndexingAction->setEnabled(false);
if (pid == getpid()) {
// Locked by me
m_indexerState = IXST_NOTRUNNING;
@ -172,6 +167,13 @@ void RclMain::periodic100()
// Real time or externally started batch indexer running
m_indexerState = IXST_RUNNINGNOTMINE;
fileToggleIndexingAction->setText(tr("Stop &Indexing"));
DbIxStatus status;
readIdxStatus(theconfig, status);
if (status.hasmonitor) {
// Real-time indexer running. We can trigger an
// incremental pass
fileBumpIndexingAction->setEnabled(true);
}
fileToggleIndexingAction->setEnabled(true);
fileRebuildIndexAction->setEnabled(false);
actionSpecial_Indexing->setEnabled(false);
@ -292,6 +294,20 @@ void RclMain::toggleIndexing()
}
}
#ifndef _WIN32
void RclMain::bumpIndexing()
{
DbIxStatus status;
readIdxStatus(theconfig, status);
if (status.hasmonitor) {
string cmd("touch ");
string path = path_cat(theconfig->getConfDir(), "recoll.conf");
cmd += path;
system(cmd.c_str());
}
}
#endif
static void delay(int millisecondsWait)
{
QEventLoop loop;

View File

@ -170,6 +170,17 @@
<cstring>fileToggleIndexingAction</cstring>
</property>
</action>
<action name="fileBumpIndexingAction">
<property name="text">
<string>Trigger incremental pass</string>
</property>
<property name="name" stdset="0">
<cstring>fileBumpIndexingAction</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
</action>
<action name="fileRebuildIndexAction">
<property name="text">
<string>&amp;Rebuild index</string>

View File

@ -282,6 +282,7 @@ void RclMain::init()
// sc = new QShortcut(quitKeySeq, restable);
// connect(sc, SIGNAL (activated()), this, SLOT (fileExit()));
// A shortcut to get the focus back to the search entry.
QKeySequence seq("Ctrl+Shift+s");
QShortcut *sc = new QShortcut(seq, this);
@ -306,6 +307,11 @@ void RclMain::init()
this, SLOT(fileExit() ) );
connect(fileToggleIndexingAction, SIGNAL(triggered()),
this, SLOT(toggleIndexing()));
#ifndef _WIN32
fileMenu->insertAction(fileRebuildIndexAction, fileBumpIndexingAction);
connect(fileBumpIndexingAction, SIGNAL(triggered()),
this, SLOT(bumpIndexing()));
#endif
connect(fileRebuildIndexAction, SIGNAL(triggered()),
this, SLOT(rebuildIndex()));
connect(fileEraseDocHistoryAction, SIGNAL(triggered()),

View File

@ -123,6 +123,9 @@ public slots:
virtual void fileExit();
virtual void periodic100();
virtual void toggleIndexing();
#ifndef _WIN32
virtual void bumpIndexing();
#endif
virtual void rebuildIndex();
virtual void specialIndex();
virtual void startSearch(std::shared_ptr<Rcl::SearchData> sdata,