Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Process files before adding them to
FileSystem
(re-land)
Summary: *This is a second attempt at D42846676 (1a81060), which was backed out due to bad Haste move handling - details in test plan.* `metro-file-map` takes raw crawl or watch results, "processes" them with a worker pool (compute hashes, read symlink targets), and makes metadata available to consumers. Previously, files would be added to the file `Map` before processing, and then additional metadata would be set, and finally (when watching) an event would be emitted. ## Problem This created a potential bug because files briefly exist, accessible in the `FileSystem` interface, in an intermediate state. Consider: 1. `foo.js` exists and has a SHA1 pre-calculated. 2. A change is made to `foo.js`, watcher backend emits a change event. 3. `FileSystem` is updated with the metadata of the unprocessed file, and an async worker starts processing. 4. Metro receives a bundle request for `foo.js`. It [fails hard](https://github.com/facebook/metro/blob/main/packages/metro/src/node-haste/DependencyGraph.js#L250) because the file has no calculated hash. 5. The worker completes and we populate the SHA1, and emit a 'change' event. This also complicates `TreeFS`, because symlink targets aren't guaranteed to be available to it. ## This diff This diff switches things around so that the `FileSystem` implementation is only updated with ready-processed `FileMetaData`, and events are emitted to `metro-file-map` consumers synchronously with updates to `FileSystem`. That means `FileSystem` will expose stale, complete state instead of fresher, incomplete state. Besides the fix above, this is okay and indeed preferable, because: - Two calls to `getSha1()` for the same file are guaranteed to return the same result unless there's been a 'change' event emitted on that file in the meantime. This is much more predictable. - In any case, any file system representation is *always* potentially stale - I/O isn't instant, OS events take time to propagate, so well behaved consumers should already be treating it as such. ## Summary Currently we 1. Remove all deleted files from the Haste map and file map simultaneously. 2. Update new/changed files in the file map (with incomplete metadata). 3. "Process" new/changed files, updating the file map with complete metadata and adding entries to the module map. In this diff: 1. Remove all deleted files from the Haste map and file map simultaneously. 2. Process new/changed files, filling in gaps in metadata and adding entries to the module map. 3. Update new/changed files in the file map (with complete metadata). *(In D42846676 (1a81060), 1 and 2 were reversed)* Changelog: **[Fix]** Race condition where a very recently modified file might have missing metadata. Reviewed By: huntie Differential Revision: D42930236 fbshipit-source-id: 983af37bc8829ebc8b403483177211b578905ffc
- Loading branch information