@@ -4,11 +4,15 @@ const kValues = require('./symbol')
4
4
const stringify = require ( 'safe-stable-stringify' )
5
5
const LRUCache = require ( 'mnemonist/lru-cache' )
6
6
7
+ const kCacheSize = Symbol ( 'kCacheSize' )
8
+ const kTTL = Symbol ( 'kTTL' )
9
+
7
10
class Cache {
8
11
constructor ( opts ) {
9
12
opts = opts || { }
10
13
this [ kValues ] = { }
11
- this . _cacheSize = opts . cacheSize || 1024
14
+ this [ kCacheSize ] = opts . cacheSize || 1024
15
+ this [ kTTL ] = opts . ttl || 0
12
16
}
13
17
14
18
define ( key , opts , func ) {
@@ -28,23 +32,40 @@ class Cache {
28
32
throw new TypeError ( 'serialize must be a function' )
29
33
}
30
34
31
- const cacheSize = opts . cacheSize || this . _cacheSize
35
+ const cacheSize = opts . cacheSize || this [ kCacheSize ]
36
+ const ttl = opts . ttl || this [ kTTL ]
32
37
33
- const wrapper = new Wrapper ( func , key , serialize , cacheSize )
38
+ const wrapper = new Wrapper ( func , key , serialize , cacheSize , ttl )
34
39
35
40
this [ kValues ] [ key ] = wrapper
36
41
this [ key ] = wrapper . add . bind ( wrapper )
37
42
}
38
43
}
39
44
45
+ let _currentSecond
46
+
47
+ function currentSecond ( ) {
48
+ if ( _currentSecond !== undefined ) {
49
+ return _currentSecond
50
+ }
51
+ _currentSecond = Math . floor ( Date . now ( ) / 1000 )
52
+ setTimeout ( _clearSecond , 1000 ) . unref ( )
53
+ return _currentSecond
54
+ }
55
+
56
+ function _clearSecond ( ) {
57
+ _currentSecond = undefined
58
+ }
59
+
40
60
class Wrapper {
41
- constructor ( func , key , serialize , cacheSize ) {
61
+ constructor ( func , key , serialize , cacheSize , ttl ) {
42
62
this . ids = new LRUCache ( cacheSize )
43
63
this . error = null
44
64
this . started = false
45
65
this . func = func
46
66
this . key = key
47
67
this . serialize = serialize
68
+ this . ttl = ttl
48
69
}
49
70
50
71
add ( args ) {
@@ -55,8 +76,15 @@ class Wrapper {
55
76
if ( ! query ) {
56
77
query = new Query ( id , args , this . func )
57
78
this . ids . set ( key , query )
79
+ } else if ( this . ttl > 0 ) {
80
+ if ( currentSecond ( ) - query . lastAccessed > this . ttl ) {
81
+ // restart
82
+ query . promise = this . func . call ( null , args )
83
+ }
58
84
}
59
85
86
+ query . touch ( )
87
+
60
88
return query . promise
61
89
}
62
90
}
@@ -65,6 +93,11 @@ class Query {
65
93
constructor ( id , args , func ) {
66
94
this . id = id
67
95
this . promise = func ( args )
96
+ this . lastAccessed = null
97
+ }
98
+
99
+ touch ( ) {
100
+ this . lastAccessed = currentSecond ( )
68
101
}
69
102
}
70
103
0 commit comments