Merge branch 'fix_history_bugs' of https://github.com/kuskarov/ClickHouse into kuskarov-fix_history_bugs

This commit is contained in:
Alexey Milovidov 2020-06-07 19:36:36 +03:00
commit 85aee18d24
2 changed files with 42 additions and 3 deletions

View File

@ -4,6 +4,7 @@
#include <string.h>
#include <unistd.h>
#include <functional>
#include <sys/file.h>
namespace
{
@ -24,7 +25,29 @@ ReplxxLineReader::ReplxxLineReader(
using Replxx = replxx::Replxx;
if (!history_file_path.empty())
rx.history_load(history_file_path);
{
history_file_fd = open(history_file_path.c_str(), O_RDWR);
if (history_file_fd < 0)
{
rx.print("Open of history file failed: %s\n", strerror(errno));
}
else
{
if (flock(history_file_fd, LOCK_SH))
{
rx.print("Shared lock of history file failed: %s\n", strerror(errno));
}
else
{
rx.history_load(history_file_path);
if (flock(history_file_fd, LOCK_UN))
{
rx.print("Unlock of history file failed: %s\n", strerror(errno));
}
}
}
}
auto callback = [&suggest] (const String & context, size_t context_size)
{
@ -49,8 +72,8 @@ ReplxxLineReader::ReplxxLineReader(
ReplxxLineReader::~ReplxxLineReader()
{
if (!history_file_path.empty())
rx.history_save(history_file_path);
if (close(history_file_fd))
rx.print("Close of history file failed: %s\n", strerror(errno));
}
LineReader::InputStatus ReplxxLineReader::readOneLine(const String & prompt)
@ -68,7 +91,20 @@ LineReader::InputStatus ReplxxLineReader::readOneLine(const String & prompt)
void ReplxxLineReader::addToHistory(const String & line)
{
// locking history file to prevent from inconsistent concurrent changes
bool locked = false;
if (flock(history_file_fd, LOCK_EX))
rx.print("Lock of history file failed: %s\n", strerror(errno));
else
locked = true;
rx.history_add(line);
// flush changes to the disk
rx.history_save(history_file_path);
if (locked && 0 != flock(history_file_fd, LOCK_UN))
rx.print("Unlock of history file failed: %s\n", strerror(errno));
}
void ReplxxLineReader::enableBracketedPaste()

View File

@ -17,4 +17,7 @@ private:
void addToHistory(const String & line) override;
replxx::Replxx rx;
// used to call flock() to synchronize multiple clients using same history file
int history_file_fd = -1;
};