Skip to content

Commit

Permalink
Adding missing paragraphs and missing links
Browse files Browse the repository at this point in the history
  • Loading branch information
cyfyifanchen committed Jul 14, 2024
1 parent ae55d59 commit df4f84c
Show file tree
Hide file tree
Showing 2 changed files with 208 additions and 2 deletions.
94 changes: 93 additions & 1 deletion markdowns/tutorials/extension-tutorial-cpp.md
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,98 @@ protected:
}
```
In the markdown content you provided, there are descriptions of the lifecycle functions and message handling functions in Chinese. Here is the translation:
Lifecycle Functions:
- on_init: Used to initialize the extension instance, such as setting the extension's configuration.
- on_start: Used to start the extension instance, such as establishing connections to external services. The extension will not receive messages until on_start is completed. In on_start, you can use the rte.get_property API to retrieve the extension's configuration.
- on_stop: Used to stop the extension instance, such as closing connections to external services.
- on_deinit: Used to destroy the extension instance, such as releasing memory resources.
Message Handling Functions:
- on_cmd/on_data/on_pcm_frame/on_image_frame: These are callback methods used to receive messages of four different types. For more information on ASTRA message types, you can refer to the [message-type-and-name](../message-type-and-name.md)
The rte::extension_t class provides default implementations for these functions, and developers can override them according to their needs.
### Registering the Extension
After defining the extension, it needs to be registered as an addon in the ASTRA runtime. For example, in the `first_cxx_extension/src/main.cc` file, the registration code is as follows:
``` C++
RTE_CPP_REGISTER_ADDON_AS_EXTENSION(first_cxx_extension, first_cxx_extension_extension_t);
```

- RTE_CPP_REGISTER_ADDON_AS_EXTENSION is a macro provided by the ASTRA runtime for registering extension addons.
- The first parameter is the name of the addon, which serves as a unique identifier for the addon. It will be used to define the extension in the graph using a declarative approach.
- The second parameter is the implementation class of the extension, which is the class that inherits from rte::extension_t.

Please note that the addon name must be unique because it is used as a unique index to find the implementation in the graph.

### on_init

Developers can set the extension's configuration in the on_init() function, as shown in the example:

``` C++
void on_init(rte::rte_t& rte, rte::metadata_info_t& manifest,
rte::metadata_info_t& property) override {
property.set(RTE_METADATA_JSON_FILENAME, "customized_property.json");
rte.on_init_done(manifest, property);
}
```
Both the property and manifest can be customized using the set() method. In the example, the first parameter RTE_METADATA_JSON_FILENAME indicates that the custom property is stored as a local file, and the second parameter is the file path relative to the extension directory. So in this example, when the app loads the extension, it will load `<app>/addon/extension/first_cxx_extension/customized_property.json`.
ASTRA's on_init provides default logic for loading default configurations. If developers do not call property.set(), the property.json file in the extension directory will be loaded by default. Similarly, if manifest.set() is not called, the manifest.json file in the extension directory will be loaded by default. In the example, since property.set() is called, the property.json file will not be loaded by default.
Please note that on_init is an asynchronous method, and developers need to call rte.on_init_done() to inform the ASTRA runtime that on_init has completed as expected.
### on_start
When on_start is called, it means that on_init_done() has been executed and the extension's property has been loaded. From this point on, the extension can access the configuration. For example:
``` C++
void on_start(rte::rte_t& rte) override {
auto prop = rte.get_property_string("some_string");
// do something
rte.on_start_done();
}
```

rte.get_property_string() is used to retrieve a property of type string with the name "some_string". If the property does not exist or the type does not match, an error will be returned. If the extension's configuration contains the following content:

``` json
{
"some_string": "hello world"
}
```

Then the value of prop will be "hello world".

Similar to on_init, on_start is also an asynchronous method, and developers need to call rte.on_start_done() to inform the ASTRA runtime that on_start has completed as expected.

For more information, you can refer to the API documentation: rte api doc.

### Error Handling

As shown in the previous example, if "some_string" does not exist or is not of type string, rte.get_property_string() will return an error. You can handle the error as follows:

``` C++
void on_start(rte::rte_t& rte) override {
rte::error_t err;
auto prop = rte.get_property_string("some_string", &err);

// error handling
if (!err.is_success()) {
RTE_LOGE("Failed to get property: %s", err.errmsg());
}

rte.on_start_done();
}
```
### Message Handling
ASTRA provides four types of messages: `cmd`, `data`, `image_frame`, and `pcm_frame`. Developers can handle these four types of messages by implementing the `on_cmd`, `on_data`, `on_image_frame`, and `on_pcm_frame` callback methods.
Expand Down Expand Up @@ -461,7 +553,7 @@ Note

</div>

For the usage of schema, refer to: `usage of rte schema <usage_of_rte_schema_cn>`.
For the usage of schema, refer to: [rte-schema](../rte-schema.md)

</div>

Expand Down
116 changes: 115 additions & 1 deletion markdowns/tutorials/extension-tutorial-go.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,119 @@ The "manifest.json" file includes a dependency on "rte_runtime_go" by default:
"api": {}
}
```
<div class="note">

