2.0.1
This commit is contained in:
parent
37abf01168
commit
aea408b2f7
4 changed files with 30 additions and 17 deletions
|
@ -1,2 +1,6 @@
|
||||||
|
# 2.0.1
|
||||||
|
* Add `ignoreQueryAndFragment` to `ResponseCache`.
|
||||||
|
* Rename `CacheService.ignoreQuery` to `ignoreParams`.
|
||||||
|
|
||||||
# 1.0.0
|
# 1.0.0
|
||||||
* First version
|
* First version
|
|
@ -19,7 +19,10 @@ class ResponseCache {
|
||||||
final Map<String, _CachedResponse> _cache = {};
|
final Map<String, _CachedResponse> _cache = {};
|
||||||
final Map<String, Pool> _writeLocks = {};
|
final Map<String, Pool> _writeLocks = {};
|
||||||
|
|
||||||
ResponseCache({this.timeout});
|
/// If `true` (default: `false`), then caching of results will discard URI query parameters and fragments.
|
||||||
|
final bool ignoreQueryAndFragment;
|
||||||
|
|
||||||
|
ResponseCache({this.timeout, this.ignoreQueryAndFragment: false});
|
||||||
|
|
||||||
/// Closes all internal write-locks, and closes the cache.
|
/// Closes all internal write-locks, and closes the cache.
|
||||||
Future close() async {
|
Future close() async {
|
||||||
|
@ -40,9 +43,9 @@ class ResponseCache {
|
||||||
|
|
||||||
// Check if there is a cache entry.
|
// Check if there is a cache entry.
|
||||||
for (var pattern in patterns) {
|
for (var pattern in patterns) {
|
||||||
if (pattern.allMatches(req.uri.path).isNotEmpty &&
|
if (pattern.allMatches(_getEffectivePath(req)).isNotEmpty &&
|
||||||
_cache.containsKey(req.uri.path)) {
|
_cache.containsKey(_getEffectivePath(req))) {
|
||||||
var response = _cache[req.uri.path];
|
var response = _cache[_getEffectivePath(req)];
|
||||||
//print('timestamp ${response.timestamp} vs since ${modifiedSince}');
|
//print('timestamp ${response.timestamp} vs since ${modifiedSince}');
|
||||||
|
|
||||||
if (response.timestamp.compareTo(modifiedSince) <= 0) {
|
if (response.timestamp.compareTo(modifiedSince) <= 0) {
|
||||||
|
@ -62,6 +65,9 @@ class ResponseCache {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String _getEffectivePath(RequestContext req) =>
|
||||||
|
ignoreQueryAndFragment == true ? req.uri.path : req.uri.toString();
|
||||||
|
|
||||||
/// Serves content from the cache, if applicable.
|
/// Serves content from the cache, if applicable.
|
||||||
Future<bool> handleRequest(RequestContext req, ResponseContext res) async {
|
Future<bool> handleRequest(RequestContext req, ResponseContext res) async {
|
||||||
if (!await ifModifiedSince(req, res)) return false;
|
if (!await ifModifiedSince(req, res)) return false;
|
||||||
|
@ -73,11 +79,11 @@ class ResponseCache {
|
||||||
// If `if-modified-since` is present, this check has already been performed.
|
// If `if-modified-since` is present, this check has already been performed.
|
||||||
if (req.headers.ifModifiedSince == null) {
|
if (req.headers.ifModifiedSince == null) {
|
||||||
for (var pattern in patterns) {
|
for (var pattern in patterns) {
|
||||||
if (pattern.allMatches(req.uri.path).isNotEmpty) {
|
if (pattern.allMatches(_getEffectivePath(req)).isNotEmpty) {
|
||||||
var now = new DateTime.now().toUtc();
|
var now = new DateTime.now().toUtc();
|
||||||
|
|
||||||
if (_cache.containsKey(req.uri.path)) {
|
if (_cache.containsKey(_getEffectivePath(req))) {
|
||||||
var response = _cache[req.uri.path];
|
var response = _cache[_getEffectivePath(req)];
|
||||||
|
|
||||||
if (timeout != null) {
|
if (timeout != null) {
|
||||||
// If the cache timeout has been met, don't send the cached response.
|
// If the cache timeout has been met, don't send the cached response.
|
||||||
|
@ -108,27 +114,27 @@ class ResponseCache {
|
||||||
|
|
||||||
// Check if there is a cache entry.
|
// Check if there is a cache entry.
|
||||||
for (var pattern in patterns) {
|
for (var pattern in patterns) {
|
||||||
if (pattern.allMatches(req.uri.path).isNotEmpty) {
|
if (pattern.allMatches(_getEffectivePath(req)).isNotEmpty) {
|
||||||
var now = new DateTime.now().toUtc();
|
var now = new DateTime.now().toUtc();
|
||||||
|
|
||||||
// Invalidate the response, if need be.
|
// Invalidate the response, if need be.
|
||||||
if (_cache.containsKey(req.uri.path)) {
|
if (_cache.containsKey(_getEffectivePath(req))) {
|
||||||
// If there is no timeout, don't invalidate.
|
// If there is no timeout, don't invalidate.
|
||||||
if (timeout == null) return true;
|
if (timeout == null) return true;
|
||||||
|
|
||||||
// Otherwise, don't invalidate unless the timeout has been exceeded.
|
// Otherwise, don't invalidate unless the timeout has been exceeded.
|
||||||
var response = _cache[req.uri.path];
|
var response = _cache[_getEffectivePath(req)];
|
||||||
if (now.difference(response.timestamp) < timeout) return true;
|
if (now.difference(response.timestamp) < timeout) return true;
|
||||||
|
|
||||||
// If the cache entry should be invalidated, then invalidate it.
|
// If the cache entry should be invalidated, then invalidate it.
|
||||||
purge(req.uri.path);
|
purge(_getEffectivePath(req));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the response.
|
// Save the response.
|
||||||
var writeLock =
|
var writeLock =
|
||||||
_writeLocks.putIfAbsent(req.uri.path, () => new Pool(1));
|
_writeLocks.putIfAbsent(_getEffectivePath(req), () => new Pool(1));
|
||||||
await writeLock.withResource(() {
|
await writeLock.withResource(() {
|
||||||
_cache[req.uri.path] = new _CachedResponse(
|
_cache[_getEffectivePath(req)] = new _CachedResponse(
|
||||||
new Map.from(res.headers), res.buffer.toBytes(), now);
|
new Map.from(res.headers), res.buffer.toBytes(), now);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,10 @@ class CacheService<Id, Data> extends Service<Id, Data> {
|
||||||
/// If not provided, this defaults to a [MapService].
|
/// If not provided, this defaults to a [MapService].
|
||||||
final Service<Id, Data> cache;
|
final Service<Id, Data> cache;
|
||||||
|
|
||||||
final bool ignoreQuery;
|
/// If `true` (default: `false`), then result caching will discard parameters passed to service methods.
|
||||||
|
///
|
||||||
|
/// If you want to return a cached result more-often-than-not, you may want to enable this.
|
||||||
|
final bool ignoreParams;
|
||||||
|
|
||||||
final Duration timeout;
|
final Duration timeout;
|
||||||
|
|
||||||
|
@ -26,7 +29,7 @@ class CacheService<Id, Data> extends Service<Id, Data> {
|
||||||
CacheService(
|
CacheService(
|
||||||
{@required this.database,
|
{@required this.database,
|
||||||
@required this.cache,
|
@required this.cache,
|
||||||
this.ignoreQuery: false,
|
this.ignoreParams: false,
|
||||||
this.timeout}) {
|
this.timeout}) {
|
||||||
assert(database != null);
|
assert(database != null);
|
||||||
}
|
}
|
||||||
|
@ -47,7 +50,7 @@ class CacheService<Id, Data> extends Service<Id, Data> {
|
||||||
|
|
||||||
if (timeout == null || !expired) {
|
if (timeout == null || !expired) {
|
||||||
// Read from the cache if necessary
|
// Read from the cache if necessary
|
||||||
var queryEqual = ignoreQuery == true ||
|
var queryEqual = ignoreParams == true ||
|
||||||
(params != null &&
|
(params != null &&
|
||||||
cached.params != null &&
|
cached.params != null &&
|
||||||
const MapEquality().equals(
|
const MapEquality().equals(
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: angel_cache
|
name: angel_cache
|
||||||
version: 2.0.0
|
version: 2.0.1
|
||||||
homepage: https://github.com/angel-dart/cache
|
homepage: https://github.com/angel-dart/cache
|
||||||
description: Support for server-side caching in Angel.
|
description: Support for server-side caching in Angel.
|
||||||
author: Tobe O <thosakwe@gmail.com>
|
author: Tobe O <thosakwe@gmail.com>
|
||||||
|
|
Loading…
Reference in a new issue