-
Notifications
You must be signed in to change notification settings - Fork 15
refactor: rewrite, use memcached-elasticache & drop Node 8 #48
Conversation
075d877
to
65404ac
Compare
README.md
Outdated
@@ -2,7 +2,7 @@ | |||
|
|||
A simple caching library, inspired by the [Play cache API](http://www.playframework.com/documentation/2.2.x/ScalaCache) and biased towards [showing stale data instead of dog piling](http://highscalability.com/strategy-break-memcache-dog-pile). | |||
The interface only exposes very limited functionality, there's no multi-get or deletion of cached data. | |||
The library is designed to support different caching backends, though right now only memcached is implemented. | |||
The library support different caching backends, though right now only memcached is implemented. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the original is more grammatically and semantically correct
README.md
Outdated
It's **highly** recommended to set a timeout. | ||
If `timeout` is left `undefined`, no timeout will be set and the operations will only fail once the underlying client, e.g. [`memcached`](https://github.com/3rd-Eden/memcached), gave up. | ||
Otherwise, there will be situations where one of the cache hosts goes down and reads hang for minutes while the memcached client retries to establish a connection. | ||
It's **highly** recommended setting a timeout. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Former is more grammatically correct
lib/backend.js
Outdated
@@ -32,35 +32,53 @@ | |||
|
|||
'use strict'; | |||
|
|||
const typeMap = new Map(); | |||
/** | |||
* @typedef {Object} backend |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: it's easier to read the later annotations if types are capitalized, i.e. Backend
not backend
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or maybe BackendImpl
if Backend
would collide with the variable named that
@@ -32,35 +32,53 @@ | |||
|
|||
'use strict'; | |||
|
|||
const typeMap = new Map(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
General principle: particularly in an otherwise large PR, the bar for renaming not-obviously-wrong variables and making similar "optional" changes should be pretty high - they make the cognitive load for reviewers much higher, as they have to analyze each changed line to see how it's relevant to the fix/refactor in question.
i.e.: not saying that the new variable name isn't better, just that it wasn't necessarily an important change to make at this time.
lib/backends/memcached.js
Outdated
* @param {any} value | ||
* @return {null|any} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* @param {any} value | |
* @return {null|any} | |
* @template T | |
* @param {T} value | |
* @return {null|T} |
I think that's right (but double-check it)
lib/backends/memcached.js
Outdated
this._get = promisify(this.client.get).bind(this.client); | ||
this._set = promisify(this.client.set).bind(this.client); | ||
this._del = promisify(this.client.del).bind(this.client); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should these be instead: promisify(this.client.get.bind(this.client))
?
* @return {Promise<void>} | ||
*/ | ||
async set(key, value, options) { | ||
await this._set(key, value, options.expire); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it ok that this no longer returns the original value
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
If you're making breaking API changes, is there any reason to continue to support callback syntax? Also, for the things that now return promises, you should review the README to make sure it's clear about callback use. |
lib/util.js
Outdated
@@ -32,38 +32,77 @@ | |||
|
|||
'use strict'; | |||
|
|||
const Bluebird = require('bluebird'); | |||
const timedOutError = new Error('operation timed out'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the stack trace is constructed at the point when you construct a new Error, so you want to do it when the error happens, and not before; e.g.:
// foo.js - BAD!
const e = new Error('boom');
function a() { b(); }
function b() { c(); }
function c() { throw e; }
a();
$ node foo.js
foo.js:5
throw e;
^
Error: boom
at Object.<anonymous> (/Users/dbushong/foo.js:1:11)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for pointing this out.
package.json
Outdated
@@ -14,18 +14,23 @@ | |||
}, | |||
"scripts": { | |||
"lint": "npm-run-all lint:*", | |||
"lint:js": "eslint .", | |||
"lint:js": "eslint --fix .", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Careful with this - it means if you don't have a lintfix-on-save trigger set up in your editor, and you have un-prettier-ified changes, then when you run npm t
it will rewrite your files out from under you, which may or may not be something safe or expected for a give developer
package.json
Outdated
"bluebird": "^3.3.3", | ||
"memcached": "^2.2.2" | ||
"@types/memcached": "^2.2.6", | ||
"@types/node": "^13.11.1", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these belong in devDeps, i believe
test/_helper.js
Outdated
|
||
exports.delay = function delay(ms) { | ||
return new Promise(resolve => setTimeout(resolve, ms)); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as of node 8, i believe, this is the same as:
const { promisify } = require('util');
exports.delay = promisify(setTimeout);
OK, I'm thru with a quick once-over. |
yes you are right, it would make sense to further simplify the code by dropping callback syntax |
README.md
Outdated
// Set a key using a value) | ||
await kittens.set('my.key', 'kitty'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Set a key using a value) | |
await kittens.set('my.key', 'kitty'); |
Seems like a dup from line 28
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh I didn't see. good spot
README.md
Outdated
const data2 = await kittens.get('my.key').catch(err => { | ||
throw err; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const data2 = await kittens.get('my.key').catch(err => { | |
throw err; | |
} | |
try { | |
const data2 = await kittens.get('my.key') | |
}catch(err) { | |
// log it somewhere ... | |
} |
How about using try/catch
block here? just to be consistent with the synchronous style of async/await
?
addType('noop', require('./backends/noop')); | ||
/** | ||
* @param {string} type | ||
* @param {Class} Backend |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be {BackendImpl}
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Skimmed; lots of changes; seems ok?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💚
- [x] chore: drop Node 8 support. Min required version is [email protected] - [x] refactor(deps): remove `lodash` and `bluebird` - [x] refactor(cache): rewrite `Cache` with ES6 class syntax - [x] refactor: `cache.set` no longer returns a value - [x] refactor: make inofficial cache api private - [x] fix: handle functions or promises as `cache.set` values as described in README.md - [x] fix: remove deprecation message, that warned when backend `name` was not a string. It will throw a type error now. - [x] deps: use `memcached-elasticache` instead of `memcached` - [x] chore(deps): upgrade dependencies - [x] test: add additional test to increase test coverage - [x] docs(README): update API section BREAKING CHANGE: - Dropped Node 8.x. Use Node 10.13 or higher. - Uses `memcached-elasticache` with AWS support instead of `memcached`. See https://github.com/jkehres/memcached-elasticache#readme - API functions no longer support callbacks. - API functions use native Promises instead of `Bluebird`. - `cached()` needs to be called with a string argument as name. If the `name` argument is undefined, it will fallback to `"default"`. - `Cache.setBackend()` no longer returns the created backend. - `Cache.getWrapped()` is removed. - Cache backend APIs need to be promise based. - Cache private function have been renamed. - The following function are now private: - `Cache.applyPrefix` - `Cache.end` - `Cache.prepareOptions` - `Cache.setBackend` - `cache.set()`, `cache.get()`, `cache.getOrElse()`, `cache.unset()` no longer support the callback argument. Use them as promise. - `cache.set()` no longer returns a value. - `cache.set(key, value)` accepts functions and promises as value. - Any client passed with the memcached backend options has to be an instance of `Memcached`. - Backend setters no longer return a value. - backend `addType()` does not return backend class anymore.
lodash
andbluebird
Cache
with ES6 class syntaxcache.set
no longer returns a valuenoop
backend and makememory
the default backendcache.set
values as described in README.mdname
was not a string. It will throw a type error now.memcached-elasticache
instead ofmemcached
BREAKING CHANGES:
General
memcached-elasticache
with AWS support instead ofmemcached
. See https://github.com/jkehres/memcached-elasticache#readmeBluebird
.cached()
needs to be called with a string argument as name. If thename
argument is undefined, it will fallback to"default"
.Cache
Cache.setBackend()
no longer returns the created backend.Cache.getWrapped()
is removed.Cache.applyPrefix
Cache.end
Cache.prepareOptions
Cache.setBackend
cache
cache.set()
,cache.get()
,cache.getOrElse()
,cache.unset()
no longer support the callback argument. Use them as promise.cache.set()
no longer returns a value.cache.set(key, value)
accepts functions and promises as value.Backends
Memcached
.addType()
does not return backend class anymore.