Skip to content

Commit a393f2e

Browse files
committed
Add RFC0014: Task Workers
1 parent 1c0b712 commit a393f2e

File tree

1 file changed

+141
-0
lines changed

1 file changed

+141
-0
lines changed

rfcs/0014-task-workers.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
- Start Date: 2023-11-08
2+
- RFC PR: -
3+
- Issue: -
4+
- Affected components <!-- Check affected components by writing an "X" into the brackets -->
5+
+ [x] [ui5-builder](https://github.com/SAP/ui5-builder)
6+
+ [ ] [ui5-server](https://github.com/SAP/ui5-server)
7+
+ [ ] [ui5-cli](https://github.com/SAP/ui5-cli)
8+
+ [ ] [ui5-fs](https://github.com/SAP/ui5-fs)
9+
+ [x] [ui5-project](https://github.com/SAP/ui5-project)
10+
+ [ ] [ui5-logger](https://github.com/SAP/ui5-logger)
11+
12+
13+
# RFC 0014 Task Workers
14+
15+
## Summary
16+
<!-- You can either remove the following explanatory text or move it into this comment for later reference -->
17+
18+
Concept for a new API provided to UI5 Tooling build tasks, enabling easy use of Node.js [Worker Threads](https://nodejs.org/api/worker_threads.html) to execute CPU intensive operations outside of the main thread.
19+
20+
## Motivation
21+
<!-- You can either remove the following explanatory text or move it into this comment for later reference -->
22+
23+
The two existing tasks `minify` and `buildThemes` should share the same pool of [workers](https://nodejs.org/api/worker_threads.html) so that there is no unnecessary teardown/startup of workers during a build.
24+
25+
The pool should also be re-used when multiple projects are being built, either in a `ui5 build --all` scenario, or concurrent project builds (as suggested in https://github.com/SAP/ui5-tooling/issues/894) within the same Node.js process to prevent creating multiple workerpools which might slow down the overall build or even system performance.
26+
27+
## Detailed design
28+
<!-- You can either remove the following explanatory text or move it into this comment for later reference -->
29+
30+
### Terminology
31+
32+
* `Worker`: A Node.js [Worker thread](https://nodejs.org/api/worker_threads.html) instance
33+
* `Task Processor`: A module associated with a UI5 Tooling build task (standard or custom) that can be executed in a `Worker`
34+
* `Thread Runner`: A ui5-project module that will be loaded in a `Worker`. It handles communication with the main thread and executes a `Task Processor` on request
35+
* `Dispatcher`: A ui5-project singleton module which uses a library like [`workerpool`](https://github.com/josdejong/workerpool) to spawn and manage `Worker` instances in order to have them execute any `Task Processor` requested by the build task
36+
- Handles the `Worker` lifecycle
37+
38+
### Key Design Decisions
39+
40+
* Task Processors shall be called with a well defined signature as described [below](#task-processor)
41+
* A Task Processor should not be exposed to Worker-specific API
42+
- I.e. it can be executed on the main thread as well as in a Worker
43+
* The Work Dispatcher and Thread Runner modules will handle all inter-process communication
44+
- This includes serializing and de-serializing `@ui5/fs/Resource` instances
45+
* Custom tasks can opt into this feature by defining one ore more "Task Processor" modules in its ui5.yaml
46+
* A Task can only invoke its own Task Processor(s)
47+
48+
### Assumptions
49+
50+
* A Task Processor is assumed to utilize a CPU thread by 90-100%
51+
- Accordingly they are also assumed to execute little to no I/O operations
52+
- This means one Worker should never execute more than one Task Processor at the same time
53+
* A Task Processor is stateless
54+
55+
### Task Processor
56+
57+
Similar to Tasks, Task Processors shall be invoked with a well defined signature:
58+
59+
* `resources`: An array of `@ui5/fs/Resource` provided by the build task
60+
* `options`: An object provided by the build task
61+
* `workspace`: Reader to read project files
62+
* `dependencies`: Reader or collection to read dependency files
63+
64+
```js
65+
/**
66+
* Task Processor example
67+
*
68+
* @param {Object} parameters Parameters
69+
* @param {DuplexCollection} parameters.workspace DuplexCollection to read and write files
70+
* @param {AbstractReader} parameters.dependencies Reader or Collection to read dependency files
71+
* @param {Object} parameters.options Options provided by the calling task
72+
* @returns {Promise<object>} Promise resolving with an object containing the result of the process in an arbitrary format
73+
*/
74+
module.exports = function({resources, workspace, dependencies, options}) {
75+
// [...]
76+
};
77+
````
78+
79+
### Task Configuration
80+
81+
82+
```yaml
83+
specVersion: "3.3"
84+
kind: extension
85+
type: task
86+
metadata:
87+
name: pi
88+
task:
89+
path: lib/tasks/pi.js
90+
processors:
91+
computePi: lib/tasks/piProcessor.js
92+
```
93+
94+
95+
### Task API
96+
97+
```js
98+
/**
99+
* Custom task example
100+
*
101+
* @param {Object} parameters Parameters
102+
* @param {DuplexCollection} parameters.workspace DuplexCollection to read and write files
103+
* @param {AbstractReader} parameters.dependencies Reader or Collection to read dependency files
104+
* @param {Object} parameters.options Options
105+
* @param {string} parameters.options.projectName Project name
106+
* @param {string} [parameters.options.configuration] Task configuration if given in ui5.yaml
107+
* @param {object} processors
108+
* @returns {Promise<undefined>} Promise resolving with undefined once data has been written
109+
*/
110+
module.exports = function({workspace, options, processors}) {
111+
const res = await processors.execute("computePi", {
112+
options: {
113+
digits: 1000000
114+
}
115+
});
116+
// [...]
117+
};
118+
````
119+
120+
121+
## How we teach this
122+
<!-- You can either remove the following explanatory text or move it into this comment for later reference -->
123+
124+
**TODO**
125+
126+
## Drawbacks
127+
<!-- You can either remove the following explanatory text or move it into this comment for later reference -->
128+
129+
**TODO**
130+
131+
## Alternatives
132+
<!-- You can either remove the following explanatory text or move it into this comment for later reference -->
133+
134+
**TODO**
135+
136+
## Unresolved Questions and Bikeshedding
137+
<!-- You can either remove the following explanatory text or move it into this comment for later reference -->
138+
139+
*This section should be removed (i.e. resolved) before merging*
140+
141+
**TODO**

0 commit comments

Comments
 (0)