• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Overview of Sendable Objects
2
3In traditional JS engines, there is only one way to optimize the overhead of concurrent object communication: moving the implementation to the native side and reducing costs through the transfer or sharing of [Transferable objects](transferabled-object.md). However, this solution falls short of addressing the extensive demand for concurrent object communication. The issue remains unresolved in current JS engine implementations.
4
5ArkTS introduces the concept of Sendable objects, which support pass-by-reference during concurrent communication.
6
7Sendable objects are designed to be shareable across threads, maintaining a consistent reference to the same JS object before and after crossing thread boundaries. If a Sendable object contains JS or native content, it can be directly shared. However, if the underlying implementation is native, thread safety must be carefully considered. The following figure shows the communication process.
8
9![sendable](figures/sendable.png)
10
11Unlike other ArkTS objects, Sendable objects must have a fixed type at runtime.
12
13When multiple concurrent instances attempt to update Sendable data at the same time, data races occurs, such as multithreaded operations on [ArkTS shared container](arkts-collections-introduction.md). To prevent data races between concurrent instances, ArkTS provides an [asynchronous lock](arkts-async-lock-introduction.md). Additionally, objects can be frozen using the [object freezing interface](sendable-freeze.md), making them read-only and thereby eliminating the risk of data races.
14
15Sendable objects offer efficient communication between concurrent instances by means of pass by reference. They are generally suitable for scenarios where large custom objects need to be transferred between threads, such as when a child thread reads data from a database and returns it to the main thread.
16
17## Basic Concepts
18
19### Sendable Protocol
20
21The Sendable protocol defines the Sendable object system and its specifications in ArkTS. Data that complies with the Sendable protocol (referred to as Sendable objects) can be passed between concurrent instances in ArkTS.
22
23By default, Sendable data is passed by reference between concurrent instances (including the UI main thread, TaskPool thread, and Worker thread). Pass-by-copy is also supported.
24
25### ISendable
26
27The interface **ISendable** is introduced to the ArkTS common library [@arkts.lang](../reference/apis-arkts/js-apis-arkts-lang.md). It has no required methods or properties. ISendable is the parent type of all Sendable types except for null and undefined. ISendable is mainly used when you want to customize Sendable data structures. The class decorator [@Sendable decorator](#sendable-decorator) is the syntax sugar for implementing ISendable.
28
29### Sendable Class
30
31> **NOTE**
32>
33> Since API version 11, the \@Sendable decorator can be used to verify Sendable classes.
34
35A Sendable class must meet the following requirements:
36
371. It must be decorated by [@Sendable](#sendable-decorator).
38
392. It must meet the Sendable constraints. For details, see [Usage Rules and Constraints for Sendable](sendable-constraints.md).
40
41### Sendable Function
42
43> **NOTE**
44>
45> - Since API version 12, the \@Sendable decorator can be used to verify Sendable functions.
46>
47> - To use a Sendable function in API version 12, you must configure "compatibleSdkVersionStage": "beta3" in the project. Otherwise, the function does not take effect. For details, see [build-profile.json5](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-hvigor-build-profile-V5).
48
49A Sendable function must meet the following requirements:
50
511. It must be decorated by [@Sendable](#sendable-decorator).
52
532. It must meet the Sendable constraints. For details, see [Usage Rules and Constraints for Sendable](sendable-constraints.md).
54
55### Sendable Interface
56
57A Sendable interface must meet the following requirements:
58
591. It must be [ISendable](#isendable) or inherit from [ISendable](#isendable).
60
612. It must meet the Sendable constraints. For details, see [Usage Rules and Constraints for Sendable](sendable-constraints.md).
62
63### Sendable Data Types
64
65- All ArkTS basic data types: boolean, number, string, bigint, null, and undefined.
66
67- [Container types](arkts-collections-introduction.md) defined in ArkTS ([@arkts.collections](../reference/apis-arkts/js-apis-arkts-collections.md) must be explicitly introduced).
68
69- [Asynchronous lock objects](arkts-async-lock-introduction.md) defined in ArkTS ([@arkts.utils](../reference/apis-arkts/js-apis-arkts-utils.md) must be explicitly introduced).
70
71- Interfaces that inherit from [ISendable](#isendable).
72
73- Classes decorated by [@Sendable](#sendable-decorator).
74
75- Functions decorated by [@Sendable](#sendable-decorator).
76
77- System objects that integrate Sendable, which are as follows:
78  - [Sendable User Preferences](../reference/apis-arkdata/js-apis-data-sendablePreferences.md)
79  - [Sendable Color Space Management](../reference/apis-arkgraphics2d/js-apis-sendableColorSpaceManager.md)
80  - [Sendable Object-based Image Processing](../reference/apis-image-kit/js-apis-sendableImage.md)
81  - [Resource Management](../reference/apis-localization-kit/js-apis-sendable-resource-manager.md)
82  - [SendableContext Object Management](../reference/apis-ability-kit/js-apis-app-ability-sendableContextManager.md)
83
84- Elements whose union type data is of the Sendable type.
85
86> **NOTE**
87>
88> - Built-in JS objects are passed between concurrent instances following the structured clone algorithm, and their cross-thread behavior is pass-by-copy. Therefore, instances of JS built-in objects are not of the Sendable type.
89>
90> - Object literals and array literals are also passed between concurrent instances following the structured cloning algorithm, and their cross-thread behavior is pass-by-copy. Therefore, object literals and array literals are not of the Sendable type.
91
92
93## Implementation Principle of Sendable
94
95To implement pass-by-reference of [Sendable data](#sendable-data-types) between different concurrent instances, Sendable objects are allocated in a shared heap to achieve memory sharing across concurrent instances.
96
97
98The shared heap is a process-level heap space. Unlike the local heap of a virtual machine, which can only be accessed by a single concurrent instance, the shared heap can be accessed by all threads. The cross-thread behavior of a Sendable object is pass-by-reference. Therefore, a Sendable object may be referenced by multiple concurrent instances, and its liveness depends on whether any concurrent instance holds a reference to it.
99
100Relationship between the shared heap and local heap
101
102![image_0000002001521153](figures/image_0000002001521153.png)
103
104The local heap of each concurrent instance is isolated, whereas the shared heap is a process-level heap that can be referenced by all concurrent instances. However, the shared heap cannot reference objects in the local heap.
105
106
107## \@Sendable Decorator
108
109The \@Sendable decorator declares and verifies Sendable classes and functions.
110
111| \@Sendable Decorator| Description|
112| -------- | -------- |
113| Parameters| None.|
114| Usage restrictions| It can be used only in projects of the stage model and only in .ets files.|
115| Supported function types| Only regular functions and async functions can be decorated by @Sendable.|
116| Class inheritance restrictions| Sendable classes can only inherit from other Sendable classes. Regular classes cannot inherit from Sendable classes.|
117| Property type restrictions| 1. The following types are supported: string, number, boolean, bigint, null, undefined, Sendable class, collections.Array, collections.Map, collections.Set, and ArkTSUtils.locks.AsyncLock.<br>2. Closure variables are not allowed.<br>3. Private properties defined with \# are not supported; use **private** instead.<br>4. Computed properties are not supported.|
118| Other property restrictions| Member properties must be initialized explicitly. They cannot be followed by exclamation marks (!).|
119| Parameter restrictions for decorated functions or class methods| Local variables, parameters, and variables imported through **import** are allowed. Closure variables are not allowed, except for top-level Sendable classes and functions.|
120| Restrictions for Sendable classes and functions| Adding or deleting properties is not allowed. Modifying properties is allowed, but the type must remain consistent before and after modification. Modifying methods is not supported.|
121| Use scenario| 1. Scenarios where class methods or Sendable functions are used in TaskPool or Worker.<br>2. Scenarios involving large amounts of object data transmission. The time required for serialization increases with the data volume. After transforming data with Sendable, the efficiency of transmitting 100 KB of data is approximately 20 times higher, and for 1 MB of data, it is about 100 times higher.|
122
123The following is an example of using the decorator on a class:
124
125```ts
126@Sendable
127class SendableTestClass {
128  desc: string = "sendable: this is SendableTestClass ";
129  num: number = 5;
130  printName() {
131    console.info("sendable: SendableTestClass desc is: " + this.desc);
132  }
133  get getNum(): number {
134    return this.num;
135  }
136}
137```
138
139The following is an example of using the decorator on a function:
140
141```ts
142@Sendable
143type SendableFuncType = () => void;
144
145@Sendable
146class TopLevelSendableClass {
147  num: number = 1;
148  PrintNum() {
149    console.info("Top level sendable class");
150  }
151}
152
153@Sendable
154function TopLevelSendableFunction() {
155  console.info("Top level sendable function");
156}
157
158@Sendable
159function SendableTestFunction() {
160  const topClass = new TopLevelSendableClass(); // Top-level Sendable class.
161  topClass.PrintNum();
162  TopLevelSendableFunction(); // Top-level Sendable function.
163  console.info("Sendable test function");
164}
165
166@Sendable
167class SendableTestClass {
168  constructor(func: SendableFuncType) {
169    this.callback = func;
170  }
171  callback: SendableFuncType; // Top-level Sendable function.
172
173  CallSendableFunc() {
174    SendableTestFunction(); // Top-level Sendable function.
175  }
176}
177
178let sendableClass = new SendableTestClass(SendableTestFunction);
179sendableClass.callback();
180sendableClass.CallSendableFunc();
181```
182