Giter VIP home page Giter VIP logo

backfill's Introduction

backfill

A JavaScript caching library for reducing build time.

๐Ÿ”Œ Easy to install: Simply wrap your build commands inside backfill -- [command]
โ˜๏ธ Remote cache: Store your cache on Azure Blob or as an npm package
โš™๏ธ Fully configurable: Smart defaults with cross-package and per-package configuration and environment variable overrides

backfill is under active development and should probably not be used in production, yet. We will initially focus on stability improvements. We will look into various optimization strategies, adding more customization, and introducing an API for only running scripts in packages that have changed and skipping others altogether.

Current prerequisites:

  • git (for running --audit)
  • yarn.lock and yarn workspaces (for optimized hashing)

These prerequisites can easily be loosened to make backfill work with npm, Rush, and Lerna.

Why

When you're working in a multi-package repo you don't want to re-build packages that haven't changed. By wrapping your build scripts inside backfill you enable storing and fetching of build output to and from a local or remote cache.

Backfill is based on two concepts:

  1. Hashing: It will hash the files of a package, its dependencies and the build command
  2. Caching: Using the hash key, it will look for build output from a local or remote cache. If there's a match, it will backfill the package using the cache. Otherwise, it will run the build command and persist the output to the cache.

Install

Install backfill using yarn:

$ yarn add --dev backfill

Usage - CLI

backfill -- [command]

Typically you would wrap your npm scripts inside backfill, like this:

{
  "name": "package",
  "scripts": {
    "build": "backfill -- tsc -b"
  }
}

--audit

