Skip to content

Commit 25f8e8e

Browse files
committed
docs(documentation): Describe resource tag handling
1 parent 1b4980d commit 25f8e8e

3 files changed

Lines changed: 87 additions & 19 deletions

File tree

rfcs/0017-incremental-build.md

Lines changed: 87 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -105,24 +105,52 @@ The Project Build Cache uses this information to determine whether a changed res
105105

106106
All necessary metadata stored in the `Build Task Cache` is serialized to disk as part of the [Build Task Metadata](#build-task-metadata).
107107

108+
### Enhancements in Existing Components
109+
108110
#### Project
109111

110-
The existing `Project` super-class shall be extended to support the new concept of `stage writers`.
112+
The existing `Project` class shall be extended to support the new concept of `stage writers`. Specifically, resource handling shall be extracted into a new [`Project Resources`](#project-resources) class, responsible for managing the different resource readers and writers of a project. The `Project` class will delegate all resource-related operations to this new class. This shall also include the handling of [resource tags](#resource-tags).
113+
114+
Before the `Project` class was responsible for providing the project's `workspace`, to be used by build tasks. This `workspace` consisted of a single `reader` (providing access to the project's sources) and a `writer` for storing all resources that have been newly produced or changed by the build in memory.
115+
116+
#### Project Resources
111117

112-
Already before, it was responsible for creating the `workspace` for a build, which consisted of a single `reader` (providing access to the project's sources) and a `writer` (storing all resources that have been newly produced or changed by the build in memory).
118+
A new `Project Resources` class shall be created to manage the access to a project's resources and decouple this responsibility from the `Project` class. This class will be responsible for managing the different resource readers and writers of a project, including the handling of resource tags.
113119

114-
Now, each `Project` instance shall feature multiple `stages`. One for each task in the build process. Each stage holds either either a `writer` or a `cached writer` (if the stage has been restored from cache). Cached-writers are read-only.
120+
In order to support the incremental build, the `Project Resources` class shall manage multiple resource `stages`. One for each task in the build process. Each stage holds either either a `writer` or, in case the stage has been restored from cache, a `cached writer`. The latter being read-only. Additionally, each stage contains a two `ResourceTagCollection` instances for managing resource tags (see [resource tags](#resource-tags)).
115121

116-
During the project build, and before executing a task, the `Project Build Cache` shall set the correct stage in the Project. E.g. before executing the `replaceCopyright` task, the Project's stage is set to `task/replaceCopyright`.
122+
During the project build, and before executing a task, the `Project Build Cache` shall set the correct stage in the `Project Resources` instance. E.g. before executing the `replaceCopyright` task, the stage is set to `task/replaceCopyright`.
117123

118-
Whenever progressing to a new stage, the stage is initialized with an empty writer. The `Project Build Cache` can replace this writer with a `cached writer`, in case a previous execution of the task has been cached and the cache is still valid.
124+
Whenever progressing to a new stage, the stage is initialized with an empty writer and resource tag collection. The `Project Build Cache` can replace the writer with a `cached writer`, in case a previous execution of the task has been cached and the cache is still valid. Similarly, the resource tag collection is updated based on cached tag operations for the stage. Note that this includes clearing tags.
119125

120-
Once a `workspace` is requested from the `Project` instance, it will create one using a `reader` that combines the writers of all previous stages stages (as well as the project's sources), and the writer of the current stage.
126+
Once a `workspace` is requested from the `Project Resources` instance, it will internally create a [DuplexCollection](https://ui5.github.io/cli/stable/api/@ui5_fs_DuplexCollection.html) using a `reader` that combines the writers of all previous stages stages (as well as the project's sources), and the writer of the current stage.
127+
128+
When requesting the `resourceTagCollection` for a stage, the `Project Resources` instance will return a `Monitored Tag Collection` wrapper around the actual `Resource Tag Collection` of the stage. This allows to track all tag operations performed during a task's execution, and store them in the cache (see [Monitored Tag Collection](#monitored-tag-collection)). A notable difference to the handling of resources is that there is a single `Resource Tag Collection` per project, which is being cleared at the beginning of every build and then populated with the tags of each stage as the build progresses.
121129

122130
Stages have an explicit order, defined during their initialization. Stages shall be named using the following schema: `<type>/<name>`, where `<type>` is the type of the stage (e.g. `task`) and `<name>` is the name of the entity creating the stage (e.g. the task name).
123131

124132
![Diagram illustrating project stages](./resources/0017-incremental-build/Project_Stages.png)
125133

134+
#### Monitored Reader
135+
136+
A `MonitoredReader` is a wrapper around a `Reader` or `Writer` instance that observes which resources are being accessed during its usage. It records the requested paths as well as glob patterns that have been used to request resources.
137+
138+
This information is used in the [`Resource Request Graph`](#resource-request-graph).
139+
140+
#### Monitored Tag Collection
141+
142+
During build task execution, tasks may associate resources with "tags" (key value pairs). These tags are collected in shared `TagCollection` instances. Tags are differentiated between `build`-tags and `project`-tags. While `build`-tags are only available during an individual project's build (i.e. they are not accessible to builds of dependent projects), `project`-tags are shared across the entire build and can be accessed by all tasks of the project and its dependencies. This allows tasks to communicate information about resources to downstream tasks, even across project boundaries.
143+
144+
To support caching of resource tags, a `Monitored Tag Collection` wrapper is introduced, following the same pattern established by the `Monitored Reader` for tracking resource access.
145+
146+
It wraps a given `Resource Tag Collection` and intercepts all tag operations during a task's execution and records which tags have been set or cleared. This allows the `Project Build Cache` to capture and persist the tags produced by each task.
147+
148+
Build tasks can access resource tags using the `Task Util` API, which internally retrieves the `Monitored Tag Collection` for the current stage from the current `Project` instance.
149+
150+
After the task completes, the `Project Build Cache` retrieves the recorded tags from the `Monitored Tag Collection` and stores them as part of the stage metadata.
151+
152+
Each `Project Resources` instance manages two `Resource Tag Collections`, one for `build`-tags and one for `project`-tags. The `build`-tags collection is cleared at the end of each project build and therefore not accessible to dependent projects.
153+
126154
#### Project Builder
127155

128156
The `Project Builder` shall be enhanced to:
@@ -170,12 +198,6 @@ Build tasks can now optionally support "differential builds" by implementing the
170198

171199
These methods took some inspiration from the existing [`determineRequiredDependencies` method](https://github.com/UI5/cli/blob/main/rfcs/0012-UI5-Tooling-Extension-API-3.md#new-api-2) ([docs](https://ui5.github.io/cli/stable/pages/extensibility/CustomTasks/#required-dependencies)).
172200

173-
#### Monitored Reader
174-
175-
A `MonitoredReader` is a wrapper around a `Reader` or `Writer` instance that observes which resources are being accessed during its usage. It records the requested paths as well as glob patterns that have been used to request resources.
176-
177-
This information is used in the [`Resource Request Graph`](#resource-request-graph).
178-
179201
#### Resource Request Graph
180202

181203
A graph recording the request sets of a build task across multiple executions.
@@ -366,21 +388,67 @@ The resource requests are stored in a serialized [`Resource Request Graph`](#res
366388
### Stage Metadata
367389

368390
```jsonc
369-
"resourceMetadata": {
370-
// Virtual paths written by the task during execution, mapped to their cache metadata
391+
"resourceMapping": {
392+
"/resources/propject/namespace/": 0,
393+
"/test-resources/propject/namespace/": 0,
394+
"/": 1
395+
},
396+
"resourceMetadata": [
397+
{
398+
// Virtual paths written by the task during execution, mapped to their cache metadata
399+
"/resources/project/namespace/Component.js": {
400+
"lastModified": 176468853453,
401+
"size": 4567,
402+
"integrity": "sha256-EvQbHDId8MgpzlgZllZv3lKvbK/h0qDHRmzeU+bxPMo="
403+
}
404+
// Virtual paths written by the task during execution, mapped to their cache metadata
405+
"/resources/project/namespace/Helper.js": {
406+
"lastModified": 1770643600860,
407+
"size": 473,
408+
"integrity": "sha256-gd33pMM2gCTxqoYxZyUYSsCKLhO+lZfFXT7MKUl7DSM=""
409+
}
410+
},
411+
{
412+
// Virtual paths written by the task during execution, mapped to their cache metadata
413+
"/index.html": {
414+
"lastModified": 176468853453,
415+
"size": 124,
416+
"integrity": "sha256-R70pB1+LgBnwvuxthr7afJv2eq8FBT3L4LO8tjloUX8="
417+
}
418+
}
419+
],
420+
"projectTagOperations": {
371421
"/resources/project/namespace/Component.js": {
372-
"lastModified": 176468853453,
373-
"size": 4567,
374-
"integrity": "sha256-EvQbHDId8MgpzlgZllZv3lKvbK/h0qDHRmzeU+bxPMo="
422+
"ui5:HasDebugVariant": true, // Set tag
423+
}
424+
},
425+
"buildTagOperations": {
426+
"/resources/project/namespace/Component.js": {
427+
"ui5:IsBundle": undefined, // Cleared tag
375428
}
376429
}
377430
```
378431
379-
Stores the metadata of all resources for a given "stage" (i.e. all resources written by a single build task). This metadata can be used to access the resource content from the content-addressable store.
432+
Stores the metadata of all resources for a given "stage" (i.e. all resources written by a single build task). This metadata can be used to access the resource content from the content-addressable store and to restore resource tag information.
380433
381434
For build tasks, the stage metadata is keyed using the the signature of the project-index and the dependency-index that produced the output. Both signatures are combined using a `-` separator. I.e. `<project-index-signature>-<dependency-index-signature>`. If a task did not consume any project- or any dependency-resources, that index signature is replaced with an `X` placeholder.
382435
383-
The contained metadata represents all resources **written** by that task during its execution. It includes the `lastModified`, `size` and `integrity` of each resource. This information is required for determining whether subsequent tasks need to be re-executed.
436+
The contained metadata represents all resources **written** by that task during its execution. It includes the `lastModified`, `size` and `integrity` of each resource. This information is required for determining whether subsequent tasks need to be re-executed. It also contains information on resource tag operations, such as setting a tag to a value or clearing a tag.
437+
438+
**Simplified Stage Metadata**
439+
440+
For some project types where no path mapping is done (e.g. type `module`), the stage metadata can be simplified to just store a single `resourceMetadata` object, mapping virtual paths directly to their cache metadata, without the need for an additional `resourceMapping`:
441+
442+
```jsonc
443+
"resourceMetadata": {
444+
// Virtual paths written by the task during execution, mapped to their cache metadata
445+
"/resource/path/Example.js": {
446+
"lastModified": 176468853453,
447+
"size": 4567,
448+
"integrity": "sha256-EvQbHDId8MgpzlgZllZv3lKvbK/h0qDHRmzeU+bxPMo="
449+
}
450+
}
451+
```
384452
385453
### Result Metadata
386454
444 Bytes
Binary file not shown.
24.2 KB
Loading

0 commit comments

Comments
 (0)