real time indexer: monitor the configuration for changes and reexecute when needed
This commit is contained in:
parent
7ce1a5f2e4
commit
2c6b023a88
@ -893,6 +893,21 @@ string RclConfig::getDbDir()
|
|||||||
return path_canon(dbdir);
|
return path_canon(dbdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RclConfig::sourceChanged()
|
||||||
|
{
|
||||||
|
if (m_conf && m_conf->sourceChanged())
|
||||||
|
return true;
|
||||||
|
if (mimemap && mimemap->sourceChanged())
|
||||||
|
return true;
|
||||||
|
if (mimeconf && mimeconf->sourceChanged())
|
||||||
|
return true;
|
||||||
|
if (mimeview && mimeview->sourceChanged())
|
||||||
|
return true;
|
||||||
|
if (m_fields && m_fields->sourceChanged())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
string RclConfig::getStopfile()
|
string RclConfig::getStopfile()
|
||||||
{
|
{
|
||||||
return path_cat(getConfDir(), "stoplist.txt");
|
return path_cat(getConfDir(), "stoplist.txt");
|
||||||
|
|||||||
@ -88,6 +88,10 @@ class RclConfig {
|
|||||||
* constructor it it is the default one (~/.recoll) and it did
|
* constructor it it is the default one (~/.recoll) and it did
|
||||||
* not exist yet. */
|
* not exist yet. */
|
||||||
string getConfDir() {return m_confdir;}
|
string getConfDir() {return m_confdir;}
|
||||||
|
|
||||||
|
/** Check if the config files were modified since we read them */
|
||||||
|
bool sourceChanged();
|
||||||
|
|
||||||
/** Returns true if this is ~/.recoll */
|
/** Returns true if this is ~/.recoll */
|
||||||
bool isDefaultConfig();
|
bool isDefaultConfig();
|
||||||
/** Get the local value for /usr/local/share/recoll/ */
|
/** Get the local value for /usr/local/share/recoll/ */
|
||||||
|
|||||||
@ -65,7 +65,8 @@ class RclMonEvent {
|
|||||||
int evflags() {return m_etyp & 0xf0;}
|
int evflags() {return m_etyp & 0xf0;}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RclMonitorOption {RCLMON_NONE=0, RCLMON_NOFORK=1, RCLMON_NOX11=2};
|
enum RclMonitorOption {RCLMON_NONE=0, RCLMON_NOFORK=1, RCLMON_NOX11=2,
|
||||||
|
RCLMON_NOCONFCHECK=4};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Monitoring event queue. This is the shared object between the main thread
|
* Monitoring event queue. This is the shared object between the main thread
|
||||||
|
|||||||
@ -39,6 +39,7 @@
|
|||||||
#include "debuglog.h"
|
#include "debuglog.h"
|
||||||
#include "rclmon.h"
|
#include "rclmon.h"
|
||||||
#include "debuglog.h"
|
#include "debuglog.h"
|
||||||
|
#include "execmd.h"
|
||||||
#include "recollindex.h"
|
#include "recollindex.h"
|
||||||
#include "pathut.h"
|
#include "pathut.h"
|
||||||
#include "x11mon.h"
|
#include "x11mon.h"
|
||||||
@ -485,11 +486,11 @@ bool startMonitor(RclConfig *conf, int opts)
|
|||||||
switch (ev.evtype()) {
|
switch (ev.evtype()) {
|
||||||
case RclMonEvent::RCLEVT_MODIFY:
|
case RclMonEvent::RCLEVT_MODIFY:
|
||||||
case RclMonEvent::RCLEVT_DIRCREATE:
|
case RclMonEvent::RCLEVT_DIRCREATE:
|
||||||
LOGDEB(("Monitor: Modify/Check on %s\n", ev.m_path.c_str()));
|
LOGDEB0(("Monitor: Modify/Check on %s\n", ev.m_path.c_str()));
|
||||||
modified.push_back(ev.m_path);
|
modified.push_back(ev.m_path);
|
||||||
break;
|
break;
|
||||||
case RclMonEvent::RCLEVT_DELETE:
|
case RclMonEvent::RCLEVT_DELETE:
|
||||||
LOGDEB(("Monitor: Delete on %s\n", ev.m_path.c_str()));
|
LOGDEB0(("Monitor: Delete on %s\n", ev.m_path.c_str()));
|
||||||
// If this is for a directory (which the caller should
|
// If this is for a directory (which the caller should
|
||||||
// tell us because he knows), we should purge the db
|
// tell us because he knows), we should purge the db
|
||||||
// of all the subtree, because on a directory rename,
|
// of all the subtree, because on a directory rename,
|
||||||
@ -552,6 +553,11 @@ bool startMonitor(RclConfig *conf, int opts)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for a config change
|
||||||
|
if (!(opts & RCLMON_NOCONFCHECK) && o_reexec && conf->sourceChanged()) {
|
||||||
|
LOGDEB(("Rclmonprc: config changed, reexecuting myself\n"));
|
||||||
|
o_reexec->reexec();
|
||||||
|
}
|
||||||
// Lock queue before waiting again
|
// Lock queue before waiting again
|
||||||
rclEQ.lock();
|
rclEQ.lock();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,6 +45,7 @@ using namespace std;
|
|||||||
#include "recollindex.h"
|
#include "recollindex.h"
|
||||||
#include "fsindexer.h"
|
#include "fsindexer.h"
|
||||||
#include "rclionice.h"
|
#include "rclionice.h"
|
||||||
|
#include "execmd.h"
|
||||||
|
|
||||||
// Command line options
|
// Command line options
|
||||||
static int op_flags;
|
static int op_flags;
|
||||||
@ -63,6 +64,9 @@ static int op_flags;
|
|||||||
#define OPT_l 0x1000
|
#define OPT_l 0x1000
|
||||||
#define OPT_b 0x2000
|
#define OPT_b 0x2000
|
||||||
#define OPT_f 0x4000
|
#define OPT_f 0x4000
|
||||||
|
#define OPT_C 0x8000
|
||||||
|
|
||||||
|
ReExec *o_reexec;
|
||||||
|
|
||||||
// Globals for atexit cleanup
|
// Globals for atexit cleanup
|
||||||
static ConfIndexer *confindexer;
|
static ConfIndexer *confindexer;
|
||||||
@ -224,9 +228,10 @@ static const char usage [] =
|
|||||||
" Index everything according to configuration file\n"
|
" Index everything according to configuration file\n"
|
||||||
" -z : reset database before starting indexing\n"
|
" -z : reset database before starting indexing\n"
|
||||||
#ifdef RCL_MONITOR
|
#ifdef RCL_MONITOR
|
||||||
"recollindex -m [-w <secs>] -x [-D]\n"
|
"recollindex -m [-w <secs>] -x [-D] [-C]\n"
|
||||||
" Perform real time indexing. Don't become a daemon if -D is set.\n"
|
" Perform real time indexing. Don't become a daemon if -D is set.\n"
|
||||||
" -w sets number of seconds to wait before starting.\n"
|
" -w sets number of seconds to wait before starting.\n"
|
||||||
|
" -C disables monitoring config for changes/reexecuting.\n"
|
||||||
#ifndef DISABLE_X11MON
|
#ifndef DISABLE_X11MON
|
||||||
" -x disables exit on end of x11 session\n"
|
" -x disables exit on end of x11 session\n"
|
||||||
#endif /* DISABLE_X11MON */
|
#endif /* DISABLE_X11MON */
|
||||||
@ -271,10 +276,12 @@ void lockorexit(Pidfile *pidfile)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, const char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
string a_config;
|
string a_config;
|
||||||
int sleepsecs = 60;
|
int sleepsecs = 60;
|
||||||
|
o_reexec = new ReExec;
|
||||||
|
o_reexec->init(argc, argv);
|
||||||
|
|
||||||
thisprog = argv[0];
|
thisprog = argv[0];
|
||||||
argc--; argv++;
|
argc--; argv++;
|
||||||
@ -290,6 +297,7 @@ int main(int argc, const char **argv)
|
|||||||
a_config = *(++argv);
|
a_config = *(++argv);
|
||||||
argc--; goto b1;
|
argc--; goto b1;
|
||||||
#ifdef RCL_MONITOR
|
#ifdef RCL_MONITOR
|
||||||
|
case 'C': op_flags |= OPT_C; break;
|
||||||
case 'D': op_flags |= OPT_D; break;
|
case 'D': op_flags |= OPT_D; break;
|
||||||
#endif
|
#endif
|
||||||
case 'e': op_flags |= OPT_e; break;
|
case 'e': op_flags |= OPT_e; break;
|
||||||
@ -333,6 +341,8 @@ int main(int argc, const char **argv)
|
|||||||
cerr << "Configuration problem: " << reason << endl;
|
cerr << "Configuration problem: " << reason << endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
o_reexec->atexit(cleanup);
|
||||||
|
|
||||||
bool rezero(op_flags & OPT_z);
|
bool rezero(op_flags & OPT_z);
|
||||||
Pidfile pidfile(config->getPidfile());
|
Pidfile pidfile(config->getPidfile());
|
||||||
updater = new MyUpdater(config);
|
updater = new MyUpdater(config);
|
||||||
@ -433,6 +443,8 @@ int main(int argc, const char **argv)
|
|||||||
int opts = RCLMON_NONE;
|
int opts = RCLMON_NONE;
|
||||||
if (op_flags & OPT_D)
|
if (op_flags & OPT_D)
|
||||||
opts |= RCLMON_NOFORK;
|
opts |= RCLMON_NOFORK;
|
||||||
|
if (op_flags & OPT_C)
|
||||||
|
opts |= RCLMON_NOCONFCHECK;
|
||||||
if (op_flags & OPT_x)
|
if (op_flags & OPT_x)
|
||||||
opts |= RCLMON_NOX11;
|
opts |= RCLMON_NOX11;
|
||||||
bool monret = startMonitor(config, opts);
|
bool monret = startMonitor(config, opts);
|
||||||
|
|||||||
@ -25,4 +25,7 @@ extern bool createAuxDbs(RclConfig *config);
|
|||||||
|
|
||||||
extern int stopindexing;
|
extern int stopindexing;
|
||||||
|
|
||||||
|
class ReExec;
|
||||||
|
extern ReExec *o_reexec;
|
||||||
|
|
||||||
#endif /* _recollindex_h_included_ */
|
#endif /* _recollindex_h_included_ */
|
||||||
|
|||||||
@ -23,6 +23,7 @@
|
|||||||
#include <unistd.h> // for access(2)
|
#include <unistd.h> // for access(2)
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -145,13 +146,13 @@ void ConfSimple::parseinput(istream &input)
|
|||||||
|
|
||||||
|
|
||||||
ConfSimple::ConfSimple(int readonly, bool tildexp)
|
ConfSimple::ConfSimple(int readonly, bool tildexp)
|
||||||
: dotildexpand(tildexp), m_holdWrites(false)
|
: dotildexpand(tildexp), m_fmtime(0), m_holdWrites(false)
|
||||||
{
|
{
|
||||||
status = readonly ? STATUS_RO : STATUS_RW;
|
status = readonly ? STATUS_RO : STATUS_RW;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfSimple::ConfSimple(const string& d, int readonly, bool tildexp)
|
ConfSimple::ConfSimple(const string& d, int readonly, bool tildexp)
|
||||||
: dotildexpand(tildexp), m_holdWrites(false)
|
: dotildexpand(tildexp), m_fmtime(0), m_holdWrites(false)
|
||||||
{
|
{
|
||||||
status = readonly ? STATUS_RO : STATUS_RW;
|
status = readonly ? STATUS_RO : STATUS_RW;
|
||||||
|
|
||||||
@ -160,7 +161,7 @@ ConfSimple::ConfSimple(const string& d, int readonly, bool tildexp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ConfSimple::ConfSimple(const char *fname, int readonly, bool tildexp)
|
ConfSimple::ConfSimple(const char *fname, int readonly, bool tildexp)
|
||||||
: dotildexpand(tildexp), m_filename(fname), m_holdWrites(false)
|
: dotildexpand(tildexp), m_filename(fname), m_fmtime(0), m_holdWrites(false)
|
||||||
{
|
{
|
||||||
status = readonly ? STATUS_RO : STATUS_RW;
|
status = readonly ? STATUS_RO : STATUS_RW;
|
||||||
|
|
||||||
@ -193,6 +194,7 @@ ConfSimple::ConfSimple(const char *fname, int readonly, bool tildexp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
parseinput(input);
|
parseinput(input);
|
||||||
|
i_changed(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfSimple::StatusCode ConfSimple::getStatus() const
|
ConfSimple::StatusCode ConfSimple::getStatus() const
|
||||||
@ -204,6 +206,26 @@ ConfSimple::StatusCode ConfSimple::getStatus() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ConfSimple::sourceChanged()
|
||||||
|
{
|
||||||
|
return i_changed(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfSimple::i_changed(bool upd)
|
||||||
|
{
|
||||||
|
if (!m_filename.empty()) {
|
||||||
|
struct stat st;
|
||||||
|
if (stat(m_filename.c_str(), &st) == 0) {
|
||||||
|
if (m_fmtime != st.st_mtime) {
|
||||||
|
if (upd)
|
||||||
|
m_fmtime = st.st_mtime;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int ConfSimple::get(const string &nm, string &value, const string &sk) const
|
int ConfSimple::get(const string &nm, string &value, const string &sk) const
|
||||||
{
|
{
|
||||||
if (!ok())
|
if (!ok())
|
||||||
|
|||||||
@ -107,6 +107,7 @@ public:
|
|||||||
virtual list<string> getSubKeys() = 0;
|
virtual list<string> getSubKeys() = 0;
|
||||||
virtual list<string> getSubKeys(bool) = 0;
|
virtual list<string> getSubKeys(bool) = 0;
|
||||||
virtual bool holdWrites(bool) = 0;
|
virtual bool holdWrites(bool) = 0;
|
||||||
|
virtual bool sourceChanged() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -140,6 +141,9 @@ public:
|
|||||||
|
|
||||||
virtual ~ConfSimple() {};
|
virtual ~ConfSimple() {};
|
||||||
|
|
||||||
|
/** Origin file changed. Only makes sense if we read the data from a file */
|
||||||
|
virtual bool sourceChanged();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decide if we actually rewrite the backing-store after modifying the
|
* Decide if we actually rewrite the backing-store after modifying the
|
||||||
* tree.
|
* tree.
|
||||||
@ -252,6 +256,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
// Set if we're working with a file
|
// Set if we're working with a file
|
||||||
string m_filename;
|
string m_filename;
|
||||||
|
time_t m_fmtime;
|
||||||
// Configuration data submaps (one per subkey, the main data has a
|
// Configuration data submaps (one per subkey, the main data has a
|
||||||
// null subkey)
|
// null subkey)
|
||||||
map<string, map<string, string> > m_submaps;
|
map<string, map<string, string> > m_submaps;
|
||||||
@ -267,6 +272,7 @@ private:
|
|||||||
// Internal version of set: no RW checking
|
// Internal version of set: no RW checking
|
||||||
virtual int i_set(const string &nm, const string &val,
|
virtual int i_set(const string &nm, const string &val,
|
||||||
const string &sk, bool init = false);
|
const string &sk, bool init = false);
|
||||||
|
bool i_changed(bool upd);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -366,6 +372,16 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool sourceChanged()
|
||||||
|
{
|
||||||
|
typename list<T*>::const_iterator it;
|
||||||
|
for (it = m_confs.begin();it != m_confs.end();it++) {
|
||||||
|
if ((*it)->sourceChanged())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual int get(const string &name, string &value, const string &sk) const
|
virtual int get(const string &name, string &value, const string &sk) const
|
||||||
{
|
{
|
||||||
typename list<T*>::const_iterator it;
|
typename list<T*>::const_iterator it;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user