Skip to content
This repository has been archived by the owner on Jun 12, 2022. It is now read-only.

Commit

Permalink
feat(cache): added CacheManager protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
zkat committed Apr 17, 2017
1 parent 781d367 commit 6e6bf8c
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 30 deletions.
38 changes: 38 additions & 0 deletions cache-manager.js
@@ -0,0 +1,38 @@
'use strict'

const duck = require('protoduck')

// CacheManager
//
// This protocol defines the interface for a make-fetch-happen-compatible
// cache implementation. Anything that implements this may be passed in as
// make-fetch-happen's opts.cacheManager
//
// docs: https://developer.mozilla.org/en-US/docs/Web/API/Cache
//
// To implement this protocol, call it on a class and write the impls:
//
// const CacheManager = require('make-fetch-happen/cache-manager')
// class MyCache {
// constructor (opts) { ... }
// }
//
// CacheManager.impl(MyCache, {
// match (req) { ...get response... }, // -> fetch.Response
// put (req, res) { ...insert into cache... }, // -> fetch.Response
// delete (req) { ...remove from cache... } // -> Boolean
// })
//
module.exports = duck.define(['req', 'res'], {
// Returns a Promise that resolves to the response associated with the first
// matching request in the Cache object.
match: ['req'],

// Takes both a request and its response and adds it to the given cache.
put: ['req', 'res'],

// Finds the Cache entry whose key is the request, and if found, deletes the
// Cache entry and returns a Promise that resolves to true. If no Cache entry
// is found, it returns false.
delete: ['req']
})
50 changes: 21 additions & 29 deletions cache.js
@@ -1,6 +1,7 @@
'use strict'

const cacache = require('cacache')
const CacheManager = require('./cache-manager')
const fetch = require('node-fetch')
const fs = require('fs')
const pipe = require('mississippi').pipe
Expand All @@ -11,33 +12,17 @@ const url = require('url')

const MAX_MEM_SIZE = 5 * 1024 * 1024 // 5MB

function cacheKey (req) {
const parsed = url.parse(req.url)
return `make-fetch-happen:request-cache:${
url.format({
protocol: parsed.protocol,
slashes: parsed.slashes,
host: parsed.host,
hostname: parsed.hostname,
pathname: parsed.pathname
})
}`
}

// This is a cacache-based implementation of the Cache standard,
// using node-fetch.
// docs: https://developer.mozilla.org/en-US/docs/Web/API/Cache
//
module.exports = class Cache {
class Cacache {
constructor (path, opts) {
this._path = path
this._uid = opts && opts.uid
this._gid = opts && opts.gid
this.Promise = (opts && opts.Promise) || Promise
}
}
module.exports = Cacache

// Returns a Promise that resolves to the response associated with the first
// matching request in the Cache object.
CacheManager.impl(Cacache, {
match (req, opts) {
const key = cacheKey(req)
return cacache.get.info(this._path, key).then(info => {
Expand Down Expand Up @@ -110,9 +95,7 @@ module.exports = class Cache {
})
}
})
}

// Takes both a request and its response and adds it to the given cache.
},
put (req, response, opts) {
const size = response.headers.get('content-length')
const fitInMemory = !!size && size < MAX_MEM_SIZE
Expand Down Expand Up @@ -196,19 +179,15 @@ module.exports = class Cache {
})
}), err => err && newBody.emit('error', err))
return response
}

// Finds the Cache entry whose key is the request, and if found, deletes the
// Cache entry and returns a Promise that resolves to true. If no Cache entry
// is found, it returns false.
},
'delete' (req) {
return cacache.rm.entry(
this._path,
cacheKey(req)
// TODO - true/false
).then(() => false)
}
}
})

function matchDetails (req, cached) {
const reqUrl = url.parse(req.url)
Expand Down Expand Up @@ -243,6 +222,19 @@ function matchDetails (req, cached) {
return url.format(reqUrl) === url.format(cacheUrl)
}

function cacheKey (req) {
const parsed = url.parse(req.url)
return `make-fetch-happen:request-cache:${
url.format({
protocol: parsed.protocol,
slashes: parsed.slashes,
host: parsed.host,
hostname: parsed.hostname,
pathname: parsed.pathname
})
}`
}

function addCacheHeaders (resHeaders, path, key, hash, time) {
resHeaders.set('X-Local-Cache', path)
resHeaders.set('X-Local-Cache-Key', key)
Expand Down
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -38,13 +38,14 @@
"dependencies": {
"agentkeepalive": "^3.1.0",
"cacache": "^7.0.3",
"http-cache-semantics": "^3.7.3",
"http-proxy-agent": "^1.0.0",
"https-proxy-agent": "^1.0.0",
"http-cache-semantics": "^3.7.3",
"lru-cache": "^4.0.2",
"mississippi": "^1.2.0",
"node-fetch": "2.0.0-alpha.3",
"promise-retry": "^1.1.1",
"protoduck": "^4.0.0",
"socks-proxy-agent": "^2.0.0",
"ssri": "^4.0.0"
},
Expand Down

0 comments on commit 6e6bf8c

Please sign in to comment.