1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
#pragma once
#include <Core/BackgroundSchedulePool.h>
#include <atomic>
#include <memory>
#include <string>
namespace DB
{
class FileLogDirectoryWatcher;
class DirectoryWatcherBase : WithContext
{
/// Most of code in this class is copy from the Poco project:
/// https://github.com/ClickHouse-Extras/poco/blob/clickhouse/Foundation/src/DirectoryWatcher.cpp
/// This class is used to get notifications about changes
/// to the filesystem, more precisely, to a specific
/// directory. Changes to a directory are reported via
/// events.
///
/// A thread will be created that watches the specified
/// directory for changes. Events are reported in the context
/// of this thread.
///
/// Note that changes to files in subdirectories of the watched
/// directory are not reported. Separate DirectoryWatcher objects
/// must be created for these directories if they should be watched.
public:
enum DirectoryEventType
{
DW_ITEM_ADDED = 1,
/// A new item has been created and added to the directory.
DW_ITEM_REMOVED = 2,
/// An item has been removed from the directory.
DW_ITEM_MODIFIED = 4,
/// An item has been modified.
DW_ITEM_MOVED_FROM = 8,
/// An item has been renamed or moved. This event delivers the old name.
DW_ITEM_MOVED_TO = 16
/// An item has been renamed or moved. This event delivers the new name.
};
enum DirectoryEventMask
{
/// Enables all event types.
DW_FILTER_ENABLE_ALL = 31,
/// Disables all event types.
DW_FILTER_DISABLE_ALL = 0
};
struct DirectoryEvent
{
DirectoryEvent(const std::string & f, DirectoryEventType ev) : path(f), event(ev) { }
/// The directory or file that has been changed.
const std::string path;
/// The kind of event.
DirectoryEventType event;
};
DirectoryWatcherBase() = delete;
DirectoryWatcherBase(const DirectoryWatcherBase &) = delete;
DirectoryWatcherBase & operator=(const DirectoryWatcherBase &) = delete;
/// Creates a DirectoryWatcher for the directory given in path.
/// To enable only specific events, an eventMask can be specified by
/// OR-ing the desired event IDs (e.g., DW_ITEM_ADDED | DW_ITEM_MODIFIED).
explicit DirectoryWatcherBase(
FileLogDirectoryWatcher & owner_, const std::string & path_, ContextPtr context_, int event_mask_ = DW_FILTER_ENABLE_ALL);
~DirectoryWatcherBase();
/// Returns the value of the eventMask passed to the constructor.
int eventMask() const { return event_mask; }
/// Returns the directory being watched.
const std::string & directory() const;
void watchFunc();
protected:
void start();
void stop();
private:
FileLogDirectoryWatcher & owner;
using TaskThread = BackgroundSchedulePool::TaskHolder;
TaskThread watch_task;
std::atomic<bool> stopped{false};
const std::string path;
int event_mask;
uint64_t milliseconds_to_wait;
int fd;
};
}
|