Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/miserylee/layered-cache-loader
Add cache layers based on dataloader.
https://github.com/miserylee/layered-cache-loader
Last synced: 6 days ago
JSON representation
Add cache layers based on dataloader.
- Host: GitHub
- URL: https://github.com/miserylee/layered-cache-loader
- Owner: miserylee
- Created: 2020-01-19T04:12:15.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2021-08-11T22:02:21.000Z (over 3 years ago)
- Last Synced: 2024-11-01T00:12:35.697Z (about 2 months ago)
- Language: TypeScript
- Size: 112 KB
- Stars: 0
- Watchers: 2
- Forks: 1
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# layered-cache-loader
## ![NPM version](https://img.shields.io/npm/v/layered-cache-loader.svg?style=flat)
# 这是什么?
`layered-cache-loader`是一个基于[dataloader](https://github.com/graphql/dataloader)的多级缓存解决方案。
# 怎么使用?
```js
// 创建内存缓存层
const layer1 = new MemoryLayer();
// 创建Redis缓存层
const layer2 = new RedisLayer({
uri: 'redis://localhost:6379',
ttl: 10000,
});
// 创建数据源
const finalMap = new Map([
['foo', 'bar'],
['foo2', 'hahaha'],
['hello', 'world'],
]);
// 创建loader,并逐个use缓存层(先use的层距离最近,所以建议越快的缓存层越先use)
const layeredCacheLoader = new LayeredCacheLoader()
.use(layer1)
.use(layer2)
.final(async keys => keys.map(key => finalMap.get(key) ?? new Error('Value not found.'))); // 未命中任何缓存的情况下,从final loader读取数据
const results = await layeredCacheLoader.loadMany(['foo', 'foo2', 'hello']); // 使用dataloader的数据读取方案,详情可以查看dataloader文档
assert(results[0] === 'bar');
assert(results[1] === 'hahaha');
assert(results[2] === 'world');
```# API定义
## `LayeredCacheLoader`
`K`:`key`值的类型;
`V`: `value`值的类型;
#### `ICacheLayer`
```js
export interface ICacheLayer {
batchGet(keys: readonly K[]): Promise>;batchSet(map: Map): void;
}
```
自定义缓存层按照`ICacheLayer`定义#### `LayeredCacheLoader().use(layer: ICacheLayer): this`
使用`use`来配置缓存层,先配置的层距离结果返回最近,建议速度越快的缓存层越先配置。
#### `LayeredCacheLoader().final(batchLoadFn: BatchLoadFn): this`
使用`final`来配置最终数据源,当`key`没有命中任何缓存层的情况下,会从`final loader`读取数据。例:在`batchLoadFn`中从`Mongodb`或`Mysql`读取原始数据。
`final`可多次调用,以最后一次调用为准。
#### `LayeredCacheLoader().load(key: K): Promise`
同`dataloader.load`。
#### `LayeredCacheLoader().loadMany(keys: K[]): Promise>`
同`dataloader.loadMany`。
## `MemoryLayer`
`K`:`key`值的类型;
`V`: `value`值的类型;
`CK`: 缓存的`key`的类型;
#### `IMemoryLayerOptions`
```js
export interface IMemoryLayerOptions {
ttl?: number; // 缓存存活时间(毫秒),默认为Infinity,即永不过期keyFn?(key: K): CK; // key到cacheKey的转换函数
}
```#### `MemoryLayer(options: IMemoryLayerOptions = {})`
构造一个基于内存的缓存层对象。
#### `readonly MemoryLayer().map: TTLMap`
内存缓存层用于存储数据的`TTLMap`对象,`TTLMap`见后文。
## `RedisLayer`
`K`:`key`值的类型;
`V`: `value`值的类型;
#### `IRedisLayerOptions`
```js
export interface IRedisLayerOptions {
uri: string; // redis连接uri
keyPrefix?: string; // 存储到redis中的key的附加前缀(命名空间),默认为'cacheloader'
ttl?: number; // 缓存存货时间(毫秒),默认为Infinity,即永不过期keyFn?(key: K): string; // key到cacheKey的转换函数
serializer?(value: V): string; // 序列化函数,默认为JSON.stringify
deserializer?(data: string): V | Error; // 反序列化函数,默认为JSON.parse
}
```#### `RedisLayer(options: IRedisLayerOptions)`
构造一个基于Redis的缓存层对象。
#### `readonly RedisLayer().redis: IORedis.Redis`
`redis`缓存层内部使用的`Redis`对象。
## `TTLMap extends Map`
`K`:`key`值的类型;
`V`: `value`值的类型;
带有`ttl(tive to live)`的`Map`。
#### `TTLMap().setTTL(key: K, value: V, ttl: number): this`
同`Map().set`,第3个参数`ttl`设置该`key`的存活时间。