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