Remove FileChange.isDirectory.
isDir can be a huge performance issue when watching a network based directory and can effectively block the thread almost completely in case of frequent file changes. This does mean than high-level code now needs to perform the check manually, if required, and the free information provided by inotify goes unused.
This commit is contained in:
parent
d7657b54e8
commit
86ee5c9477
5 changed files with 37 additions and 28 deletions
|
@ -8,7 +8,7 @@ import eventcore.core;
|
|||
import eventcore.internal.utils : print;
|
||||
import core.thread : Thread;
|
||||
import core.time : Duration, MonoTime, msecs;
|
||||
import std.file : exists, remove, rename, rmdirRecurse, mkdir;
|
||||
import std.file : exists, remove, rename, rmdirRecurse, mkdir, isDir;
|
||||
import std.format : format;
|
||||
import std.functional : toDelegate;
|
||||
import std.path : baseName, buildPath, dirName;
|
||||
|
@ -97,6 +97,20 @@ void expectChange(FileChange ch, bool expect_change)
|
|||
assert(!expect_change, format("Got no change, expected %s.", ch));
|
||||
return;
|
||||
}
|
||||
|
||||
// ignore different directory modification notifications on Windows as
|
||||
// opposed to the other systems
|
||||
while (pendingChanges.length) {
|
||||
auto pch = pendingChanges[0];
|
||||
if (pch.kind == FileChangeKind.modified) {
|
||||
auto p = buildPath(pch.baseDirectory, pch.directory, pch.name);
|
||||
if (!exists(p) || isDir(p)) {
|
||||
pendingChanges = pendingChanges[1 .. $];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(expect_change, "Got change although none was expected.");
|
||||
|
||||
|
@ -119,43 +133,43 @@ void testFile(string name, bool expect_change = true)
|
|||
{
|
||||
print("test %s CREATE %s", name, expect_change);
|
||||
auto fil = File(buildPath(testDir, name), "wt");
|
||||
expectChange(fchange(FileChangeKind.added, name, false), expect_change);
|
||||
expectChange(fchange(FileChangeKind.added, name), expect_change);
|
||||
|
||||
print("test %s MODIFY %s", name, expect_change);
|
||||
fil.write("test");
|
||||
fil.close();
|
||||
expectChange(fchange(FileChangeKind.modified, name, false), expect_change);
|
||||
expectChange(fchange(FileChangeKind.modified, name), expect_change);
|
||||
|
||||
print("test %s DELETE %s", name, expect_change);
|
||||
remove(buildPath(testDir, name));
|
||||
expectChange(fchange(FileChangeKind.removed, name, false), expect_change);
|
||||
expectChange(fchange(FileChangeKind.removed, name), expect_change);
|
||||
}
|
||||
|
||||
void testCreateDir(string name, bool expect_change = true)
|
||||
{
|
||||
print("test %s CREATEDIR %s", name, expect_change);
|
||||
mkdir(buildPath(testDir, name));
|
||||
expectChange(fchange(FileChangeKind.added, name, true), expect_change);
|
||||
expectChange(fchange(FileChangeKind.added, name), expect_change);
|
||||
}
|
||||
|
||||
void testRemoveDir(string name, bool expect_change = true)
|
||||
{
|
||||
print("test %s DELETEDIR %s", name, expect_change);
|
||||
rmdirRecurse(buildPath(testDir, name));
|
||||
expectChange(fchange(FileChangeKind.removed, name, true), expect_change);
|
||||
expectChange(fchange(FileChangeKind.removed, name), expect_change);
|
||||
}
|
||||
|
||||
void testRename(string from, string to, bool expect_change = true)
|
||||
{
|
||||
print("test %s RENAME %s %s", from, to, expect_change);
|
||||
rename(buildPath(testDir, from), buildPath(testDir, to));
|
||||
expectChange(fchange(FileChangeKind.removed, from, true), expect_change);
|
||||
expectChange(fchange(FileChangeKind.added, to, true), expect_change);
|
||||
expectChange(fchange(FileChangeKind.removed, from), expect_change);
|
||||
expectChange(fchange(FileChangeKind.added, to), expect_change);
|
||||
}
|
||||
|
||||
FileChange fchange(FileChangeKind kind, string name, bool is_dir)
|
||||
FileChange fchange(FileChangeKind kind, string name)
|
||||
{
|
||||
auto dn = dirName(name);
|
||||
if (dn == ".") dn = "";
|
||||
return FileChange(kind, testDir, dn, baseName(name), is_dir);
|
||||
return FileChange(kind, testDir, dn, baseName(name));
|
||||
}
|
||||
|
|
|
@ -5,8 +5,9 @@
|
|||
module test;
|
||||
|
||||
import eventcore.core;
|
||||
import std.file : exists, isDir, mkdir, remove, rmdirRecurse;
|
||||
import std.path : buildPath;
|
||||
import std.stdio : File, writefln;
|
||||
import std.file : exists, mkdir, remove, rmdirRecurse;
|
||||
import core.time : Duration, msecs;
|
||||
|
||||
bool s_done;
|
||||
|
@ -23,6 +24,11 @@ void main()
|
|||
scope (exit) rmdirRecurse(testDir);
|
||||
|
||||
auto id = eventDriver.watchers.watchDirectory(testDir, false, (id, ref change) {
|
||||
try {
|
||||
if (change.kind == FileChangeKind.modified && isDir(buildPath(change.baseDirectory, change.directory, change.name)))
|
||||
return;
|
||||
} catch (Exception e) assert(false, e.msg);
|
||||
|
||||
switch (s_cnt++) {
|
||||
default:
|
||||
import std.conv : to;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue