Invalidate cache based on timeout

This commit is contained in:
Tobe O 2018-04-01 21:37:34 -04:00
parent 6a8183d646
commit 4c37659cc7
2 changed files with 27 additions and 2 deletions

View file

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:angel_framework/angel_framework.dart'; import 'package:angel_framework/angel_framework.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:pool/pool.dart';
final DateFormat _fmt = new DateFormat('EEE, d MMM yyyy HH:mm:ss'); final DateFormat _fmt = new DateFormat('EEE, d MMM yyyy HH:mm:ss');
@ -14,12 +15,16 @@ class ResponseCache {
ResponseCache({this.timeout}); ResponseCache({this.timeout});
/// Removes an entry from the response cache.
void invalidate(String path) => _cache.remove(path);
/// A middleware that handles requests with an `If-Modified-Since` header. /// A middleware that handles requests with an `If-Modified-Since` header.
/// ///
/// This prevents the server from even having to access the cache, and plays very well with static assets. /// This prevents the server from even having to access the cache, and plays very well with static assets.
Future<bool> ifModifiedSince(RequestContext req, ResponseContext res) async { Future<bool> ifModifiedSince(RequestContext req, ResponseContext res) async {
if (req.headers.value('if-modified-since') != null) { if (req.headers.value('if-modified-since') != null) {
var modifiedSince = _fmt.parse(req.headers.value('if-modified-since')); var modifiedSince = _fmt
.parse(req.headers.value('if-modified-since').replaceAll('GMT', ''));
// Check if there is a cache entry. // Check if there is a cache entry.
for (var pattern in patterns) { for (var pattern in patterns) {
@ -38,11 +43,30 @@ class ResponseCache {
return true; return true;
} }
/// A response finalizer that saves responses to the cache.
Future<bool> responseFinalizer( Future<bool> responseFinalizer(
RequestContext req, ResponseContext res) async { RequestContext req, ResponseContext res) async {
if (res.statusCode == 304) return true; if (res.statusCode == 304) return true;
var now = new DateTime.now().toUtc(); // Check if there is a cache entry.
for (var pattern in patterns) {
if (pattern.allMatches(req.uri.path).isNotEmpty) {
var now = new DateTime.now().toUtc();
// Invalidate the response, if need be.
if (_cache.containsKey(req.uri.path)) {
// If there is no timeout, don't invalidate.
if (timeout == null) return true;
// Otherwise, don't invalidate unless the timeout has been exceeded.
var response = _cache[req.uri.path];
if (now.difference(response.timestamp) < timeout) return true;
// If the cache entry should be invalidated, then invalidate it.
invalidate(req.uri.path);
}
}
}
} }
void setCachedHeaders( void setCachedHeaders(

View file

@ -3,6 +3,7 @@ dependencies:
angel_framework: ">=1.0.0-dev <2.0.0" angel_framework: ">=1.0.0-dev <2.0.0"
intl: ^0.15.0 intl: ^0.15.0
meta: ^1.0.0 meta: ^1.0.0
pool: ^1.0.0
dev_dependencies: dev_dependencies:
angel_test: ^1.1.0 angel_test: ^1.1.0
glob: ^1.0.0 glob: ^1.0.0