• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Common Concurrency Issues
2
3## Troubleshooting for Non-Executing Tasks in the TaskPool
4
5If a task in a TaskPool is not executed, perform the following steps to quickly locate the fault:
6
71. Check whether the **taskpool.execute** API is called.
8
9   When the **taskpool.execute** API is called, HiLog prints a TaskPool maintenance log (**Task Allocation: taskId:**).
10
11   If this log is missing, **taskpool.execute** is not actually called. Check whether the service logic preceding this API has been completed.
12
13   ```ts
14   console.log("test start");
15   ... // Other service logic.
16   taskpool.execute(xxx);
17
18   // If "test start" is printed in the console but the Task Allocation: taskId: log is missing, taskpool.execute is not executed. Check the preceding service logic.
19   ```
20
212. Check whether the task in the TaskPool is executed.
22
23   Calling the **taskpool.execute** API will print a call state log **Task Allocation: taskId:**.
24
25   After locating the **Task Allocation: taskId:** log for the target task, search for the ID following **taskId** in the log. Under normal circumstances, an execution state log (**Task Perform: name:**) and an end state log (**Task PerformTask End: taskId:**) should be printed.
26
27   1.  If the call state log exists but the execution state log is missing, it may be because a preceding task has blocked the worker thread of the TaskPool, rendering it unavailable for subsequent tasks to execute. You should check the service logic or use trace to further pinpoint the issue.
28
29   2. If the call state log and execution state log exist but the end state log is missing, check whether there are blocking operations in the service logic of the custom TaskPool task.
30
31   3. If there is a significant time gap between the call state log and the execution state log, and your application is concerned about the timing of task execution, continue the analysis as follows:
32
33      1. Check whether there is a backlog of a large number of TaskPool tasks that have not been executed. If a large number of tasks are submitted in a short period (resulting in numerous call state logs), subsequent tasks have to wait for the preceding tasks to complete. At this point, check the TaskPool's scaling situation. If the number of worker threads of the TaskPool has already been scaled up to near the upper limit (the **maxThreads** field in log snippet 2) before the call state log is printed, it may be due to too many tasks being submitted in a short time. You should prioritize important and time-sensitive tasks by setting appropriate priorities.
34
35      2. Check whether the preceding tasks in the TaskPool are inherently time-consuming or have experienced blocking. If the preceding tasks are time-consuming, your application should address this by setting appropriate priorities. If the preceding tasks have encountered unexpected blocking (which is resolved after a period), check the service logic.
36
37   ```ts
38   // HiLog log snippet (simulation)
39   // Log 1: A large number of tasks are submitted.
40   taskpool:: Task Allocation: taskId: , priority: , executeState:
41   taskpool:: Task Allocation: taskId: , priority: , executeState:
42   taskpool:: Task Allocation: taskId: , priority: , executeState:
43   taskpool:: Task Allocation: taskId: , priority: , executeState:
44   taskpool:: Task Allocation: taskId: , priority: , executeState:
45   ...
46   // Log 2: scaling log
47   taskpool:: maxThreads: , create num: , total num:
48   // Log 3: execution state log
49   taskpool:: Task Perform: name: , taskId: , priority:
50   ```
51
523. Check whether exceptions occur during task execution in the TaskPool.
53
54   1. If a JavaScript exception occurs during task execution, the TaskPool catches the JavaScript exception and returns the exception information through **taskpool.execute().catch((e:Error)=>{})**. Review the exception information and rectify the fault.
55
56      ```ts
57      taskpool.execute().then((res: object)=>{
58        // Handle the result after task execution.
59        ...
60      }).catch((e: Error)=>{
61        // Handle the exception after task failure.
62        ...
63      })
64      ```
65
66   2. If the .catch branch does not return any exception information, but the application's functionality implemented through the tasks is malfunctioning, check whether there are blocking operations in the task logic that cause the function exceptions.
67
68## Troubleshooting for Slow Task Execution in the TaskPool
69
70If there is a significant time gap between the call state log (e.g., **taskpool::add taskId:** or **taskpool::Task Allocation: taskId:**) and the execution state log (**taskpool::Task Perform: name:**), follow this guide for troubleshooting.
71
72### Low-Priority Tasks Delayed by Many Medium-Priority Tasks
73
74**Scenario Example 1**
75
76An application creates a low-priority task that other service scenarios depend on for execution. Subsequently, the application creates many medium-priority tasks, causing the low-priority task to be executed later than planned, and other service scenarios fail to complete tasks at the scheduled time.
77
78**Solution**
79
80Executing tasks with low priority that have timing requirements is not a good choice. Applications should set reasonable task priorities based on service scenarios and properly combine task priorities.
81
82**Scenario Example 2**
83
84The application has a timing requirement for the execution of a certain task (referred to as taskA), with a detection mechanism for execution exceeding 5 seconds. The application sets taskA to medium priority and executes many other tasks with medium priority before taskA, which take 3 to 5 seconds each. These tasks occupy all existing and newly scaled-up threads, causing taskA to exceed 5 seconds from **taskpool.execute** to execution completion.
85
86**Solution**
87
881. Analyze whether the execution duration (3 to 5 seconds) for other tasks are reasonable.
892. Adjust the priority of taskA.
90
91### Tasks in Serial Queue Delayed by Slow Predecessors
92
93**Scenario Example**
94
95If the task is in a serial queue, check the execution of the preceding tasks in that serial queue. As shown in log snippet 1, the serial queue has four tasks, and the problem scenario corresponds to the fourth task. Log snippet 2 reveals that the second task took 2 seconds to execute, which is abnormal for the application's service logic.
96```ts
97// HiLog log snippet 1 (simulation)
98// seqRunner has four tasks.
99taskpool:: taskId 389508780288 in seqRunnner 393913878464 immediately.
100taskpool:: add taskId: 394062838784 to seqRunnner 393913878464
101taskpool:: add taskId: 393918679936 to seqRunnner 393913878464
102taskpool:: add taskId: 393918673408 to seqRunnner 393913878464
103
104// HiLog log snippet 2 (simulation)
105// Check the second task. It takes 2s to complete.
10618:28:28.223 taskpool:: taskId 394062838784 in seqRunner 393913878464 immediately.
10718:28:28.224 taskpool:: Task Perform: name : , taskId : 394062838784, priority : 0
10818:28:30.243 taskpool:: Task Perform End: taskId : 394062838784, performResult : Successful
109```
110
111**Solution**
112
113Further check whether there are time-consuming operations in the service logic of the second task.
114
115### ETS File Containing @Concurrent-Marked Methods Imports Too Many Modules
116
117**Scenario Example**
118
119The first execution of TaskPool tasks is slow, with a delay of several hundred milliseconds. The reason is that before deserialization in the child thread, all modules imported by the .ets file containing @Concurrent-marked methods are initialized, resulting in slow task scheduling. Use trace to further locate the issue. If there are many init module traces before successful deserialization, check whether the .ets file imports too many modules.
120
121**Solution**
122
1231. Split the @Concurrent methods into separate .ets files to reduce module initialization time.
1242. Use lazy import.
125
126## Troubleshooting for TaskPool Serialization Failures
127
128**Symptom**
129
1301. JavaScript exception
131
132   ```ts
133   Error message:An exception occurred during serialization, taskpool: failed to serialize arguments.
134   ```
135
1362. HiLog error log
137
138   ```ts
139   [ecmascript] Unsupport serialize object type:
140   [ecmascript] ValueSerialize: serialize data is incomplete
141   ```
142
143**Cause**
144
145The input parameters of the concurrent function used by the TaskPool to implement tasks must meet the types supported by inter-thread communication. For details, see [Inter-thread Communication Objects](../reference/apis-arkts/js-apis-taskpool.md#sequenceable-data-types). When unsupported communication objects are passed into the concurrent function, the above phenomena occur. Further check whether the parameters meet the requirements based on the object type printed in HiLog logs.
146
147**Scenario Example**
148
1491. The application throws a serialization failure exception when starting a task because it passes an unsupported object type for inter-thread communication into the concurrent function.
150**Solution**: Check the input parameters of the concurrent function based on [Inter-thread Communication Objects](../reference/apis-arkts/js-apis-taskpool.md#sequenceable-data-types).
151
1522. The application throws a serialization failure exception when starting a task, and HiLog prints the error log **Unsupport serialize object type: Proxy**. Based on the error log, the application passes a proxy object into the concurrent function. The parameter uses the @State decorator, causing the original object to become a Proxy object, which is not a supported object type for inter-thread communication.
153**Solution**: TaskPool does not support complex types decorated with @State and @Prop. For details, see [Precautions for TaskPool](taskpool-introduction.md#precautions-for-taskpool). The application should remove the @State decorator.
154
155## Using instanceof with Sendable Objects in Child Threads Returns False
156
157When using the **instanceof** operator in a child thread, the application needs to mark the module exporting Sendable class A in the .ets file with the **use shared** directive to indicate that the module is a [shared module](../arkts-utils/arkts-sendable-module.md#shared-module).
158
159**Code Example**
160
161```ts
162// pages/index.ets
163import { worker, ErrorEvent } from '@kit.ArkTS'
164import { A } from './sendable'
165const workerInstance = new worker.ThreadWorker('../workers/Worker.ets');
166function testInstanceof() {
167  let a = new A();
168  if (a instanceof A) {
169    // Print "test instanceof in main thread success".
170    console.log("test instanceof in main thread success");
171  } else {
172    console.log("test instanceof in main thread fail");
173  }
174  workerInstance.postMessageWithSharedSendable(a);
175  workerInstance.onerror = (err: ErrorEvent) => {
176    console.log("worker err :" + err.message)
177  }
178}
179
180testInstanceof()
181```
182```ts
183// pages/sendable.ets
184"use shared"
185@Sendable
186export class A {
187    name: string = "name";
188    printName(): string {
189        return this.name;
190    }
191}
192```
193```ts
194// workers/Worker.ets
195import { A } from '../pages/sendable'
196import { worker, ThreadWorkerGlobalScope, MessageEvents } from '@kit.ArkTS'
197
198const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
199workerPort.onmessage = (e: MessageEvents) => {
200    let a : A = e.data as A;
201    if (a instanceof A) {
202        // Print "test instanceof in worker thread success".
203        console.log("test instanceof in worker thread success");
204    } else {
205        console.log("test instanceof in worker thread fail");
206    }
207}
208```
209
210## Troubleshooting for JavaScript Exceptions Thrown by Sendable Features
211
212Due to the fixed layout and the constraint that Sendable objects cannot hold non-Sendable objects, an inappropriate modification to Sendable objects may lead to the throwing of corresponding JavaScript exceptions. Follow this guide for troubleshooting.
213
214### Type Mismatch Exception
215
216**Symptom**
217
218```ts
219JavaScript exception: TypeError: Cannot set sendable property with mismatched type
220```
221
222**Cause and Solution**
223
224ArkTS runtime strictly checks type consistency during property assignment. If the defined property type does not match the type of the passed object, the above JavaScript exception is thrown. Locate the corresponding .ts file code line based on the JavaScript exception stack and check the relevant service logic.
225
226**Scenario Example**
227
2281. A type mismatch exception is thrown when the application passes an instance of Sendable class A to a child thread. Based on the JavaScript stack, the problem occurs when creating an instance of class A. It is found that when the application is integrated with other modules, the other modules do not use Sendable class B to encapsulate the dataset.
229
230   **Solution**: Use a Sendable class to re-encapsulate the data passed by other modules into the current module.
231
232     ```ts
233     @Sendable
234     export class B {
235       constructor() {}
236     }
237
238     @Sendable
239     export class A {
240       constructor(b: B) {
241         this.b = b;
242       }
243       public b: B | undefined = undefined;
244     }
245     ```
246
2472. A type mismatch exception is thrown when the application runs the assignment statement **this.g = g**. It is found that the property **g** uses the @State decorator, causing the original object to become a Proxy object, resulting in a type mismatch.
248
249   **Solution**: Remove the @State decorator.
250
251### Adding Property Exception
252
253**Symptom**
254
255```ts
256JavaScript exception: TypeError: Cannot add property in prevent extensions
257```
258
259**Cause and Solution**
260
261Since the layout of Sendable classes is fixed and does not allow adding or removing properties, adding a new property to a Sendable object will throw the above JavaScript exception. Locate the corresponding .ts file code line based on the JavaScript exception stack and check the relevant service logic.
262
263**Scenario Example**
264
2651. The application defines a Sendable class and a namespace with the same name in the same .ets file. An exception is thrown when the application attempts to add a new property. Since TS merges classes and namespaces with the same name, appending the exports of the namespace to the class with the same name effectively adds a new property to the Sendable class, causing the exception.
266**Solution**: Due to specification limitations, merging Sendable classes and namespaces with the same name is currently not supported.
267
2682. An exception is thrown when the application attempts to add a new property while using the Sendable feature in a HAR. The exception code line is located in a .js file, and the Sendable feature is not supported in .js files, resulting in the exception.
269**Solution**: When using the Sendable feature in a HAR, [build TS files for the HAR](../quick-start/har-package.md#building-ts-files).
270
2713. An exception is thrown when the application attempts to add a new property while using the Sendable feature in Local Test or Previewer. Since the Sendable feature is currently not supported in Local Test and Previewer, the exception is thrown.
272**Solution**: Due to specification limitations, this is currently not supported.
273
274## What is the Principle Behind ArkTS Promise?
275
276Promise is the asynchronous concurrency capability provided by ArkTS and is a standard JavaScript syntax. For details, see [Promise](async-concurrency-overview.md#promise).
277
278## Can Taskpool Threads Execute JavaScript Closure Functions That Do Not Require @Concurrent and @Sendable Decorators?
279
280Task functions executed by the TaskPool must be decorated with @Concurrent. Since concurrent functions cannot access closures, they cannot call other regular functions within the same file. For details, see [Precautions for TaskPool](taskpool-introduction.md#precautions-for-taskpool). However, you can pass @Sendable-decorated regular functions and async functions as parameters to concurrent functions and call Sendable functions within the concurrent functions.
281
282TaskPool threads do not support executing regular JavaScript closure functions. If necessary, you can use the [Worker](worker-introduction.md) concurrency capability to reconstruct your services.
283