Skip to content

[feat] fs.watch #3249

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Jun 24, 2023
Merged

[feat] fs.watch #3249

merged 18 commits into from
Jun 24, 2023

Conversation

cirospaciari
Copy link
Member

No description provided.

@github-actions
Copy link
Contributor

github-actions bot commented Jun 8, 2023

@cirospaciari 9 files with test failures on linux-x64:

  • test/bundler/bundler_browser.test.ts
  • test/bundler/esbuild/default.test.ts
  • test/bundler/esbuild/importstar.test.ts
  • test/cli/install/bunx.test.ts
  • test/js/bun/util/inspect.test.js
  • test/js/bun/websocket/websocket-server.test.ts
  • test/js/third_party/napi_create_external/napi-create-external.test.ts
  • test/js/third_party/prisma/prisma.test.ts
  • test/js/web/websocket/websocket.test.js

View test output

#42f1b6d40b33a952ac17a12bb17ee1aec007e152

@github-actions
Copy link
Contributor

github-actions bot commented Jun 8, 2023

@cirospaciari 8 files with test failures on linux-x64-baseline:

  • test/bundler/bundler_browser.test.ts
  • test/bundler/esbuild/default.test.ts
  • test/bundler/esbuild/importstar.test.ts
  • test/cli/install/bunx.test.ts
  • test/js/bun/util/inspect.test.js
  • test/js/bun/websocket/websocket-server.test.ts
  • test/js/third_party/prisma/prisma.test.ts
  • test/js/web/websocket/websocket.test.js

View test output

#42f1b6d40b33a952ac17a12bb17ee1aec007e152

@github-actions
Copy link
Contributor

github-actions bot commented Jun 8, 2023

@cirospaciari 12 files with test failures on bun-darwin-x64-baseline:

  • test/bundler/bundler_browser.test.ts
  • test/bundler/esbuild/default.test.ts
  • test/bundler/esbuild/importstar.test.ts
  • test/cli/install/bunx.test.ts
  • test/js/bun/spawn/spawn-streaming-stdin.test.ts
  • test/js/bun/sqlite/sqlite.test.js
  • test/js/bun/util/inspect.test.js
  • test/js/bun/util/sleepSync.test.ts
  • test/js/bun/websocket/websocket-server.test.ts
  • test/js/web/timers/setInterval.test.js
  • test/js/web/timers/setTimeout.test.js
  • test/js/web/websocket/websocket.test.js

View test output

#42f1b6d40b33a952ac17a12bb17ee1aec007e152

@github-actions
Copy link
Contributor

github-actions bot commented Jun 15, 2023

@cirospaciari 10 files with test failures on bun-darwin-aarch64:

  • test/bundler/bundler_browser.test.ts
  • test/bundler/esbuild/default.test.ts
  • test/bundler/esbuild/importstar.test.ts
  • test/cli/install/bunx.test.ts
  • test/js/bun/net/socket.test.ts
  • test/js/bun/test/test-test.test.ts
  • test/js/bun/util/inspect.test.js
  • test/js/bun/websocket/websocket-server.test.ts
  • test/js/web/fetch/fetch-leak.test.js
  • test/js/web/websocket/websocket.test.js

View test output

#42f1b6d40b33a952ac17a12bb17ee1aec007e152

@cirospaciari cirospaciari marked this pull request as ready for review June 16, 2023 11:20
@github-actions
Copy link
Contributor

github-actions bot commented Jun 18, 2023

prettier errors have been resolved. Thank you.

#42f1b6d40b33a952ac17a12bb17ee1aec007e152

@cirospaciari
Copy link
Member Author

cirospaciari commented Jun 22, 2023

@Jarred-Sumner

Today once initialized we never deinit this loop, but we can deinit it when no watchers are active

fn deinit(this: *FSEventsLoop) void {
// signal close and wait
this.enqueueTaskConcurrent(Task.New(FSEventsLoop, FSEventsLoop._stop).init(this));
this.thread.join();
const CF = CoreFoundation.get();
CF.Release(this.signal_source);
this.signal_source = null;
this.sem.deinit();
this.mutex.deinit();
if (this.watcher_count > 0) {
while (this.watchers.popOrNull()) |watcher| {
if (watcher) |w| {
// unlink watcher
w.loop = null;
}
}
}
this.watchers.deinitWithAllocator(bun.default_allocator);
bun.default_allocator.destroy(this);

This implementation is also using babylist to keep track of active stuff and we reuse free slots, not the optimal way but should be fine when using 1-100 watchers

var watchers = this.watchers.slice();
for (watchers, 0..) |w, i| {
if (w == null) {
watchers[i] = watcher;
this.watcher_count += 1;
break;
}
}

This is the main logic

for (loop.watchers.slice()) |watcher| {
if (watcher) |handle| {
for (paths, 0..) |path_ptr, i| {
var flags = event_flags[i];
var path = path_ptr[0..bun.len(path_ptr)];
// Filter out paths that are outside handle's request
if (path.len < handle.path.len or !bun.strings.startsWith(path, handle.path)) {
continue;
}
const is_file = (flags & kFSEventStreamEventFlagItemIsDir) == 0;
// Remove common prefix, unless the watched folder is "/"
if (!(handle.path.len == 1 and handle.path[0] == '/')) {
path = path[handle.path.len..];
// Ignore events with path equal to directory itself
if (path.len <= 1 and is_file) {
continue;
}
if (path.len == 0) {
// Since we're using fsevents to watch the file itself, path == handle.path, and we now need to get the basename of the file back
while (path.len > 0) {
if (bun.strings.startsWithChar(path, '/')) {
path = path[1..];
break;
} else {
path = path[1..];
}
}
// Created and Removed seem to be always set, but don't make sense
flags &= ~kFSEventsRenamed;
} else {
// Skip forward slash
path = path[1..];
}
}
// Do not emit events from subdirectories (without option set)
if (path.len == 0 or (bun.strings.containsChar(path, '/') and !handle.recursive)) {
continue;
}
var is_rename = true;
if ((flags & kFSEventsRenamed) == 0) {
if ((flags & kFSEventsModified) != 0 or is_file) {
is_rename = false;
}
}
handle.callback(handle.ctx, path, is_file, is_rename);

and we use 1 thread for all watchers and just filter by path like uv does, watcher.zig is using 1 thread per watcher and maybe we can refactor it to do the same as fs_events, relative path logic is also much simpler on fs_events loop.

@Jarred-Sumner Jarred-Sumner merged commit 069b42a into main Jun 24, 2023
@Jarred-Sumner Jarred-Sumner deleted the ciro/fs-watch branch June 24, 2023 06:24
@Jarred-Sumner
Copy link
Collaborator

🎉

@Electroid Electroid mentioned this pull request Jun 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants