Git Product home page Git Product logo

cacache's Introduction

cacache npm version license Travis AppVeyor Coverage Status

cacache is a Node.js library for managing caches of keyed data that can be looked up both by key and by a digest of the content itself. This means that by-content lookups can be very very fast, and that stored content is shared by different keys if they point to the same data.

Install

$ npm install --save cacache

Table of Contents

Example

const cacache = require('cacache')
const fs = require('fs')

const tarball = '/path/to/mytar.tgz'
const cachePath = '/tmp/my-toy-cache'
const key = 'my-unique-key-1234'
let tarballDigest = null

// Cache it! Use `cachePath` as the root of the content cache
fs.createReadStream(
  tarball
).pipe(
  cacache.put.stream(
    cachePath, key
  ).on('digest', (d) => tarballDigest = d)
).on('end', function () {
  console.log(`Saved ${tarball} to ${cachePath}.`)
})

const destination = '/tmp/mytar.tgz'

// Copy the contents out of the cache and into their destination!
cacache.get.stream(
  cachePath, key
).pipe(
  fs.createWriteStream(destination)
).on('end', () => {
  console.log('done extracting!')
})

// The same thing, but skip the key index.
cacache.get.stream.byDigest(
  cachePath, tarballDigest
).pipe(
  fs.createWriteStream(destination)
).on('end', () => {
  console.log('done extracting using sha1!')
})

Features

  • Extraction by key or by content digest (shasum, etc).
  • Deduplicated content by digest -- two inputs with same key are only saved once
  • Consistency checks, both on insert and extract.
  • (Kinda) concurrency-safe and fault tolerant.
  • Streaming support.
  • Metadata storage.

Contributing

The cacache team enthusiastically welcomes contributions and project participation! There's a bunch of things you can do if you want to contribute! The Contributor Guide has all the information you need for everything from reporting bugs to contributing entire new features. Please don't hesitate to jump in if you'd like to, or even ask us questions if something isn't clear.

API

> cacache.ls(cache, cb)

Lists info for all entries currently in the cache as a single large object. Each entry in the object will be keyed by the unique index key, with corresponding get.info objects as the values.

Example
cacache.ls(cachePath, (err, allEntries) => {
  if (err) { throw err }
  console.log(allEntries)
})
// Output
{
  'my-thing': {
    key: 'my-thing',
    digest: 'deadbeef',
    path: '.testcache/content/deadbeef',
    time: 12345698490,
    metadata: {
      name: 'blah',
      version: '1.2.3',
      description: 'this was once a package but now it is my-thing'
    }
  },
  'other-thing': {
    key: 'other-thing',
    digest: 'bada55',
    path: '.testcache/content/bada55',
    time: 11992309289
  }
}

> cacache.get.stream(cache, key, [opts])

Returns a stream of the cached data identified by key.

If there is no content identified by key, or if the locally-stored data does not pass the validity checksum, an error will be emitted.

A sub-function, get.stream.byDigest may be used for identical behavior, except lookup will happen by content digest, bypassing the index entirely.

Example
cache.get.stream(
  cachePath, 'my-thing'
).pipe(
  fs.createWriteStream('./x.tgz')
)

cache.get.stream.byDigest(
  cachePath, 'deadbeef'
).pipe(
  fs.createWriteStream('./x.tgz')
)

> cacache.get.info(cache, key, cb)

Looks up key in the cache index, returning information about the entry if one exists. If an entry does not exist, the second argument to cb will be falsy.

Fields
  • key - Key the entry was looked up under. Matches the key argument.
  • digest - Content digest the entry refers to.
  • path - Filesystem path relative to cache argument where content is stored.
  • time - Timestamp the entry was first added on.
  • metadata - User-assigned metadata associated with the entry/content.
