Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F100979537
IdleFileCachePlugin.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Tue, Feb 4, 12:03
Size
4 KB
Mime Type
text/x-c++
Expires
Thu, Feb 6, 12:03 (2 d)
Engine
blob
Format
Raw Data
Handle
24065411
Attached To
rOACCT Open Access Compliance Check Tool (OACCT)
IdleFileCachePlugin.js
View Options
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict"
;
const
Cache
=
require
(
"../Cache"
);
const
ProgressPlugin
=
require
(
"../ProgressPlugin"
);
/** @typedef {import("../Compiler")} Compiler */
const
BUILD_DEPENDENCIES_KEY
=
Symbol
();
class
IdleFileCachePlugin
{
/**
* @param {TODO} strategy cache strategy
* @param {number} idleTimeout timeout
* @param {number} idleTimeoutForInitialStore initial timeout
*/
constructor
(
strategy
,
idleTimeout
,
idleTimeoutForInitialStore
)
{
this
.
strategy
=
strategy
;
this
.
idleTimeout
=
idleTimeout
;
this
.
idleTimeoutForInitialStore
=
idleTimeoutForInitialStore
;
}
/**
* Apply the plugin
* @param {Compiler} compiler the compiler instance
* @returns {void}
*/
apply
(
compiler
)
{
const
strategy
=
this
.
strategy
;
const
idleTimeout
=
this
.
idleTimeout
;
const
idleTimeoutForInitialStore
=
Math
.
min
(
idleTimeout
,
this
.
idleTimeoutForInitialStore
);
const
resolvedPromise
=
Promise
.
resolve
();
/** @type {Map<string | typeof BUILD_DEPENDENCIES_KEY, () => Promise>} */
const
pendingIdleTasks
=
new
Map
();
compiler
.
cache
.
hooks
.
store
.
tap
(
{
name
:
"IdleFileCachePlugin"
,
stage
:
Cache
.
STAGE_DISK
},
(
identifier
,
etag
,
data
)
=>
{
pendingIdleTasks
.
set
(
identifier
,
()
=>
strategy
.
store
(
identifier
,
etag
,
data
)
);
}
);
compiler
.
cache
.
hooks
.
get
.
tapPromise
(
{
name
:
"IdleFileCachePlugin"
,
stage
:
Cache
.
STAGE_DISK
},
(
identifier
,
etag
,
gotHandlers
)
=>
{
return
strategy
.
restore
(
identifier
,
etag
).
then
(
cacheEntry
=>
{
if
(
cacheEntry
===
undefined
)
{
gotHandlers
.
push
((
result
,
callback
)
=>
{
if
(
result
!==
undefined
)
{
pendingIdleTasks
.
set
(
identifier
,
()
=>
strategy
.
store
(
identifier
,
etag
,
result
)
);
}
callback
();
});
}
else
{
return
cacheEntry
;
}
});
}
);
compiler
.
cache
.
hooks
.
storeBuildDependencies
.
tap
(
{
name
:
"IdleFileCachePlugin"
,
stage
:
Cache
.
STAGE_DISK
},
dependencies
=>
{
pendingIdleTasks
.
set
(
BUILD_DEPENDENCIES_KEY
,
()
=>
strategy
.
storeBuildDependencies
(
dependencies
)
);
}
);
compiler
.
cache
.
hooks
.
shutdown
.
tapPromise
(
{
name
:
"IdleFileCachePlugin"
,
stage
:
Cache
.
STAGE_DISK
},
()
=>
{
if
(
idleTimer
)
{
clearTimeout
(
idleTimer
);
idleTimer
=
undefined
;
}
isIdle
=
false
;
const
reportProgress
=
ProgressPlugin
.
getReporter
(
compiler
);
const
jobs
=
Array
.
from
(
pendingIdleTasks
.
values
());
if
(
reportProgress
)
reportProgress
(
0
,
"process pending cache items"
);
const
promises
=
jobs
.
map
(
fn
=>
fn
());
pendingIdleTasks
.
clear
();
promises
.
push
(
currentIdlePromise
);
const
promise
=
Promise
.
all
(
promises
);
currentIdlePromise
=
promise
.
then
(()
=>
strategy
.
afterAllStored
());
if
(
reportProgress
)
{
currentIdlePromise
=
currentIdlePromise
.
then
(()
=>
{
reportProgress
(
1
,
`
stored
`
);
});
}
return
currentIdlePromise
;
}
);
/** @type {Promise<any>} */
let
currentIdlePromise
=
resolvedPromise
;
let
isIdle
=
false
;
let
isInitialStore
=
true
;
const
processIdleTasks
=
()
=>
{
if
(
isIdle
)
{
if
(
pendingIdleTasks
.
size
>
0
)
{
const
promises
=
[
currentIdlePromise
];
const
maxTime
=
Date
.
now
()
+
100
;
let
maxCount
=
100
;
for
(
const
[
filename
,
factory
]
of
pendingIdleTasks
)
{
pendingIdleTasks
.
delete
(
filename
);
promises
.
push
(
factory
());
if
(
maxCount
--
<=
0
||
Date
.
now
()
>
maxTime
)
break
;
}
currentIdlePromise
=
Promise
.
all
(
promises
);
currentIdlePromise
.
then
(()
=>
{
// Allow to exit the process between
setTimeout
(
processIdleTasks
,
0
).
unref
();
});
return
;
}
currentIdlePromise
=
currentIdlePromise
.
then
(()
=>
strategy
.
afterAllStored
()
);
isInitialStore
=
false
;
}
};
let
idleTimer
=
undefined
;
compiler
.
cache
.
hooks
.
beginIdle
.
tap
(
{
name
:
"IdleFileCachePlugin"
,
stage
:
Cache
.
STAGE_DISK
},
()
=>
{
idleTimer
=
setTimeout
(
()
=>
{
idleTimer
=
undefined
;
isIdle
=
true
;
resolvedPromise
.
then
(
processIdleTasks
);
},
isInitialStore
?
idleTimeoutForInitialStore
:
idleTimeout
);
idleTimer
.
unref
();
}
);
compiler
.
cache
.
hooks
.
endIdle
.
tap
(
{
name
:
"IdleFileCachePlugin"
,
stage
:
Cache
.
STAGE_DISK
},
()
=>
{
if
(
idleTimer
)
{
clearTimeout
(
idleTimer
);
idleTimer
=
undefined
;
}
isIdle
=
false
;
}
);
}
}
module
.
exports
=
IdleFileCachePlugin
;
Event Timeline
Log In to Comment