Add user interfaces for triggering an incremental in a running monitor
This commit is contained in:
parent
8559572c7e
commit
272a63104e
@ -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 \
|
||||
|
||||
@ -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
39
src/index/idxstatus.cpp
Normal 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
56
src/index/idxstatus.h
Normal 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_ */
|
||||
@ -31,6 +31,7 @@
|
||||
#endif
|
||||
#include "mimehandler.h"
|
||||
#include "pathut.h"
|
||||
#include "idxstatus.h"
|
||||
|
||||
#ifdef RCL_USE_ASPELL
|
||||
#include "rclaspell.h"
|
||||
|
||||
@ -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();}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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>&Rebuild index</string>
|
||||
|
||||
@ -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()),
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user