Example
cacache.get.info(cachePath, 'my-thing', (err, info) => {
  if (err) { throw err }
  console.log(info)
})
// Output
{
  key: 'my-thing',
  digest: 'deadbeef',
  path: '.testcache/content/deadbeef',
  time: 12345698490,
  metadata: {
    name: 'blah',
    version: '1.2.3',
    description: 'this was once a package but now it is my-thing'
  }
}

> cacache.put.stream(cache, key, stream, [opts])

Inserts data from a stream into the cache. Emits a digest event with the digest of written contents when it succeeds.

Example
request.get(
  'https://registry.npmjs.org/cacache/-/cacache-1.0.0.tgz'
).pipe(
  cacache.put.stream(
    cachePath, 'registry.npmjs.org|[email protected]'
  ).on('digest', d => console.log(`digest is ${d}`))
)

> cacache.put options

cacache.put functions have a number of options in common.

metadata

Arbitrary metadata to be attached to the inserted key.

size

If provided, the data stream will be verified to check that enough data was passed through. If there's more or less data than expected, an EBADSIZE error will be returned.

digest

If present, the pre-calculated digest for the inserted content. If this option if provided and does not match the post-insertion digest, insertion will fail.

To control the hashing algorithm, use opts.hashAlgorithm.

hashAlgorithm

Default: 'sha1'

Hashing algorithm to use when calculating the digest for inserted data. Can use any algorithm supported by Node.js' crypto module.

uid/gid

If provided, cacache will do its best to make sure any new files added to the cache use this particular uid/gid combination. This can be used, for example, to drop permissions when someone uses sudo, but cacache makes no assumptions about your needs here.

> cacache.rm.all(cache, cb)

Clears the entire cache. Mainly by blowing away the cache directory itself.

Example
cacache.rm.all(cachePath, (err) => {
  if (err) { throw err }
  console.log('THE APOCALYPSE IS UPON US ๐Ÿ˜ฑ')
})

> cacache.rm.entry(cache, key, cb)

Removes the index entry for key. Content will still be accessible if requested directly.

Example
cacache.rm.entry(cachePath, 'my-thing', (err) => {
  if (err) { throw err }
  console.log('I did not like it anyway')
})

> cacache.rm.content(cache, digest, cb)

Removes the content identified by digest. Any index entries referring to it will not be usable again until the content is re-added to the cache with an identical digest.

Example
cacache.rm.content(cachePath, 'deadbeef', (err) => {
  if (err) { throw err }
  console.log('data for my-thing is gone!')
})

> cacache.verify(cache, opts, cb)

Checks out and fixes up your cache:

  • Cleans up corrupted or invalid index entries.
  • Garbage collects any content entries not referenced by the index.
  • Checks digests for all content entries and removes invalid content.
  • Fixes cache ownership.
  • Removes the tmp directory in the cache and all its contents.

When it's done, it'll return an object with various stats about the verification process, including amount of storage reclaimed, number of valid entries, number of entries removed, etc.

This function should not be run while other processes are running cacache. It assumes it'll be used offline by a human or a coordinated process. Concurrent verifies are protected by a lock, but there's no guarantee others won't be reading/writing on the cache.

Options
  • opts.uid - uid to assign to cache and its contents
  • opts.gid - gid to assign to cache and its contents
  • opts.hashAlgorithm - defaults to 'sha256'. Hash to use for content checks.
Example
echo somegarbage >> $CACHEPATH/content/deadbeef
cacache.verify(cachePath, (err, stats) => {
  if (err) { throw err }
  // deadbeef collected, because of invalid checksum.
  console.log('cache is much nicer now! stats:', stats)
})

> cacache.verify.lastRun(cache, cb)

Returns a Date representing the last time cacache.verify was run on cache.

Example
cacache.verify(cachePath, (err) => {
  if (err) { throw err }
  cacache.verify.lastRun(cachePath, (err, lastTime) => {
    if (err) { throw err }
    console.log('cacache.verify was last called on' + lastTime)
  })
})

cacache's People

Contributors

greenkeeper[bot] avatar zkat avatar

Watchers

 avatar

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.