metro: concurrent builds fail due to shared use of /tmp/metro-cache/

Do you want to request a feature or report a bug?

bug

What is the current behavior?

Concurrently-running react-native builds often fail with e.g.:

ENOENT: no such file or directory, open '/tmp/metro-cache/03/2ed8513838f8bad0238a0a6032e415d1ea766f50f498e7d284ac6a05cb0b4000001234'

Error: ENOENT: no such file or directory, open '/tmp/metro-cache/03/2ed8513838f8bad0238a0a6032e415d1ea766f50f498e7d284ac6a05cb0b400001234'
    at Object.fs.openSync (fs.js:646:18)
    at Object.fs.writeFileSync (fs.js:1291:33)
    at FileStore.set (/Users/jenkins/src/node_modules/metro-cache/src/stores/FileStore.js:43:8)
    at Cache.set (/Users/jenkins/src/node_modules/metro-cache/src/Cache.js:96:31)
    at /Users/jenkins/src/node_modules/react-native/node_modules/metro/src/DeltaBundler/Transformer.js:127:13
    at Generator.next (<anonymous>)
    at step (/Users/jenkins/src/node_modules/react-native/node_modules/metro/src/DeltaBundler/Transformer.js:11:657)
    at /Users/jenkins/src/node_modules/react-native/node_modules/metro/src/DeltaBundler/Transformer.js:11:817
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)

If the current behavior is a bug, please provide the steps to reproduce and a minimal repository on GitHub that we can yarn install and yarn test.

What is the expected behavior?

I’d expect concurrently-running builds not to interfere with each other.

Please provide your exact Metro configuration and mention your Metro, node, yarn/npm version and operating system.

MacOS 10.13.3 node 8.9.4 npm 5.6.0 started seeing this when upgraded react-native from 0.55.4 to 0.57.2 => (from our package-lock.json) metro went from 0.30.2 to 0.47.1

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 7
  • Comments: 17 (2 by maintainers)

Most upvoted comments

Reset the cache react-native start --reset-cache

it might be fixed by providing custom TMPDIR folder for each build.

I am caching metro cache this way in gitlab ci

 script:
   - mkdir -p ${PROJECT_ROOT_DIR}/metro-cache
   - TMPDIR=${PROJECT_ROOT_DIR}/metro-cache react-native bundle --platform android --dev true --entry-file index.js --bundle-output index.android.bundle

  cache:
    key: ${CI_PROJECT_ID}-metro-cache-${CI_COMMIT_REF_NAME}
    paths:
      - ${PROJECT_ROOT_DIR}/metro-cache

Note that resetting the cache will only work if you have write permission to the newly created files and directories. If you are on a shared machine with your own login, then you can’t build and you can’t cleanup. Could you make the directory world writable so others can delete things?

Other tools typically cache these things in e.g. ~/.metro/ not /tmp. That’s presumably since /tmp is typically cleaned up on reboot and/or daily:

https://askubuntu.com/questions/20783/how-is-the-tmp-directory-cleaned-up https://superuser.com/questions/187071/in-macos-how-often-is-tmp-deleted

It was decided to store the artifacts in the OS default temp folder to delegate the cleaning of the cache to the OS, so Metro don’t have to worry about using too much space and the OS can decide to delete things based on available disk space/etc.

Another option would have been to store things in the home folder, this way Metro would have more control over the cleaning process but at the expenses of eating tons of HDD space

These OS scripts could delete directories while a build is running, which could cause a build failure. I’m seeing failures throughout the day though, so while I think this should probably be fixed, it’s not the main problem for me.

Metro caching should handle correctly external scripts deleting its temp folder, there may be a bug there that we can easily fix (e.g catching potential errors when writing to the cache to not fail). If you find any specific issue and you want to collaborate, I’ll be happy to review any PR on that topic 😃

Here’s the mtime-related cleanup code I found:

https://github.com/facebook/metro/blob/v0.50.0/packages/metro-cache/src/stores/AutoCleanFileStore.js#L82

Oh wow! I didn’t even know that we had an auto-cleaning cache store 😅 This was created by @CompuIves and it’s not being used by the default configuration. If you want you can use it and it will work, and this will allow you to have your cache folder e.g in ~/.metro as opposed to $TMPDIR.