10
10
11
11
import org .apache .logging .log4j .LogManager ;
12
12
import org .apache .logging .log4j .Logger ;
13
- import org .elasticsearch .cluster .ClusterChangedEvent ;
14
- import org .elasticsearch .cluster .ClusterState ;
15
- import org .elasticsearch .cluster .ClusterStateListener ;
16
- import org .elasticsearch .cluster .node .DiscoveryNode ;
17
- import org .elasticsearch .cluster .service .ClusterService ;
18
13
import org .elasticsearch .common .Randomness ;
19
14
import org .elasticsearch .common .component .AbstractLifecycleComponent ;
20
15
import org .elasticsearch .reservedstate .service .FileChangedListener ;
27
22
import java .nio .file .WatchKey ;
28
23
import java .nio .file .WatchService ;
29
24
import java .nio .file .attribute .BasicFileAttributes ;
30
- import java .nio .file .attribute .FileTime ;
31
- import java .time .Instant ;
32
25
import java .util .List ;
33
26
import java .util .concurrent .CopyOnWriteArrayList ;
34
27
import java .util .concurrent .ExecutionException ;
52
45
* An implementation class should override {@link #processFileChanges()} to define
53
46
* the correct behavior.</p>
54
47
*/
55
- public abstract class AbstractFileWatchingService extends AbstractLifecycleComponent implements ClusterStateListener {
48
+ public abstract class AbstractFileWatchingService extends AbstractLifecycleComponent {
56
49
57
50
private static final Logger logger = LogManager .getLogger (AbstractFileWatchingService .class );
58
51
private static final int REGISTER_RETRY_COUNT = 5 ;
59
- private final ClusterService clusterService ;
60
52
private final Path watchedFileDir ;
61
53
private final Path watchedFile ;
62
54
private final List <FileChangedListener > eventListeners ;
@@ -65,10 +57,8 @@ public abstract class AbstractFileWatchingService extends AbstractLifecycleCompo
65
57
private FileUpdateState fileUpdateState ;
66
58
private WatchKey settingsDirWatchKey ;
67
59
private WatchKey configDirWatchKey ;
68
- private volatile boolean active = false ;
69
60
70
- public AbstractFileWatchingService (ClusterService clusterService , Path watchedFile ) {
71
- this .clusterService = clusterService ;
61
+ public AbstractFileWatchingService (Path watchedFile ) {
72
62
this .watchedFile = watchedFile ;
73
63
this .watchedFileDir = watchedFile .getParent ();
74
64
this .eventListeners = new CopyOnWriteArrayList <>();
@@ -84,40 +74,6 @@ public AbstractFileWatchingService(ClusterService clusterService, Path watchedFi
84
74
*/
85
75
protected abstract void processFileChanges () throws InterruptedException , ExecutionException , IOException ;
86
76
87
- /**
88
- * There may be an indication in cluster state that the file we are watching
89
- * should be re-processed: for example, after cluster state has been restored
90
- * from a snapshot. By default, we do nothing, but this method should be overridden
91
- * if different behavior is desired.
92
- * @param clusterState State of the cluster
93
- * @return false, by default
94
- */
95
- protected boolean shouldRefreshFileState (ClusterState clusterState ) {
96
- return false ;
97
- }
98
-
99
- /**
100
- * 'Touches' the settings file so the file watcher will re-processes it.
101
- * <p>
102
- * The file processing is asynchronous, the cluster state or the file must be already updated such that
103
- * the version information in the file is newer than what's already saved as processed in the
104
- * cluster state.
105
- *
106
- * For snapshot restores we first must restore the snapshot and then force a refresh, since the cluster state
107
- * metadata version must be reset to 0 and saved in the cluster state.
108
- */
109
- private void refreshExistingFileStateIfNeeded (ClusterState clusterState ) {
110
- if (watching ()) {
111
- if (shouldRefreshFileState (clusterState ) && Files .exists (watchedFile ())) {
112
- try {
113
- Files .setLastModifiedTime (watchedFile (), FileTime .from (Instant .now ()));
114
- } catch (IOException e ) {
115
- logger .warn ("encountered I/O error trying to update file settings timestamp" , e );
116
- }
117
- }
118
- }
119
- }
120
-
121
77
public final void addFileChangedListener (FileChangedListener listener ) {
122
78
eventListeners .add (listener );
123
79
}
@@ -131,33 +87,12 @@ public final Path watchedFile() {
131
87
}
132
88
133
89
@ Override
134
- public final void clusterChanged (ClusterChangedEvent event ) {
135
- ClusterState clusterState = event .state ();
136
- if (clusterState .nodes ().isLocalNodeElectedMaster ()) {
137
- startWatcher (clusterState );
138
- } else if (event .previousState ().nodes ().isLocalNodeElectedMaster ()) {
139
- stopWatcher ();
140
- }
90
+ protected void doStart () {
91
+ startWatcher ();
141
92
}
142
93
143
94
@ Override
144
- protected final void doStart () {
145
- // We start the file watcher when we know we are master from a cluster state change notification.
146
- // We need the additional active flag, since cluster state can change after we've shutdown the service
147
- // causing the watcher to start again.
148
- this .active = Files .exists (watchedFileDir ().getParent ());
149
- if (active == false ) {
150
- // we don't have a config directory, we can't possibly launch the file settings service
151
- return ;
152
- }
153
- if (DiscoveryNode .isMasterNode (clusterService .getSettings ())) {
154
- clusterService .addListener (this );
155
- }
156
- }
157
-
158
- @ Override
159
- protected final void doStop () {
160
- this .active = false ;
95
+ protected void doStop () {
161
96
logger .debug ("Stopping file watching service" );
162
97
stopWatcher ();
163
98
}
@@ -184,10 +119,9 @@ final boolean watchedFileChanged(Path path) throws IOException {
184
119
return (previousUpdateState == null || previousUpdateState .equals (fileUpdateState ) == false );
185
120
}
186
121
187
- private synchronized void startWatcher (ClusterState clusterState ) {
188
- if (watching () || active == false ) {
189
- refreshExistingFileStateIfNeeded (clusterState );
190
-
122
+ protected final synchronized void startWatcher () {
123
+ if (Files .exists (watchedFileDir .getParent ()) == false ) {
124
+ logger .warn ("File watcher for [{}] cannot start because grandparent directory does not exist" , watchedFile );
191
125
return ;
192
126
}
193
127
@@ -295,7 +229,7 @@ protected final void watcherThread() {
295
229
}
296
230
}
297
231
298
- final synchronized void stopWatcher () {
232
+ protected final synchronized void stopWatcher () {
299
233
if (watching ()) {
300
234
logger .debug ("stopping watcher ..." );
301
235
// make sure watch service is closed whatever
0 commit comments