mirror of https://github.com/djcb/mu.git
cmd-server: Update to use the new Indexer
This commit is contained in:
parent
f9415caab7
commit
ba13a62e90
|
@ -24,6 +24,9 @@
|
|||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
#include <cstring>
|
||||
#include <glib.h>
|
||||
#include <glib/gprintf.h>
|
||||
|
@ -33,7 +36,7 @@
|
|||
#include "mu-cmd.hh"
|
||||
#include "mu-maildir.h"
|
||||
#include "mu-query.h"
|
||||
#include "mu-index.h"
|
||||
#include "index/mu-indexer.hh"
|
||||
#include "mu-store.hh"
|
||||
#include "mu-msg-part.h"
|
||||
#include "mu-contacts.hh"
|
||||
|
@ -49,14 +52,9 @@ using namespace Sexp;
|
|||
|
||||
using DocId = unsigned;
|
||||
|
||||
static std::mutex OutputLock;
|
||||
static std::atomic<bool> MuTerminate{false};
|
||||
|
||||
static void
|
||||
sig_handler (int sig)
|
||||
{
|
||||
MuTerminate = true;
|
||||
}
|
||||
|
||||
static void
|
||||
install_sig_handler (void)
|
||||
{
|
||||
|
@ -65,7 +63,7 @@ install_sig_handler (void)
|
|||
|
||||
MuTerminate = false;
|
||||
|
||||
action.sa_handler = sig_handler;
|
||||
action.sa_handler = [](int sig){ MuTerminate = true; };
|
||||
sigemptyset(&action.sa_mask);
|
||||
action.sa_flags = SA_RESETHAND;
|
||||
|
||||
|
@ -86,6 +84,8 @@ install_sig_handler (void)
|
|||
static void G_GNUC_PRINTF(1, 2)
|
||||
print_expr (const char* frm, ...)
|
||||
{
|
||||
std::lock_guard<std::mutex> l {OutputLock};
|
||||
|
||||
char *expr, *expr_orig;
|
||||
va_list ap;
|
||||
ssize_t rv;
|
||||
|
@ -208,6 +208,7 @@ print_sexps (MuMsgIter *iter, unsigned maxnum)
|
|||
}
|
||||
|
||||
|
||||
/// @brief object to manage the server-context for all commands.
|
||||
struct Context {
|
||||
Context(){}
|
||||
Context (const MuConfig *opts):
|
||||
|
@ -219,8 +220,8 @@ struct Context {
|
|||
throw Error(Error::Code::Store, &gerr/*consumes*/, "failed to create query");
|
||||
|
||||
g_message ("opened store @ %s; maildir @ %s; debug-mode %s",
|
||||
store_->database_path().c_str(),
|
||||
store_->root_maildir().c_str(),
|
||||
store_->metadata().database_path.c_str(),
|
||||
store_->metadata().root_maildir.c_str(),
|
||||
opts->debug ? "yes" : "no");
|
||||
}
|
||||
|
||||
|
@ -236,9 +237,10 @@ struct Context {
|
|||
throw Mu::Error (Error::Code::Internal, "no store");
|
||||
return *store_.get();
|
||||
}
|
||||
Indexer& indexer() { return store().indexer(); }
|
||||
|
||||
std::unique_ptr<Mu::Store> store_;
|
||||
|
||||
std::unique_ptr<Mu::Store> store_;
|
||||
MuQuery *query{};
|
||||
bool do_quit{};
|
||||
|
||||
|
@ -343,7 +345,6 @@ compose_handler (Context& context, const Parameters& params)
|
|||
Node::Seq compose_seq;
|
||||
compose_seq.add_prop(":compose", Node::make_symbol(std::string(ctype)));
|
||||
|
||||
// message optioss below checks extract-images / extract-encrypted
|
||||
if (ctype == "reply" || ctype == "forward" || ctype == "edit" || ctype == "resend") {
|
||||
|
||||
GError *gerr{};
|
||||
|
@ -410,7 +411,6 @@ contacts_handler (Context& context, const Parameters& params)
|
|||
seq.add_prop(":contacts", std::move(contacts));
|
||||
seq.add_prop(":tstamp", Node::make_string(format("%" G_GINT64_FORMAT,
|
||||
g_get_monotonic_time())));
|
||||
|
||||
/* dump the contacts cache as a giant sexp */
|
||||
print_expr(std::move(seq));
|
||||
}
|
||||
|
@ -708,79 +708,35 @@ help_handler (Context& context, const Parameters& params)
|
|||
}
|
||||
}
|
||||
|
||||
static MuError
|
||||
index_msg_cb (MuIndexStats *stats, void *user_data)
|
||||
static void
|
||||
print_stats (const Indexer::Progress& stats, const std::string& state)
|
||||
{
|
||||
if (MuTerminate)
|
||||
return MU_STOP;
|
||||
|
||||
if (stats->_processed % 1000)
|
||||
return MU_OK;
|
||||
|
||||
Node::Seq seq;
|
||||
|
||||
seq.add_prop(":info", Node::make_symbol("index"));
|
||||
seq.add_prop(":status", Node::make_symbol("running"));
|
||||
seq.add_prop(":processed", stats->_processed);
|
||||
seq.add_prop(":updated", stats->_updated);
|
||||
seq.add_prop(":status", Node::make_symbol(std::string{state}));
|
||||
seq.add_prop(":processed", stats.processed);
|
||||
seq.add_prop(":updated", stats.updated);
|
||||
seq.add_prop(":cleaned-up", stats.removed);
|
||||
|
||||
print_expr(std::move(seq));
|
||||
|
||||
return MU_OK;
|
||||
}
|
||||
|
||||
|
||||
static MuError
|
||||
index_and_maybe_cleanup (MuIndex *index, bool cleanup, bool lazy_check)
|
||||
{
|
||||
MuIndexStats stats{}, stats2{};
|
||||
mu_index_stats_clear (&stats);
|
||||
auto rv = mu_index_run (index, FALSE, lazy_check, &stats,
|
||||
index_msg_cb, NULL, NULL);
|
||||
if (rv != MU_OK && rv != MU_STOP)
|
||||
throw Error{Error::Code::Store, "indexing failed"};
|
||||
|
||||
mu_index_stats_clear (&stats2);
|
||||
if (cleanup) {
|
||||
GError *gerr{};
|
||||
rv = mu_index_cleanup (index, &stats2, NULL, NULL, &gerr);
|
||||
if (rv != MU_OK && rv != MU_STOP)
|
||||
throw Error{Error::Code::Store, &gerr, "cleanup failed"};
|
||||
}
|
||||
|
||||
Node::Seq seq;
|
||||
seq.add_prop(":info", Node::make_symbol("index"));
|
||||
seq.add_prop(":status", Node::make_symbol("complete"));
|
||||
seq.add_prop(":processed", stats._processed);
|
||||
seq.add_prop(":updated", stats._updated);
|
||||
seq.add_prop(":cleaned-up", stats2._cleaned_up);
|
||||
|
||||
print_expr(std::move(seq));
|
||||
|
||||
return MU_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
index_handler (Context& context, const Parameters& params)
|
||||
{
|
||||
GError *gerr{};
|
||||
const auto cleanup{get_bool_or(params, ":cleanup")};
|
||||
const auto lazy_check{get_bool_or(params, ":lazy-check")};
|
||||
Mu::Indexer::Config conf{};
|
||||
conf.cleanup = get_bool_or(params, ":cleanup");
|
||||
conf.lazy_check = get_bool_or(params, ":lazy-check");
|
||||
|
||||
auto store_ptr = reinterpret_cast<MuStore*>(&context.store());
|
||||
context.indexer().stop();
|
||||
|
||||
auto index{mu_index_new (store_ptr, &gerr)};
|
||||
if (!index)
|
||||
throw Error(Error::Code::Index, &gerr, "failed to create index object");
|
||||
|
||||
try {
|
||||
index_and_maybe_cleanup (index, cleanup, lazy_check);
|
||||
} catch (...) {
|
||||
mu_index_destroy(index);
|
||||
throw;
|
||||
context.indexer().start(conf);
|
||||
while (context.indexer().is_running()) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
print_stats (context.indexer().progress(), "running");
|
||||
}
|
||||
mu_index_destroy(index);
|
||||
mu_store_flush(store_ptr);
|
||||
print_stats (context.indexer().progress(), "complete");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -953,6 +909,7 @@ ping_handler (Context& context, const Parameters& params)
|
|||
const auto queries = get_string_vec (params, ":queries");
|
||||
Node::Seq qresults;
|
||||
for (auto&& q: queries) {
|
||||
|
||||
const auto count{mu_query_count_run (context.query, q.c_str())};
|
||||
const auto unreadq{format("flag:unread AND (%s)", q.c_str())};
|
||||
const auto unread{mu_query_count_run (context.query, unreadq.c_str())};
|
||||
|
@ -966,7 +923,7 @@ ping_handler (Context& context, const Parameters& params)
|
|||
}
|
||||
|
||||
Node::Seq addrs;
|
||||
for (auto&& addr: context.store().personal_addresses())
|
||||
for (auto&& addr: context.store().metadata().personal_addresses)
|
||||
addrs.add(std::string(addr));
|
||||
|
||||
Node::Seq seq;
|
||||
|
@ -975,8 +932,8 @@ ping_handler (Context& context, const Parameters& params)
|
|||
Node::Seq propseq;
|
||||
propseq.add_prop(":version", VERSION);
|
||||
propseq.add_prop(":personal-addresses", std::move(addrs));
|
||||
propseq.add_prop(":database-path", context.store().database_path());
|
||||
propseq.add_prop(":root-maildir", context.store().root_maildir());
|
||||
propseq.add_prop(":database-path", context.store().metadata().database_path);
|
||||
propseq.add_prop(":root-maildir", context.store().metadata().root_maildir);
|
||||
propseq.add_prop(":doccount", storecount);
|
||||
propseq.add_prop(":queries", std::move(qresults));
|
||||
seq.add_prop(":props", std::move(propseq));
|
||||
|
|
Loading…
Reference in New Issue