Backfill can only bring back build output from the folders it was asked to cache. A package that modifies or adds files outside of the cached folder will not be brought back to the same state as when it was initially built. To help you debug this you can add --audit to your backfill command. It will listen to all file changes in your repo (it assumes you're in a git repo) while running the build command and then report on any files that got changed outside of the cache folder.

Configuration

Backfill will look for backfill.config.js in the package it was called from and among parent folders recursively and then combine those configs together.

To configure backfill, simply export a config object with the properties you wish to override:

module.exports = {
  cacheStorageConfig: {
    provider: "azure-blob",
    options: { ... }
  }
};

The default configuration object is:

{
  cacheStorageConfig: { provider: "local" },
  clearOutputFolder: false,
  internalCacheFolder: "node_modules/.cache/backfill",
  logFolder: "node_modules/.cache/backfill",
  logLevel: "info",
  mode: "READ_WRITE",
  name: "[name-of-package]",
  outputGlob: ["lib/**"],
  packageRoot: "path/to/package",
  producePerformanceLogs: false,
  validateOutput: false
}

The outputGlob is a list of globs describing the files you want to cache. outputGlob should be expressed as a relative path from the root of each package. If you want to cache package-a/lib, for instance, you'd write outputGlob: ["lib/**"]. If you also want to cache the pacakge-a/dist/bundles folder, you'd write outputGlob: ["lib/**", "dist/bundles/**"].

The configuration type is:

export type Config = {
  cacheStorageConfig: CacheStorageConfig;
  clearOutputFolder: boolean;
  internalCacheFolder: string;
  logFolder: string;
  logLevel: LogLevels;
  mode: "READ_ONLY" | "WRITE_ONLY" | "READ_WRITE" | "PASS";
  name: string;
  outputGlob: string[];
  packageRoot: string;
  performanceReportName?: string;
  producePerformanceLogs: boolean;
  validateOutput: boolean;
};

Environment variable

You can override configuration with environment variables. Backfill will also look for a .env-file in the root of your repository, and load those into the environment. This can be useful when you don't want to commit keys and secrets to your remote cache, or if you want to commit a read-only cache access key in the repo and override with a write and read access key in the PR build, for instance.

See getEnvConfig() in ./packages/config/src/envConfig.ts.

Set up remote cache

Microsoft Azure Blob Storage

To cache to a Microsoft Azure Blob Storage you need to provide a connection string and the container name. If you are configuring via backfill.config.js, you can use the following syntax:

module.exports = {
  cacheStorageConfig: {
    provider: "azure-blob",
    options: {
      connectionString: "...",
      container: "..."
      maxSize: 12345
    }
  }
};

Optionally, you can pass a credential along with a connectionString which does not have a SAS token. This is useful if you want to use a managed identity or interactive browser login. For example:

import { InteractiveBrowserCredential } from '@azure/identity'

module.exports = {
  cacheStorageConfig: {
    provider: "azure-blob",
    options: {
      connectionString: "https://<your-storage-account-name>.blob.core.windows.net",
      credential: new InteractiveBrowserCredential()
      container: "..."
      maxSize: 12345
    }
  }
};

Options

connectionString
retrieve this from the Azure Portal interface
container
the name of the blob storage container
maxSize (optional)
max size of a single package cache, in the number of bytes

You can also configure Microsoft Azure Blob Storage using environment variables.


BACKFILL_CACHE_PROVIDER="azure-blob"
BACKFILL_CACHE_PROVIDER_OPTIONS='{"connectionString":"...","container":"..."}'

Npm package

To cache to an NPM package you need to provide a package name and the registry URL of your package feed. This feed should probably be private. If you are configuring via backfill.config.js, you can use the following syntax:

module.exports = {
  cacheStorageConfig: {
    provider: "npm",
    options: {
      npmPackageName: "...",
      registryUrl: "...",
    },
  },
};

You can also provide a path to the .npmrc user config file, to provide auth details related to your package feed using the npmrcUserconfig field in options.

You can also configure NPM package cache using environment variables.

BACKFILL_CACHE_PROVIDER="npm"
BACKFILL_CACHE_PROVIDER_OPTIONS='{"npmPackageName":"...","registryUrl":"..."}'

Skipping cache locally

Sometimes in a local build environment, it is useful to compare hashes to determine whether to execute the task without having to explicitly use a separate directory for the cache.

One caveat, this is using output that the task produced and one could possibly modify the output on a local development environment. For this reason, this is an opt-in behavior rather than the default.

The main benefit of using this strategy is a significant speed boost. Backfill can skip file copying of the cached outputs if it can rely on the built artifacts. Hashing is CPU-bound while caching is I/O-bound. Using this strategy results in speed gains but at the cost of needing to trust the outputs have not be altered by the user. While this usually is true, it is prudent to also provide a command in your repository to clean the output along with the saved hashes.

You can configure this from the backfill.config.js file this way:

module.exports = {
  cacheStorageConfig: {
    provider: "local-skip",
  },
};

Like other cases, you can also use the environment variable to choose this storage strategy:

BACKFILL_CACHE_PROVIDER="local-skip"

Custom storage providers

It is also possible to give backfill a custom storage provider altogether. This will give the ultimate flexibility in how to handle cache fetching and putting.

Configure the custom cache provider this way:

// CustomStorageProvider.ts
class CustomStorageProvider implements ICacheStorage {
  constructor(providerOptions: any, logger: Logger, cwd: string) {
    // do what is needed in regards to the options
  }

  async fetch(hash: string) {
    // some fetch logic
  }

  async put(hash: string, filesToCache: string[]) {
    // some putting logic
  }
}

module.exports.CustomStorageProvider = CustomStorageProvider;

// backfill configuration
const CustomStorageProvider = require("./custom-storage-provider");

module.exports = {
  cacheStorageConfig: {
    provider: (logger, cwd) =>
      new CustomStorageProvider(
        {
          key1: "value1",
          key2: "value2",
        },
        logger,
        cwd
      ),
  },
};

API

Backfill provides an API, this allows for more complex scenarios, and performance optimizations.

const backfill = require("backfill/lib/api");

const packagePath = getPath(packageName);

const logger = backfill.makeLogger("verbose", process.stdout, process.stderr);
const packagehash = await backfill.computeHash(packagePath, logger);

const fetchSuccess = await backfill.fetch(packagePath, packageHash, logger);

if (!fetchSuccess) {
  await runBuildCommand();
  await backfill.put(packagePath, packageHash, logger);
}

Performance Logs

You can optionally output performance logs to disk. If turned on, backfill will output a log file after each run with performance metrics. Each log file is formatted as a JSON file. You can turn performance logging by setting producePerformanceLogs: true in backfill.config.js.

Contributing

Ways to contribute

This project welcomes contributions and suggestions.

Describing your changes

When submitting source code changes, be sure to accompany the changes with a change file. Change files can be generated with the yarn change command.

Contributor License Agreement (CLA)

Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

backfill's People

Contributors

adjective-object avatar altinokdarici avatar bweggersen avatar dependabot-preview[bot] avatar dependabot[bot] avatar dzearing avatar ecraig12345 avatar kenotron avatar microsoftopensource avatar msftgits avatar pavelchern avatar renovate[bot] avatar statm avatar threepointone avatar vincentbailly avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

backfill's Issues

Hashes of source files don't include the file names

Workflow:

  • build a package with backfill
  • rename a source file in this package
  • build again

Expected:

  • cache miss, the project is rebuilt
    Actual:
  • cache hit, the project is not rebuilt and the outdated artifacts are retrieved from cache.

Outdated hash-files among dependencies

Currently, backfill will look for a hash-file for each dependency. If it can find the hash-file, it will use that hash. It is possible that the hash is out of date, and we currently don't take this into account. As explained in the Readme, we assume that you're running all of your scripts through a tool such as lerna which runs your script in topological order. When this assumption holds, we can know that any hash file belonging to a dependency will be up to date. However, someone might be running backfill directly from a package, in which case their dependencies might have changed, and the hash file is out of date. It could give backfill a false positive, causing it to get a cache hit.

We could check the timestamp of the hash file against the newest file in that package. If it is out of date we could show a warning, force a rebuild, or fail with an error message. How would this work if there were circular dependencies? How would this work with transitive dependencies?

Consider upgrading to the latest version of yargs

Yargs tends to be a source of frequent security vulnerabilities, such as this. While we can dismiss the vulnerability in our tooling due to this being a dev dependnecy rather than an internal dependency, it's probably worthwhile to upgrade to the latest yargs anyway.

Outdated warning in documentation

The documentation states that backfill is not ready for production. This warning is out of date since it has been used in production for two years now

Don't look for a hash file unless the package is an internal package

Currently, backfill will always look for a hash file inside of every dependency. This is unnecessary as any dependency that lives inside a node_modules folder will not have a hash file. We should first determine if the package is internal and then look for a hash file.

Centralize Jest testing to the `utils-test` package

The utils-test package contains all of the fixtures and the Jest setup code. We should make it depend on Jest and expose a test runner to other packages so they don't have to depend on Jest. We should also make jest.config.js optional for the individual packages. This will simplify the creation of new packages and the maintenance of the Jest setup in backfill.

Watch for changes to cached builds

If I'm reading the code correctly, it looks like backfill will run and then exit, which is great for production builds.

One use case you might consider is to allow backfill to watch the package directory for changes if it serves up a cached build and then execute the build command so that it can be used with watch scripts. This allows people to use tools like wsrun to launch watchers for many packages in dev mode, but only actually spin up the watcher on either a cache miss or a local change.

I found this approach provided a good balance of performance and developer experience in a project where I wrote some one-off build caching scripts. On the other hand, this may be either a pathological use case or overly complicated.

Lockfile hashing

I was exploring how to add yarn's lockfile to the environment glob hash in our repo when I discovered rush's lockfile was not already present. After talking with @kenotron he mentioned that lockfile hashing causes issues and therefore is not included in the environment glob.

Beyond my yarn/rush hybrid scenario, I'm curious if there are other situations that could cause problems here. If a leaf package changes an internal dep that ends up changing a core dep used by a lot of packages due to yarn's hoisting algorithm, could this cause issues by not having the yarn.lock as part of the environment hash? It seems like this is a case where all packages using that dep should be rebuilt, but only the leaf package would be.

I'm creating this issue because some key stakeholders are gone but I want to make sure this doesn't slip through the cracks.

Add support for finding last known good cache

Sometimes we don't care about getting the exact cache match to the current package. Maybe we have cached a webpack cache. In that case we're fine if the webpack cache is a few commits behind. It will still improve a cold start.

We should add support to find the latest known good cache to the package and backfill it.

Incorrect hash used if file is modified and hashed twice within 100ns on Windows

This is an extreme edge case which is very unlikely to occur outside of tests and is probably not worth the effort to fix (if it's even possible), so this issue is mainly to serve as documentation.

getFileHash uses a cache based on the file modification time, and does not re-calculate the hash if the modification time is unchanged. This is a good approach for perf and usually doesn't cause any problems.

export async function getFileHash(
cwd: string,
filePath: string
): Promise<string> {
const fileAbsPath = path.join(cwd, filePath);
const stat = await fs.stat(fileAbsPath);
if (memo.has(fileAbsPath) && memo.get(fileAbsPath)!.has(stat.mtimeMs)) {
return memo.get(fileAbsPath)!.get(stat.mtimeMs)!;

However, the cache storage test was failing on Windows in CI (I couldn't repro locally) because a file that's changed in the code below was not being registered as changed. This was because the hash hadn't changed.

It turns out the reason the hash hadn't changed was because the CI build runs quickly enough that the file creation and modification happened within the same 100ns interval. This was fine on Mac and Linux which use filesystems that record mtimes with 1ns precision, but NTFS only records mtimes with 100ns precision. So on NTFS, the mtime wouldn't change and the cached hash would be used.

I worked around this in the test by adding a 1ms wait. Based on how backfill is actually used, such as in lage, it seems extremely unlikely that this would happen in a real scenario.

fs.writeFileSync(path.join(dir, "Changing"), "changing content");
await storage.fetch(hash);
// Wait 1ms to make sure the file modification time changes.
// WHY: hashFile uses the file modification time to determine if the hash
// needs to be recomputed. The filesystems typically used by Mac and Linux
// record these times at 1ns resolution, but NTFS uses 100ns resolution.
// So sometimes the test would fail on Windows if it ran too quickly.
await new Promise((resolve) => setTimeout(resolve, 1));
fs.writeFileSync(path.join(dir, "Changing"), "changing content now");
await storage.put(hash, ["**/*"]);
expect(storage.filesToCache).toEqual(["Changing"]);

npm cache is broken?

Hey,
npm-cache-strategy overwrites package.json files with the cache package.json.
Thanks

Add retry logic and fallback to build on dev machines

If a fetch or put fails, it should quickly retry and then fall back to a regular build. The timeout should be short as most packages might not take that long to build.

Related, there should also be support for determining if the device is offline, and if so, it could look for a local cache, and if not it should simply build.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Pending Approval

These branches will be created by Renovate only once you click their checkbox below.

  • Update devDependency typescript to ~4.9.0
  • Update actions/setup-node action to v4
  • Update dependency @rushstack/package-deps-hash to v4
  • Update dependency dotenv to v16
  • Update dependency filenamify to v5
  • Update dependency fs-extra to v10
  • Update dependency pkg-dir to v5
  • Update dependency set-value to v4
  • Update dependency tar-fs to v3
  • Update dependency tempy to v1
  • Update devDependency @types/fs-extra to v11
  • Update devDependency husky to v8
  • Update devDependency syncpack to v10
  • Update devDependency typescript to v5
  • Update yargs packages to v17 (major) (@types/yargs, yargs)
  • ๐Ÿ” Create all pending approval PRs at once ๐Ÿ”

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Ignored or Blocked

These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.

Detected dependencies

github-actions
.github/workflows/CI.yml
  • actions/checkout v4
  • actions/setup-node v3
.github/workflows/release.yml
  • actions/checkout v4
  • actions/setup-node v3
npm
package.json
  • @typescript-eslint/eslint-plugin ^5.52.0
  • @typescript-eslint/parser ^5.52.0
  • beachball ^2.31.8
  • cross-env ^7.0.3
  • eslint ^8.34.0
  • eslint-config-prettier ^8.6.0
  • eslint-plugin-import ^2.27.5
  • execa ^5.0.0
  • husky ^7.0.4
  • lage ^2.0.0
  • lint-staged ^12.5.0
  • lodash.merge ^4.6.2
  • prettier ~3.1.0
  • prettier-package-json ^2.8.0
  • resolve-from ^5.0.0
  • syncpack 8.5.14
  • typescript ~4.3.0
  • node >=14
  • set-value ^2.0.0
packages/backfill/package.json
  • anymatch ^3.0.3
  • chokidar ^3.2.1
  • execa ^5.0.0
  • find-up ^5.0.0
  • fs-extra ^8.1.0
  • globby ^11.0.0
  • yargs ^16.1.1
  • @types/fs-extra ^9.0.13
  • @types/jest ^29.0.0
  • @types/node ^14.18.36
  • @types/yargs ^15.0.15
  • jest ^29.0.0
  • ts-jest ^29.0.0
  • ts-mockito ^2.6.1
  • typescript ~4.3.0
  • node >=14
packages/cache/package.json
  • @azure/core-http ^3.0.0
  • @azure/storage-blob ^12.15.0
  • execa ^5.0.0
  • fs-extra ^8.1.0
  • globby ^11.0.0
  • p-limit ^3.0.0
  • tar-fs ^2.1.0
  • @types/fs-extra ^9.0.13
  • @types/jest ^29.0.0
  • @types/node ^14.18.36
  • @types/tar-fs ^2.0.1
  • jest ^29.0.0
  • ts-jest ^29.0.0
  • typescript ~4.3.0
  • node >=14
packages/config/package.json
  • @azure/core-http ^3.0.0
  • find-up ^5.0.0
  • pkg-dir ^4.2.0
  • @types/fs-extra ^9.0.13
  • @types/jest ^29.0.0
  • jest ^29.0.0
  • ts-jest ^29.0.0
  • typescript ~4.3.0
  • node >=14
packages/hasher/package.json
  • @rushstack/package-deps-hash ^3.2.4
  • fs-extra ^8.1.0
  • workspace-tools ^0.35.2
  • @types/fs-extra ^9.0.13
  • @types/jest ^29.0.0
  • jest ^29.0.0
  • ts-jest ^29.0.0
  • typescript ~4.3.0
  • node >=14
packages/logger/package.json
  • chalk ^4.1.1
  • filenamify ^4.1.0
  • fs-extra ^8.1.0
  • @types/fs-extra ^9.0.13
  • @types/node ^14.18.36
  • typescript ~4.3.0
  • node >=14
packages/sample-dependency/package.json
  • typescript ~4.3.0
packages/sample/package.json
  • typescript ~4.3.0
packages/utils-dotenv/package.json
  • dotenv ^8.1.0
  • find-up ^5.0.0
  • @types/node ^14.18.36
  • typescript ~4.3.0
  • node >=14
packages/utils-test/package.json
  • execa ^5.0.0
  • find-up ^5.0.0
  • fs-extra ^8.1.0
  • tempy ^0.7.1
  • @types/fs-extra ^9.0.13
  • @types/jest ^29.0.0
  • @types/node ^14.18.36
  • jest ^29.0.0
  • typescript ~4.3.0
packages/utils-tsconfig/package.json
nvm
.nvmrc
  • node 14

  • Check this box to trigger a request for Renovate to run again on this repository

Allow .dot files/directories to be properly copied back after caching

The cache is properly created for hidden (.dot) files and directories but these are not copied back after a cache hit since globby's default is to not include them:

const files = await globby(`**/*`, {
cwd: localCacheFolder,
});

These lines should either be:

    const files = await globby(`**/*`, {
      cwd: localCacheFolder,
      dot: true,
    });

Or they should be made configurable.

Don't download/fetch if the output folder is already up to date

Currently, backfill will create a hash and then try to download the content belonging to that hash. In many cases, this is unnecessary as the local output folder might already be up to date. Is there a way to figure out whether the output folder is up to date and then skip fetching?

We could create a local mapping between the hash of the output-folder and the hash of the package. Then, on a later run, after we have created a hash of the package, we could create a hash of the output folder and then do a lookup to see if the output folder hash points to the package hash. In which case we don't have to even do a fetch.

This problem might be related to the clearOutputFolder config option. This value is false by default, which means the output folder doesn't get cleared between runs and between scripts that might be outputting to the same output folder in the same package (i.e. prepare and build). It is possible that hashing the output folder might not work well, as the output folder might change too often.

outputFolders -> outputHashGlob

There may be cases where there are overlaps between the folder from hashGlob and outputFolder - for example, we generate these .scss.ts files.

Support caching multiple output folders

Some packages output to multiple output folders. We should either support caching multiple output folders or maybe allow each backfill command to specify an output folder, or maybe something else.

Add support for using Azure Dev Ops pipeline caching

Azure Devops has added the pipeline caching feature which enables sharing the output of a previous build to speed up the outputs of the next build. This has a dedicated Azure Devops task and handles some security/compliance concerns necessary for using backfill in the Office 365 engineering system.

It would be great to see what overlap there is between backfill and ADO pipeline caching and adding first class support for using pipeline caching as a storage location for backfill

Performance Idea

This is a cool project!

I was curious how this project approached various scenarios, after doing so I believe I can share some past findings and alternative approaches that may be of use to you.

Specifically finding package.json's recursively across a large dep graph with duplicates can easily consume a large amount of time (in some of our applications this alone could take many minutes) (although our approach did traverse node_modules, which amplifies this problem)

The existing approach ->

const packageRoot = await findUp("package.json", { cwd });

To mitigate this problem, some collaborators and I implemented a pretty fast approach that worked well for our use cases ultimately turning those minutes into seconds in the largest of our applications.

Our approach does the following:

  • carefully avoids unnecessary IO
  • added various levels of memoization, which by default mimics that of nodes require but is configurable to suit most use cases.

When profiling slow builds, we noticed many such problems and ended up extracting our approach for reuse. If you are interested, it can be found here -> https://github.com/stefanpenner/resolve-package-path

Local cache hits max filename length on Windows

The files stored in the local cache can easily hit the max filename length on Windows.
This is because the local cache reproduces the folder structure of the cached package in a location which already has a long path.

The behavior of the backfill cache when this happens in unpredictable, backfill may fail, backfill may silently fail to restore the impacted files.

More investigation is needed to observe what are the exact consequences of this bug.

Confusion over dependencies between yarn workspace packages - yarn workspace dependencies don't trigger cache misses if dependent

Assuming there are 2 existing caches for workspace A and B and workspace A depends on workspace B.
If something changes now in workspace B and it causes it to rebuild, lage will still consider workspace A as a cache hit and will not rebuild it which causes an inconsistency:

This is the lage.config I'm using

const package = require("./package.json");

module.exports = {
  pipeline: {
    patch: ["^patch"],
    development: ["^development"],
    build: ["^build"]
  },
  npmClient: "yarn",
  cacheOptions: {
    outputGlob: [`${package["project-configuration"].buildDirectory}/**`],
    validateOutput: true,
    clearOutputFolder: true,
  },
};

For the package dependencies I simply use yarn workspaces and normal imports from on package to the other.

backfill API

I think it would be really nice to have backfill be opened up as an API to be integrated into other tools (I would like to absorb this into just-scripts, for example).

I also am wondering if parts of this software can be tweaked so that it works in terms of arbitrary (like a task) dependency rather than package dependency. This would allow us to generate a top level graph of all the tasks needed to run ahead of time and analyze the cache much better.

Support to allow list packages for caching

There is a use case where we have setup a maxsize for caching of our packages, now their is a need to allow caching for some packages which exceed this max size.
In current implementation if these packages need to be cached then the maxsize property must be increased to accommodate these packages, but this will not only cache the required packages but also other non required packages.
The proposal is to introduce another property which when set can allow caching of packages irrespective of the max size.

Other hashing strategies

We're currently using the folder-hash package to calculate the hash of the files in a package. For packages with very large files (~20k lines of code), the hashing has been observed to take over 10 seconds. On average, though, for most normal packages, the hashing takes around 80 ms.

Could we piggy-back the hash already created by git in some way? If so, would we create our own implementation or could we use another package, such as package-deps-hash?

We should consider making each hashing strategy a separate package so people can choose the strategy that fits their project best.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.