<div class="title">

Note

</div>

- Please note that according to ASTRA's naming convention, the <span class="title-ref">name</span> should be alphanumeric because when integrating the extension into an app, a directory will be created based on the extension name. Additionally, ASTRA will provide functionality to load the <span class="title-ref">manifest.json</span> and <span class="title-ref">property.json</span> files from the extension directory.
- The dependencies section declares the dependencies of the current extension. When installing the ASTRA package, arpm will automatically download the declared dependencies.
- The api section is used to declare the schema of the extension. For the usage of schema, refer to: [rte-schema](../rte-schema.md)

</div>

ASTRA GO API is not publicly available and needs to be installed locally using arpm. Therefore, the <span class="title-ref">go.mod</span> file uses the <span class="title-ref">replace</span> directive to reference the ASTRA GO API. For example:

``` GO
replace agora.io/rte => ../../../interface
```

When the extension is installed in an app, it will be placed in the <span class="title-ref">addon/extension/</span> directory. At the same time, the ASTRA GO API will be installed in the root directory of the app. The expected directory structure is as follows:

``` text
.
├── addon
│ └── extension
│ └── first_go_extension
│ ├── default_extension.go
│ ├── go.mod
│ ├── manifest.json
│ └── property.json
├── go.mod
├── go.sum
├── interface
│ └── rtego
└── main.go
```

Therefore, the <span class="title-ref">replace</span> directive in the extension's go.mod file points to the <span class="title-ref">interface</span> directory in the app.

### Manual Creation

Alternatively, developers can create a go module project using the <span class="title-ref">go init</span> command and then create the <span class="title-ref">manifest.json</span> and <span class="title-ref">property.json</span> files based on the examples provided above.

Do not add the dependency on the ASTRA GO API yet because the required <span class="title-ref">interface</span> directory is not available locally. It needs to be installed using arpm before adding the dependency.

To convert a newly created go module project or an existing one into an extension project, follow these steps:

- Create the <span class="title-ref">property.json</span> file in the project directory and add the necessary configuration for the extension.
- Create the <span class="title-ref">manifest.json</span> file in the project directory and specify the <span class="title-ref">type</span>, <span class="title-ref">name</span>, <span class="title-ref">version</span>, <span class="title-ref">language</span>, and <span class="title-ref">dependencies</span> information. Note that these fields are required.
- The <span class="title-ref">type</span> should be <span class="title-ref">extension</span>.
- The <span class="title-ref">language</span> should be <span class="title-ref">go</span>.
- The <span class="title-ref">dependencies</span> should include the dependency on <span class="title-ref">rte_runtime_go</span> and any other dependencies as needed.

## Download Dependencies

Execute the following command in the extension project directory to download dependencies:

``` shell
$ arpm install
```

After the command is successfully executed, a <span class="title-ref">.rte</span> directory will be generated in the current directory, which contains all the dependencies of the current extension.

<div class="note">

<div class="title">

Note

</div>

- There are two modes for an extension: development mode and runtime mode. In development mode, the root directory is the source code directory of the extension. In runtime mode, the root directory is the app directory. Therefore, the placement path of dependencies is different in these two modes. The <span class="title-ref">.rte</span> directory mentioned here is the root directory of dependencies in development mode.

</div>

The directory structure is as follows:

``` text
├── default_extension.go
├── go.mod
├── manifest.json
├── property.json
└── .rte
└── app
```

In this structure, <span class="title-ref">.rte/app/interface</span> is the module for the ASTRA GO API.

Therefore, in development mode, the <span class="title-ref">go.mod</span> file of the extension should be modified as follows:

``` GO
replace agora.io/rte => ./.rte/app/interface
```

If you manually created the extension as mentioned in the previous section, you also need to execute the following command in the extension directory:

``` shell
$ go get agora.io/rte
```

The expected output should be:

``` shell
go: added agora.io/rte v0.0.0-00010101000000-000000000000
```

At this point, an ASTRA GO extension project has been created.

## Implementing Extension Functionality



The "go.mod" file uses the "replace" directive to reference the ASTRA GO API:

Expand Down Expand Up @@ -212,7 +325,8 @@ Lifecycle functions:

Message handling functions:

- OnCmd/OnData/OnImageFrame/OnPcmFrame: Callback functions for receiving four types of messages. The message types in ASTRA can be referred to as `message type and name`.
- OnCmd/OnData/OnImageFrame/OnPcmFrame: Callback functions for receiving four types of messages. The message types in ASTRA can be referred to as [message-type-and-name](../message-type-and-name.md)


For the implementation of the extension, you may only need to focus on a subset of message types. To facilitate implementation, ASTRA provides a default `DefaultExtension`. Developers have two options: either directly implement the `rtego.Extension` interface or embed `DefaultExtension` and override the necessary methods.

Expand Down

0 comments on commit df4f84c

Please sign in to comment.