@static-suite/static-suite-data-server 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +569 -107
- package/dist/http/README.md +569 -107
- package/dist/http/routes/dependency.d.ts +10 -0
- package/dist/http/routes/dependency.d.ts.map +1 -0
- package/dist/http/routes/dependency.js +71 -0
- package/dist/http/routes/dump.d.ts.map +1 -1
- package/dist/http/routes/dump.js +15 -10
- package/dist/http/routes/home.js +2 -1
- package/dist/http/routes/index.d.ts.map +1 -1
- package/dist/http/routes/index.js +8 -0
- package/dist/http/routes/status.d.ts.map +1 -1
- package/dist/http/routes/status.js +1 -6
- package/dist/http/views/dependencyIndex.pug +14 -0
- package/dist/lib/dataServer.d.ts +2 -1
- package/dist/lib/dataServer.d.ts.map +1 -1
- package/dist/lib/query/query.types.d.ts +2 -2
- package/dist/lib/query/query.types.d.ts.map +1 -1
- package/dist/lib/query/query.types.js +2 -2
- package/dist/lib/query/queryRunner.d.ts.map +1 -1
- package/dist/lib/query/queryRunner.js +3 -1
- package/dist/lib/store/dataDir/dataDir.types.d.ts +5 -5
- package/dist/lib/store/dataDir/dataDir.types.d.ts.map +1 -1
- package/dist/lib/store/dataDir/dataDirManager.d.ts.map +1 -1
- package/dist/lib/store/dataDir/dataDirManager.js +23 -12
- package/dist/lib/store/dependency/dependency.types.d.ts.map +1 -1
- package/dist/lib/store/dependency/dependencyFileHelper.d.ts +1 -1
- package/dist/lib/store/dependency/dependencyFileHelper.d.ts.map +1 -1
- package/dist/lib/store/dependency/dependencyFileHelper.js +5 -3
- package/dist/lib/store/dependency/dependencyManager.d.ts +12 -0
- package/dist/lib/store/dependency/dependencyManager.d.ts.map +1 -1
- package/dist/lib/store/dependency/dependencyManager.js +7 -5
- package/dist/lib/store/dependency/dependencyTagger.d.ts.map +1 -1
- package/dist/lib/store/dependency/dependencyTagger.js +3 -38
- package/dist/lib/store/diff/{diffManager.types.d.ts → diff.types.d.ts} +14 -6
- package/dist/lib/store/diff/diff.types.d.ts.map +1 -0
- package/dist/lib/store/{dependency/dependencyManager.types.js → diff/diff.types.js} +0 -0
- package/dist/lib/store/diff/diffManager.d.ts +1 -1
- package/dist/lib/store/diff/diffManager.d.ts.map +1 -1
- package/dist/lib/store/diff/diffManager.js +38 -81
- package/dist/lib/store/dump/{dumpManager.types.d.ts → dump.types.d.ts} +21 -8
- package/dist/lib/store/dump/dump.types.d.ts.map +1 -0
- package/dist/lib/store/{diff/diffManager.types.js → dump/dump.types.js} +0 -0
- package/dist/lib/store/dump/dumpManager.d.ts +1 -1
- package/dist/lib/store/dump/dumpManager.d.ts.map +1 -1
- package/dist/lib/store/dump/dumpManager.js +31 -56
- package/dist/lib/store/dump/dumpMetadataHelper.d.ts +7 -0
- package/dist/lib/store/dump/dumpMetadataHelper.d.ts.map +1 -0
- package/dist/lib/store/dump/dumpMetadataHelper.js +61 -0
- package/dist/lib/store/hook/hook.types.d.ts +49 -23
- package/dist/lib/store/hook/hook.types.d.ts.map +1 -1
- package/dist/lib/store/hook/hookManager.d.ts.map +1 -1
- package/dist/lib/store/hook/hookManager.js +19 -8
- package/dist/lib/store/store.d.ts.map +1 -1
- package/dist/lib/store/store.js +9 -4
- package/dist/lib/store/store.types.d.ts +14 -37
- package/dist/lib/store/store.types.d.ts.map +1 -1
- package/dist/lib/store/storeManager.d.ts.map +1 -1
- package/dist/lib/store/storeManager.js +20 -10
- package/dist/lib/store/workDir/storage/getChangedLinesBetween.d.ts +16 -0
- package/dist/lib/store/workDir/storage/getChangedLinesBetween.d.ts.map +1 -0
- package/dist/lib/store/workDir/storage/{getChangedLinesSince.js → getChangedLinesBetween.js} +22 -20
- package/dist/lib/store/workDir/storage/getDataFromLogLine.d.ts.map +1 -1
- package/dist/lib/store/workDir/storage/getDataFromLogLine.js +16 -3
- package/dist/lib/store/workDir/storage/index.d.ts +1 -1
- package/dist/lib/store/workDir/storage/index.d.ts.map +1 -1
- package/dist/lib/store/workDir/storage/index.js +1 -1
- package/dist/lib/store/workDir/workDir.types.d.ts +9 -1
- package/dist/lib/store/workDir/workDir.types.d.ts.map +1 -1
- package/dist/lib/store/workDir/workDirHelper.d.ts +13 -6
- package/dist/lib/store/workDir/workDirHelper.d.ts.map +1 -1
- package/dist/lib/store/workDir/workDirHelper.js +42 -11
- package/dist/lib/utils/fs/fsUtils.d.ts +6 -0
- package/dist/lib/utils/fs/fsUtils.d.ts.map +1 -1
- package/dist/lib/utils/fs/fsUtils.js +20 -1
- package/dist/lib/utils/module/moduleManager.d.ts.map +1 -1
- package/dist/lib/utils/module/moduleManager.js +5 -1
- package/dist/lib/utils/string/stringUtils.d.ts +14 -0
- package/dist/lib/utils/string/stringUtils.d.ts.map +1 -1
- package/dist/lib/utils/string/stringUtils.js +28 -1
- package/dist/static-suite-data-server.d.ts +19 -39
- package/package.json +3 -3
- package/src/http/routes/dependency.ts +91 -0
- package/src/http/routes/dump.ts +21 -10
- package/src/http/routes/home.ts +2 -2
- package/src/http/routes/index.ts +16 -0
- package/src/http/routes/status.ts +1 -9
- package/src/http/views/dependencyIndex.pug +14 -0
- package/src/lib/dataServer.ts +2 -0
- package/src/lib/query/query.types.ts +2 -2
- package/src/lib/query/queryRunner.ts +3 -1
- package/src/lib/store/dataDir/dataDir.types.ts +5 -5
- package/src/lib/store/dataDir/dataDirManager.ts +30 -14
- package/src/lib/store/dependency/dependency.types.ts +0 -5
- package/src/lib/store/dependency/dependencyFileHelper.ts +5 -3
- package/src/lib/store/dependency/dependencyManager.ts +6 -3
- package/src/lib/store/dependency/dependencyTagger.ts +3 -39
- package/src/lib/store/diff/{diffManager.types.ts → diff.types.ts} +14 -5
- package/src/lib/store/diff/diffManager.ts +45 -84
- package/src/lib/store/dump/{dumpManager.types.ts → dump.types.ts} +24 -7
- package/src/lib/store/dump/dumpManager.ts +40 -75
- package/src/lib/store/dump/dumpMetadataHelper.ts +73 -0
- package/src/lib/store/hook/hook.types.ts +58 -23
- package/src/lib/store/hook/hookManager.ts +24 -9
- package/src/lib/store/store.ts +9 -4
- package/src/lib/store/store.types.ts +16 -37
- package/src/lib/store/storeManager.ts +28 -12
- package/src/lib/store/workDir/__tests__/workDirHelper.test.ts +6 -1
- package/src/lib/store/workDir/storage/__tests__/{getChangedLinesSince.test.ts → getChangedLinesBetween.test.ts} +9 -4
- package/src/lib/store/workDir/storage/getChangedLinesBetween.ts +52 -0
- package/src/lib/store/workDir/storage/getDataFromLogLine.ts +22 -3
- package/src/lib/store/workDir/storage/index.ts +1 -1
- package/src/lib/store/workDir/workDir.types.ts +11 -1
- package/src/lib/store/workDir/workDirHelper.ts +45 -11
- package/src/lib/utils/fs/fsUtils.ts +18 -0
- package/src/lib/utils/module/moduleManager.ts +5 -1
- package/src/lib/utils/string/__tests__/stringUtils.test.ts +30 -1
- package/src/lib/utils/string/stringUtils.ts +32 -0
- package/dist/lib/query/queryRunner copy.d.ts +0 -3
- package/dist/lib/query/queryRunner copy.d.ts.map +0 -1
- package/dist/lib/query/queryRunner copy.js +0 -87
- package/dist/lib/store/dependency/dependencyManager copy.d.ts +0 -6
- package/dist/lib/store/dependency/dependencyManager copy.d.ts.map +0 -1
- package/dist/lib/store/dependency/dependencyManager copy.js +0 -91
- package/dist/lib/store/dependency/dependencyManager.types.d.ts +0 -48
- package/dist/lib/store/dependency/dependencyManager.types.d.ts.map +0 -1
- package/dist/lib/store/dependency/dependencyTagManager.d.ts +0 -6
- package/dist/lib/store/dependency/dependencyTagManager.d.ts.map +0 -1
- package/dist/lib/store/dependency/dependencyTagManager.js +0 -33
- package/dist/lib/store/diff/diffManager.types.d.ts.map +0 -1
- package/dist/lib/store/diff/tracker.d.ts +0 -3
- package/dist/lib/store/diff/tracker.d.ts.map +0 -1
- package/dist/lib/store/diff/tracker.js +0 -82
- package/dist/lib/store/diff/tracker.types.d.ts +0 -31
- package/dist/lib/store/diff/tracker.types.d.ts.map +0 -1
- package/dist/lib/store/diff/tracker.types.js +0 -2
- package/dist/lib/store/dump/dumpManager.types.d.ts.map +0 -1
- package/dist/lib/store/dump/dumpManager.types.js +0 -2
- package/dist/lib/store/include/includeIndex.d.ts +0 -6
- package/dist/lib/store/include/includeIndex.d.ts.map +0 -1
- package/dist/lib/store/include/includeIndex.js +0 -65
- package/dist/lib/store/include/includeIndex.types.d.ts +0 -29
- package/dist/lib/store/include/includeIndex.types.d.ts.map +0 -1
- package/dist/lib/store/include/includeIndex.types.js +0 -2
- package/dist/lib/store/workDir/storage/getChangedLinesSince.d.ts +0 -9
- package/dist/lib/store/workDir/storage/getChangedLinesSince.d.ts.map +0 -1
- package/src/lib/store/workDir/storage/getChangedLinesSince.ts +0 -47
package/src/http/routes/index.ts
CHANGED
|
@@ -20,6 +20,15 @@ import {
|
|
|
20
20
|
dumpMetadataShow,
|
|
21
21
|
dumpMetadataReset,
|
|
22
22
|
} from './dump';
|
|
23
|
+
import {
|
|
24
|
+
dependencyIndex,
|
|
25
|
+
dependencyInvalidatedFilepaths,
|
|
26
|
+
dependencyExplicitlyInvalidatedTags,
|
|
27
|
+
dependencyAllInvalidatedTags,
|
|
28
|
+
dependencyTreeReversed,
|
|
29
|
+
dependencyTreeRoute,
|
|
30
|
+
dependencyTagParents,
|
|
31
|
+
} from './dependency';
|
|
23
32
|
|
|
24
33
|
const routes = Router();
|
|
25
34
|
|
|
@@ -42,6 +51,13 @@ routes.get('/dump/incremental', dumpIncremental);
|
|
|
42
51
|
routes.get('/dump/full', dumpFull);
|
|
43
52
|
routes.get('/dump/metadata/show', dumpMetadataShow);
|
|
44
53
|
routes.get('/dump/metadata/reset', dumpMetadataReset);
|
|
54
|
+
routes.get('/dependency/tree/reversed', dependencyTreeReversed);
|
|
55
|
+
routes.get('/dependency/tree', dependencyTreeRoute);
|
|
56
|
+
routes.get('/dependency/invalidated/tags', dependencyExplicitlyInvalidatedTags);
|
|
57
|
+
routes.get('/dependency/invalidated/tags/all', dependencyAllInvalidatedTags);
|
|
58
|
+
routes.get('/dependency/invalidated/filepaths', dependencyInvalidatedFilepaths);
|
|
59
|
+
routes.get('/dependency/tag/parents', dependencyTagParents);
|
|
60
|
+
routes.get('/dependency', dependencyIndex);
|
|
45
61
|
routes.get(['/data/*', '/data'], data);
|
|
46
62
|
|
|
47
63
|
export default routes;
|
|
@@ -8,11 +8,6 @@ import { store } from '@lib/store';
|
|
|
8
8
|
import { jsonify } from '@lib/utils/object';
|
|
9
9
|
import { diffManager } from '@lib/store/diff/diffManager';
|
|
10
10
|
import { ObjectType } from '@lib/utils/object/object.types';
|
|
11
|
-
import { dependencyManager } from '@lib/store/dependency/dependencyManager';
|
|
12
|
-
import {
|
|
13
|
-
dependencyTree,
|
|
14
|
-
getReversedDependencyTree,
|
|
15
|
-
} from '@lib/store/dependency/dependencyTagger';
|
|
16
11
|
|
|
17
12
|
const statusIndex = (req: Request, res: Response): void => {
|
|
18
13
|
res.render('statusIndex', {
|
|
@@ -32,14 +27,11 @@ const statusBasic = (req: Request, res: Response): void => {
|
|
|
32
27
|
|
|
33
28
|
const response = {
|
|
34
29
|
config,
|
|
35
|
-
dataDirLastUpdate: dataDirManager.
|
|
30
|
+
dataDirLastUpdate: dataDirManager.getModificationUniqueId(),
|
|
36
31
|
query: {
|
|
37
32
|
numberOfExecutions: queryRunner.getCount(),
|
|
38
33
|
numberOfCachedQueries: cache.bin('query').size,
|
|
39
34
|
},
|
|
40
|
-
dependencyTree: jsonify(dependencyTree),
|
|
41
|
-
reversedDependencyTree: jsonify(getReversedDependencyTree()),
|
|
42
|
-
invalidatedFilepaths: dependencyManager.getInvalidatedFilepaths(),
|
|
43
35
|
};
|
|
44
36
|
|
|
45
37
|
res.status(200);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
extends includes/layout.pug
|
|
2
|
+
|
|
3
|
+
block vars
|
|
4
|
+
- var title = "Dependency | Static Suite Data Server"
|
|
5
|
+
|
|
6
|
+
block content
|
|
7
|
+
h1(class="title is-1")="Dependency"
|
|
8
|
+
table(class="table is-fullwidth is-hoverable")
|
|
9
|
+
tbody
|
|
10
|
+
each description, link in links
|
|
11
|
+
tr
|
|
12
|
+
td
|
|
13
|
+
a(href=link)= link
|
|
14
|
+
td=description
|
package/src/lib/dataServer.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { store } from '@lib/store';
|
|
|
7
7
|
import { Store } from '@lib/store/store.types';
|
|
8
8
|
import { queryRunner } from '@lib/query';
|
|
9
9
|
import { taskRunner } from '@lib/task/taskRunner';
|
|
10
|
+
import { TaskRunner } from '@lib/task/task.types';
|
|
10
11
|
import {
|
|
11
12
|
QueryRunner,
|
|
12
13
|
QuerySuccessfulResponse,
|
|
@@ -77,5 +78,6 @@ export {
|
|
|
77
78
|
QueryErrorResponse,
|
|
78
79
|
QueryArgs,
|
|
79
80
|
QueryModule,
|
|
81
|
+
TaskRunner,
|
|
80
82
|
CacheStatus,
|
|
81
83
|
};
|
|
@@ -74,12 +74,14 @@ export const queryRunner: QueryRunner = {
|
|
|
74
74
|
queryCache.set(cacheId, queryResult);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
// Set tags for this query
|
|
77
|
+
// Set tags for this query, replacing any other, because query
|
|
78
|
+
// dependencies are set only by their "tags" field.
|
|
78
79
|
const queryTags =
|
|
79
80
|
queryResponse.tags && queryResponse.tags?.length > 0
|
|
80
81
|
? queryResponse.tags
|
|
81
82
|
: ['*'];
|
|
82
83
|
dependencyTagger.setDependency(queryDefinition, queryTags);
|
|
84
|
+
queryResult.tags = queryTags;
|
|
83
85
|
} catch (e) {
|
|
84
86
|
// Log error and rethrow.
|
|
85
87
|
logger.error(
|
|
@@ -23,16 +23,16 @@ export type DataDirManager = {
|
|
|
23
23
|
update(): ChangedFiles;
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
-
* Get
|
|
26
|
+
* Get unique id of last modification of data directory.
|
|
27
27
|
*
|
|
28
28
|
* @remarks
|
|
29
29
|
* Metadata about when and how is the data directory updated is
|
|
30
30
|
* stored in the work directory. If that directory is not present or
|
|
31
|
-
* not initialized with proper data, it returns the
|
|
32
|
-
* If the store is not yet loaded, it returns a
|
|
31
|
+
* not initialized with proper data, it returns the unique id of the store.
|
|
32
|
+
* If the store is not yet loaded, it returns a unique id in the past,
|
|
33
33
|
* the Unix Epoch (00:00:00 UTC on 1 January 1970).
|
|
34
34
|
*
|
|
35
|
-
* @returns The
|
|
35
|
+
* @returns The unique id of last modification of data directory
|
|
36
36
|
*/
|
|
37
|
-
|
|
37
|
+
getModificationUniqueId(): string;
|
|
38
38
|
};
|
|
@@ -3,7 +3,7 @@ import { config } from '@lib/config';
|
|
|
3
3
|
import { store } from '@lib/store';
|
|
4
4
|
import { findFilesInDir } from '@lib/utils/fs';
|
|
5
5
|
import { logger } from '@lib/utils/logger';
|
|
6
|
-
import { workDirHelper } from '@lib/store/workDir';
|
|
6
|
+
import { unixEpochUniqueId, workDirHelper } from '@lib/store/workDir';
|
|
7
7
|
import { cache } from '@lib/utils/cache';
|
|
8
8
|
import { storeManager } from '@lib/store/storeManager';
|
|
9
9
|
import { hookManager } from '@lib/store/hook';
|
|
@@ -13,6 +13,8 @@ import { DataDirManager } from './dataDir.types';
|
|
|
13
13
|
import { ChangedFiles } from '../workDir/workDir.types';
|
|
14
14
|
import { dependencyManager } from '../dependency/dependencyManager';
|
|
15
15
|
|
|
16
|
+
let initialUniqueIdAlreadySet = false;
|
|
17
|
+
|
|
16
18
|
export const dataDirManager: DataDirManager = {
|
|
17
19
|
load: () => {
|
|
18
20
|
logger.info('Loading data dir...');
|
|
@@ -28,11 +30,18 @@ export const dataDirManager: DataDirManager = {
|
|
|
28
30
|
hookManager.reset();
|
|
29
31
|
queryManager.reset();
|
|
30
32
|
taskManager.reset();
|
|
33
|
+
dependencyManager.reset();
|
|
31
34
|
|
|
32
35
|
// Invoke "store load start" hook.
|
|
33
36
|
hookManager.invokeOnStoreLoadStart();
|
|
34
37
|
|
|
35
|
-
|
|
38
|
+
const modificationUniqueId = dataDirManager.getModificationUniqueId();
|
|
39
|
+
if (!initialUniqueIdAlreadySet) {
|
|
40
|
+
store.initialUniqueId = modificationUniqueId;
|
|
41
|
+
initialUniqueIdAlreadySet = true;
|
|
42
|
+
}
|
|
43
|
+
store.currentUniqueId = modificationUniqueId;
|
|
44
|
+
logger.info(`Found unique id: ${store.currentUniqueId}`);
|
|
36
45
|
|
|
37
46
|
// Add all files, one by one.
|
|
38
47
|
const relativeFilePaths = findFilesInDir(config.dataDir);
|
|
@@ -62,29 +71,34 @@ export const dataDirManager: DataDirManager = {
|
|
|
62
71
|
},
|
|
63
72
|
|
|
64
73
|
update: () => {
|
|
65
|
-
const
|
|
74
|
+
const dataDirModificationUniqueId =
|
|
75
|
+
dataDirManager.getModificationUniqueId();
|
|
66
76
|
|
|
67
77
|
let changedFiles: ChangedFiles = {
|
|
68
78
|
updated: [],
|
|
69
79
|
deleted: [],
|
|
80
|
+
fromUniqueId: store.currentUniqueId,
|
|
81
|
+
toUniqueId: dataDirModificationUniqueId,
|
|
70
82
|
};
|
|
71
83
|
|
|
72
|
-
if (store.
|
|
73
|
-
if (
|
|
74
|
-
// Save store.syncDate to a variable and set it ASAP
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
store.syncDate = dataDirModificationDate;
|
|
84
|
+
if (store.currentUniqueId) {
|
|
85
|
+
if (dataDirModificationUniqueId > store.currentUniqueId) {
|
|
86
|
+
// Save store.syncDate to a variable and set it ASAP.
|
|
87
|
+
const storeLastUniqueId = store.currentUniqueId;
|
|
88
|
+
store.currentUniqueId = dataDirModificationUniqueId;
|
|
78
89
|
const startDate = microtime.now();
|
|
79
90
|
logger.debug(
|
|
80
|
-
`Data dir outdated. Current
|
|
91
|
+
`Data dir outdated. Current unique id in memory is ${storeLastUniqueId} but data dir is ${dataDirModificationUniqueId}`,
|
|
81
92
|
);
|
|
82
93
|
|
|
83
94
|
// Before updating anything, track down which filepaths are invalidated with
|
|
84
95
|
// the current set of dependencies, before those dependencies change.
|
|
85
96
|
dependencyManager.trackInvalidatedFilepaths();
|
|
86
97
|
|
|
87
|
-
changedFiles = workDirHelper.
|
|
98
|
+
changedFiles = workDirHelper.getChangedFilesBetween(
|
|
99
|
+
storeLastUniqueId,
|
|
100
|
+
dataDirModificationUniqueId,
|
|
101
|
+
);
|
|
88
102
|
hookManager.invokeOnStoreChangeStart(changedFiles);
|
|
89
103
|
changedFiles.updated.forEach(file => {
|
|
90
104
|
storeManager.update(file);
|
|
@@ -107,7 +121,7 @@ export const dataDirManager: DataDirManager = {
|
|
|
107
121
|
logger.debug(`Data dir updated in ${execTimeMs}ms.`);
|
|
108
122
|
} else {
|
|
109
123
|
logger.debug(
|
|
110
|
-
`Data dir up to date. Current
|
|
124
|
+
`Data dir up to date. Current unique id in memory is ${store.currentUniqueId} and data dir is ${dataDirModificationUniqueId}`,
|
|
111
125
|
);
|
|
112
126
|
}
|
|
113
127
|
} else {
|
|
@@ -116,6 +130,8 @@ export const dataDirManager: DataDirManager = {
|
|
|
116
130
|
return changedFiles;
|
|
117
131
|
},
|
|
118
132
|
|
|
119
|
-
|
|
120
|
-
workDirHelper.
|
|
133
|
+
getModificationUniqueId: (): string =>
|
|
134
|
+
workDirHelper.getModificationUniqueId() ||
|
|
135
|
+
store.currentUniqueId ||
|
|
136
|
+
unixEpochUniqueId,
|
|
121
137
|
};
|
|
@@ -37,11 +37,6 @@ export type DependencyTagger = {
|
|
|
37
37
|
* @param tags - The list of tags for which to invalidate dependency items.
|
|
38
38
|
*/
|
|
39
39
|
invalidateTags(tags: string[]): void;
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Resets the list of invalidated tags once consumed.
|
|
43
|
-
*/
|
|
44
|
-
// resetInvalidatedTags(): void;
|
|
45
40
|
};
|
|
46
41
|
|
|
47
42
|
/**
|
|
@@ -2,17 +2,17 @@ import { Json } from '@lib/utils/object/object.types';
|
|
|
2
2
|
import { dependencyTagger } from './dependencyTagger';
|
|
3
3
|
|
|
4
4
|
export const dependencyIncludeHelper = {
|
|
5
|
-
|
|
5
|
+
addIncludeDependencies: (filepath: string, json: Json): void => {
|
|
6
6
|
const includes = json?.metadata?.includes;
|
|
7
7
|
|
|
8
8
|
if (includes?.static) {
|
|
9
9
|
const staticIncludes = Object.values(includes?.static);
|
|
10
|
-
dependencyTagger.
|
|
10
|
+
dependencyTagger.addDependency(filepath, staticIncludes);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
if (includes?.dynamic) {
|
|
14
14
|
const dynamicIncludes = Object.values(includes?.dynamic);
|
|
15
|
-
dependencyTagger.
|
|
15
|
+
dependencyTagger.addDependency(filepath, dynamicIncludes);
|
|
16
16
|
// Queries are invalidated by any data change until they are executed,
|
|
17
17
|
// when they return their dependencies. They are "globally invalidable" when:
|
|
18
18
|
// 1) Are added for the first time
|
|
@@ -24,6 +24,8 @@ export const dependencyIncludeHelper = {
|
|
|
24
24
|
// 2) When that query is executed, it has a dependency on "node:1234"
|
|
25
25
|
// 3) When that file with a query is updated, the query has again a dependency on "*"
|
|
26
26
|
dynamicIncludes.forEach(queryDefinition => {
|
|
27
|
+
// This is explicity a "set" operation, because query dependencies are
|
|
28
|
+
// only set from a query's "tags" field.
|
|
27
29
|
dependencyTagger.setDependency(queryDefinition, ['*']);
|
|
28
30
|
});
|
|
29
31
|
}
|
|
@@ -10,7 +10,10 @@ const invalidatedFilepaths = {
|
|
|
10
10
|
/**
|
|
11
11
|
* Gets a list of parents of a dependency tag
|
|
12
12
|
*/
|
|
13
|
-
const getTagParents = (
|
|
13
|
+
export const getTagParents = (
|
|
14
|
+
tag: string,
|
|
15
|
+
parents = new Set<string>(),
|
|
16
|
+
): Set<string> => {
|
|
14
17
|
getReversedDependencyTree()
|
|
15
18
|
.get(tag)
|
|
16
19
|
?.forEach(parent => {
|
|
@@ -29,7 +32,7 @@ const getTagParents = (tag: string, parents = new Set<string>()) => {
|
|
|
29
32
|
* Iterates over all explicitly invalidated tags, and obtains all
|
|
30
33
|
* its parents.
|
|
31
34
|
*/
|
|
32
|
-
const
|
|
35
|
+
export const getAllInvalidatedTags = (): string[] => {
|
|
33
36
|
const allInvalidatedTags = new Set<string>();
|
|
34
37
|
const invalidatedTagsArray = Array.from(invalidatedTags);
|
|
35
38
|
if (invalidatedTagsArray.length > 0) {
|
|
@@ -54,7 +57,7 @@ const getInvalidatedTags = (): string[] => {
|
|
|
54
57
|
*/
|
|
55
58
|
export const dependencyManager: DependencyManager = {
|
|
56
59
|
trackInvalidatedFilepaths: () => {
|
|
57
|
-
const allInvalidatedTags =
|
|
60
|
+
const allInvalidatedTags = getAllInvalidatedTags();
|
|
58
61
|
allInvalidatedTags.forEach(invalidatedTag => {
|
|
59
62
|
if (store.deleted.has(invalidatedTag)) {
|
|
60
63
|
invalidatedFilepaths.deleted.add(invalidatedTag);
|
|
@@ -61,45 +61,9 @@ export const dependencyTagger: DependencyTagger = {
|
|
|
61
61
|
|
|
62
62
|
invalidateTags: tags => {
|
|
63
63
|
tags.forEach(tag => {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
},
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
/*
|
|
70
|
-
import { DependencyTagger } from './dependency.types';
|
|
71
|
-
|
|
72
|
-
export const dependencyTree = new Map<string, Set<string>>();
|
|
73
|
-
|
|
74
|
-
export const invalidatedTags = new Set<string>();
|
|
75
|
-
|
|
76
|
-
export const dependencyTagger: DependencyTagger = {
|
|
77
|
-
setDependency: (tag, dependsOnTags) => {
|
|
78
|
-
dependsOnTags.forEach(dependsOnTag => {
|
|
79
|
-
const previousData = dependencyTree.get(dependsOnTag);
|
|
80
|
-
if (previousData) {
|
|
81
|
-
previousData.add(tag);
|
|
82
|
-
} else {
|
|
83
|
-
dependencyTree.set(dependsOnTag, new Set<string>([tag]));
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
deleteDependency: (tag, dependsOnTags) => {
|
|
89
|
-
dependsOnTags.forEach(dependsOnTag => {
|
|
90
|
-
const previousData = dependencyTree.get(dependsOnTag);
|
|
91
|
-
if (previousData) {
|
|
92
|
-
previousData.delete(tag);
|
|
93
|
-
if (previousData.size === 0) {
|
|
94
|
-
dependencyTree.delete(dependsOnTag);
|
|
95
|
-
}
|
|
64
|
+
if (tag) {
|
|
65
|
+
invalidatedTags.add(tag);
|
|
96
66
|
}
|
|
97
67
|
});
|
|
98
68
|
},
|
|
99
|
-
|
|
100
|
-
invalidateTags: tags => {
|
|
101
|
-
tags.forEach(tag => {
|
|
102
|
-
invalidatedTags.add(tag);
|
|
103
|
-
});
|
|
104
|
-
},
|
|
105
|
-
}; */
|
|
69
|
+
};
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export type DiffManager = {
|
|
5
5
|
/**
|
|
6
|
-
* Clears intermediate changes tracked by
|
|
6
|
+
* Clears intermediate changes tracked by dependency manager.
|
|
7
7
|
*
|
|
8
|
-
* @param
|
|
8
|
+
* @param uniqueId - Unique id to be used for the next diff.
|
|
9
9
|
*/
|
|
10
|
-
reset(
|
|
10
|
+
reset(uniqueId: string): void;
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Gets a list of changed files affected by includes and queries.
|
|
@@ -35,9 +35,18 @@ export type DiffManager = {
|
|
|
35
35
|
*/
|
|
36
36
|
export type Diff = {
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
38
|
+
* Execution time taken by the diff, in milliseconds.
|
|
39
39
|
*/
|
|
40
|
-
|
|
40
|
+
execTimeMs: number;
|
|
41
|
+
/**
|
|
42
|
+
* A unique id representing the date from which this diff is obtained.
|
|
43
|
+
*/
|
|
44
|
+
fromUniqueId: string;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* A unique id representing the date until which this diff is obtained.
|
|
48
|
+
*/
|
|
49
|
+
toUniqueId: string;
|
|
41
50
|
|
|
42
51
|
/**
|
|
43
52
|
* A list of updated files (both newly added and changed files).
|
|
@@ -1,115 +1,76 @@
|
|
|
1
1
|
import microtime from 'microtime';
|
|
2
2
|
import { logger } from '@lib/utils/logger';
|
|
3
3
|
import { store } from '../store';
|
|
4
|
-
import { DiffManager, Diff } from './
|
|
4
|
+
import { DiffManager, Diff } from './diff.types';
|
|
5
5
|
import { dataDirManager } from '../dataDir/dataDirManager';
|
|
6
6
|
import { dependencyManager } from '../dependency/dependencyManager';
|
|
7
|
+
import { unixEpochUniqueId, workDirHelper } from '../workDir';
|
|
8
|
+
import { dumpMetadataHelper } from '../dump/dumpMetadataHelper';
|
|
7
9
|
|
|
8
|
-
let
|
|
10
|
+
let lastDiffUniqueId: string = unixEpochUniqueId;
|
|
9
11
|
|
|
10
12
|
export const diffManager: DiffManager = {
|
|
11
|
-
reset(
|
|
12
|
-
|
|
13
|
+
reset(uniqueId: string): void {
|
|
14
|
+
lastDiffUniqueId = uniqueId;
|
|
13
15
|
dependencyManager.reset();
|
|
14
16
|
},
|
|
15
17
|
|
|
16
|
-
getDiff(options = { incremental: true }): Diff {
|
|
17
|
-
const startDate = microtime.now();
|
|
18
|
-
|
|
19
|
-
// Before getting any diff data, update any pending changes from data dir.
|
|
20
|
-
dataDirManager.update();
|
|
21
|
-
|
|
22
|
-
let updated = new Set<string>();
|
|
23
|
-
let deleted = new Set<string>();
|
|
24
|
-
if (options.incremental && lastDiffDate) {
|
|
25
|
-
logger.debug(`Getting incremental diff using date "${lastDiffDate}"`);
|
|
26
|
-
const invalidatedFilepaths = dependencyManager.getInvalidatedFilepaths();
|
|
27
|
-
updated = new Set<string>(invalidatedFilepaths.updated);
|
|
28
|
-
deleted = new Set<string>(invalidatedFilepaths.deleted);
|
|
29
|
-
} else {
|
|
30
|
-
// If no sinceDate is passed, return all files
|
|
31
|
-
logger.debug(`Getting full diff with no date`);
|
|
32
|
-
updated = new Set<string>(store.data.keys());
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const diff: Diff = {
|
|
36
|
-
since: lastDiffDate ? lastDiffDate.getTime() : new Date(0).getTime(),
|
|
37
|
-
updated,
|
|
38
|
-
deleted,
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
logger.info(
|
|
42
|
-
`Diff created in ${(microtime.now() - startDate) / 1000} ms. Updated: ${
|
|
43
|
-
diff.updated.size
|
|
44
|
-
} / Deleted: ${diff.deleted.size}`,
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
// Log diff if not empty
|
|
48
|
-
// if (diff.updated.length || diff.deleted.length) {
|
|
49
|
-
// logger.debug(`Diff: "${JSON.stringify(jsonify(diff))}"`);
|
|
50
|
-
// }
|
|
51
|
-
|
|
52
|
-
return diff;
|
|
53
|
-
},
|
|
54
|
-
|
|
55
|
-
/*
|
|
56
18
|
getDiff(options = { incremental: true }): Diff {
|
|
57
19
|
const startDate = microtime.now();
|
|
58
20
|
|
|
59
21
|
// Before getting any diff data, update any pending changes from data dir.
|
|
60
22
|
const changedFiles = dataDirManager.update();
|
|
61
23
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
24
|
+
const updated = new Set<string>();
|
|
25
|
+
const deleted = new Set<string>();
|
|
26
|
+
|
|
27
|
+
const currentDumpUniqueId = dumpMetadataHelper.getCurrentDumpUniqueId();
|
|
28
|
+
const isFirstDiffAfterReboot = lastDiffUniqueId === unixEpochUniqueId;
|
|
29
|
+
const isADumpAvailable = currentDumpUniqueId !== unixEpochUniqueId;
|
|
30
|
+
// If both checks passes, check if something has changed after last dump to avoid a full diff:
|
|
31
|
+
if (isFirstDiffAfterReboot && isADumpAvailable) {
|
|
32
|
+
const dataDirModificationUniqueId = changedFiles.toUniqueId;
|
|
33
|
+
if (currentDumpUniqueId === store.initialUniqueId) {
|
|
34
|
+
// If nothing changed, use store.initialUniqueId as lastDiffUniqueId, to
|
|
35
|
+
// execute an incremental dump.
|
|
36
|
+
lastDiffUniqueId = store.initialUniqueId;
|
|
37
|
+
} else {
|
|
38
|
+
// If something changed, keep lastDiffUniqueId as is, and get the list of
|
|
39
|
+
// changed files from last dump. From that list, we need deleted files, since
|
|
40
|
+
// those files are no more in data dir and we need to remove them from dump dir.
|
|
41
|
+
const changedFilesSinceLastDump = workDirHelper.getChangedFilesBetween(
|
|
42
|
+
currentDumpUniqueId,
|
|
43
|
+
dataDirModificationUniqueId,
|
|
44
|
+
);
|
|
45
|
+
changedFilesSinceLastDump.deleted.forEach(filepath =>
|
|
46
|
+
deleted.add(filepath),
|
|
47
|
+
);
|
|
76
48
|
}
|
|
49
|
+
}
|
|
77
50
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
updated
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
// "deleted" includes only deleted files, and is based only
|
|
85
|
-
// on data coming from changedFiles, because all deleted files
|
|
86
|
-
// are stored on Static Suite Data Server log
|
|
87
|
-
deleted = new Set<string>(changedFiles.deleted);
|
|
88
|
-
|
|
89
|
-
// Add updated files affected by queries only if "updated" or "deleted"
|
|
90
|
-
// contain any changes.
|
|
91
|
-
if (updated.size > 0 || deleted.size > 0) {
|
|
92
|
-
queryTagManager
|
|
93
|
-
.getInvalidFilepaths()
|
|
94
|
-
.forEach(file => updated.add(file));
|
|
95
|
-
queryTagManager.resetInvalidatedTags();
|
|
96
|
-
}
|
|
51
|
+
if (options.incremental && lastDiffUniqueId !== unixEpochUniqueId) {
|
|
52
|
+
logger.debug(`Getting incremental diff using date "${lastDiffUniqueId}"`);
|
|
53
|
+
const invalidatedFilepaths = dependencyManager.getInvalidatedFilepaths();
|
|
54
|
+
invalidatedFilepaths.updated.forEach(filepath => updated.add(filepath));
|
|
55
|
+
invalidatedFilepaths.deleted.forEach(filepath => deleted.add(filepath));
|
|
97
56
|
} else {
|
|
98
|
-
//
|
|
57
|
+
// Return all files
|
|
99
58
|
logger.debug(`Getting full diff with no date`);
|
|
100
|
-
|
|
59
|
+
Array.from(store.data.keys()).forEach(key => updated.add(key));
|
|
101
60
|
}
|
|
102
61
|
|
|
62
|
+
const execTimeMs = (microtime.now() - startDate) / 1000;
|
|
63
|
+
|
|
103
64
|
const diff: Diff = {
|
|
104
|
-
|
|
65
|
+
execTimeMs,
|
|
66
|
+
fromUniqueId: lastDiffUniqueId,
|
|
67
|
+
toUniqueId: changedFiles.toUniqueId,
|
|
105
68
|
updated,
|
|
106
69
|
deleted,
|
|
107
70
|
};
|
|
108
71
|
|
|
109
72
|
logger.info(
|
|
110
|
-
`Diff created in ${
|
|
111
|
-
diff.updated.size
|
|
112
|
-
} / Deleted: ${diff.deleted.size}`,
|
|
73
|
+
`Diff created in ${execTimeMs} ms. Updated: ${diff.updated.size} / Deleted: ${diff.deleted.size}`,
|
|
113
74
|
);
|
|
114
75
|
|
|
115
76
|
// Log diff if not empty
|
|
@@ -118,5 +79,5 @@ export const diffManager: DiffManager = {
|
|
|
118
79
|
// }
|
|
119
80
|
|
|
120
81
|
return diff;
|
|
121
|
-
},
|
|
82
|
+
},
|
|
122
83
|
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Diff } from '../diff/diff.types';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Service that dumps resolved data (with resolved includes) into a dump directory.
|
|
3
5
|
*/
|
|
@@ -20,11 +22,11 @@ export type DumpManager = {
|
|
|
20
22
|
* Reset dump metadata.
|
|
21
23
|
*
|
|
22
24
|
* @remarks
|
|
23
|
-
* Resets dump metadata, removing any dump information older than the passed
|
|
25
|
+
* Resets dump metadata, removing any dump information older than the passed unique id.
|
|
24
26
|
*
|
|
25
|
-
* @param
|
|
27
|
+
* @param uniqueId - Unique id
|
|
26
28
|
*/
|
|
27
|
-
reset(
|
|
29
|
+
reset(uniqueId: string): void;
|
|
28
30
|
};
|
|
29
31
|
|
|
30
32
|
/**
|
|
@@ -32,9 +34,19 @@ export type DumpManager = {
|
|
|
32
34
|
*/
|
|
33
35
|
export type Dump = {
|
|
34
36
|
/**
|
|
35
|
-
*
|
|
37
|
+
* Execution time taken by the dump, in milliseconds.
|
|
36
38
|
*/
|
|
37
|
-
|
|
39
|
+
execTimeMs: number;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* A unique id representing the date from which this dump is obtained.
|
|
43
|
+
*/
|
|
44
|
+
fromUniqueId: string;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* A unique id representing the date until which this dump is obtained.
|
|
48
|
+
*/
|
|
49
|
+
toUniqueId: string;
|
|
38
50
|
|
|
39
51
|
/**
|
|
40
52
|
* A list of updated files, keyed by file path. Its value is an object with two keys,
|
|
@@ -55,7 +67,12 @@ export type Dump = {
|
|
|
55
67
|
deleted: Map<string, { oldPublicUrl: string | null; newPublicUrl: null }>;
|
|
56
68
|
|
|
57
69
|
/**
|
|
58
|
-
*
|
|
70
|
+
* The diff used to generate this dump.
|
|
59
71
|
*/
|
|
60
|
-
|
|
72
|
+
diff: Diff;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export type DumpMetadata = {
|
|
76
|
+
current: string;
|
|
77
|
+
dumps: Dump[];
|
|
61
78
|
};
|