Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

refactor: rewrite, use memcached-elasticache & drop Node 8 #48

Merged
merged 6 commits into from
Jun 27, 2021

Conversation

aaarichter
Copy link

@aaarichter aaarichter commented Apr 13, 2020

  • chore: drop Node 8 support. Min required version is [email protected]
  • refactor(deps): remove lodash and bluebird
  • refactor(cache): rewrite Cache with ES6 class syntax
  • refactor: cache.set no longer returns a value
  • refactor: make inofficial cache api private
  • refactor: remove noop backend and make memory the default backend
  • fix: handle functions or promises as cache.set values as described in README.md
  • fix: remove deprecation message, that warned when backend name was not a string. It will throw a type error now.
  • deps: use memcached-elasticache instead of memcached
  • docs(README): update API section
  • chore(deps): upgrade dependencies
  • test: add additional test to increase test coverage

BREAKING CHANGES:

General

  • 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

  • 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

  • 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

  • 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.

@aaarichter aaarichter changed the title refactor: no bluebird, no lodash refactor: no bluebird, no lodash & code refactor Apr 14, 2020
@aaarichter aaarichter force-pushed the updates branch 2 times, most recently from 075d877 to 65404ac Compare July 3, 2020 10:20
@aaarichter aaarichter marked this pull request as ready for review July 3, 2020 10:42
@aaarichter aaarichter requested a review from aotarola July 3, 2020 10:43
@aaarichter
Copy link
Author

Hey @jkrems, @dbushong & @aotarola
would you be so kind and have a look at this PR 😼 . Thanks

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.
Copy link
Contributor

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.
Copy link
Contributor

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
Copy link
Contributor

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

Copy link
Contributor

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();
Copy link
Contributor

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.

Comment on lines 57 to 58
* @param {any} value
* @return {null|any}
Copy link
Contributor

@dbushong dbushong Jul 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @param {any} value
* @return {null|any}
* @template T
* @param {T} value
* @return {null|T}

I think that's right (but double-check it)

Comment on lines 72 to 74
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);
Copy link
Contributor

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);
Copy link
Contributor

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?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

@dbushong
Copy link
Contributor

dbushong commented Jul 5, 2020

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');
Copy link
Contributor

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)

Copy link
Author

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 .",
Copy link
Contributor

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",
Copy link
Contributor

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));
};
Copy link
Contributor

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);

@dbushong
Copy link
Contributor

dbushong commented Jul 5, 2020

OK, I'm thru with a quick once-over.

@aaarichter
Copy link
Author

aaarichter commented May 5, 2021

If you're making breaking API changes, is there any reason to continue to support callback syntax?

yes you are right, it would make sense to further simplify the code by dropping callback syntax

@aaarichter aaarichter changed the title refactor: no bluebird, no lodash & code refactor refactor: rewrite, use memcached-elasticache & drop Node 8 May 6, 2021
@aaarichter aaarichter requested a review from dbushong May 6, 2021 20:34
@aaarichter
Copy link
Author

Hey @dbushong @aotarola

sorry it took so long to address your feedback. Would you do another review? 🙇‍♂️

I rebased and updated the PR.

README.md Outdated
Comment on lines 35 to 36
// Set a key using a value)
await kittens.set('my.key', 'kitty');
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Set a key using a value)
await kittens.set('my.key', 'kitty');

Seems like a dup from line 28 ?

Copy link
Author

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
Comment on lines 50 to 52
const data2 = await kittens.get('my.key').catch(err => {
throw err;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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 ?

@aaarichter aaarichter requested a review from aotarola May 7, 2021 09:20
addType('noop', require('./backends/noop'));
/**
* @param {string} type
* @param {Class} Backend
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be {BackendImpl} ?

Copy link
Contributor

@dbushong dbushong left a 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?

Copy link

@aotarola aotarola left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💚

Andreas Richter added 5 commits June 4, 2021 16:31
- [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.
@aaarichter aaarichter merged commit 1a7a256 into master Jun 27, 2021
@aaarichter aaarichter deleted the updates branch June 27, 2021 15:44
@aaarichter aaarichter mentioned this pull request Jul 16, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants