Message System

In the NYRA framework, messages are categorized into four primary types:

  • Command

  • Data

  • Video Frame

  • Audio Frame

The main difference between a command and other message types is that commands can have a result, while data, video frame, and audio frame messages do not.

Corresponding to these message types, NYRA extensions typically provide four message callbacks:

  • OnCmd

  • OnData

  • OnVideoFrame

  • OnAudioFrame

Message Classification

Here is a classification diagram of NYRA framework messages:

β”Œβ”€β”€ has result
β”‚   └── Command
β”‚       β”œβ”€β”€ NYRA framework built-in command
β”‚       β”‚    => message name starts with `nyra:`
β”‚       └── Non-NYRA framework built-in command
β”‚            => message name does not start with `nyra:`
└── no result
    β”œβ”€β”€ Data
    β”‚   β”œβ”€β”€ NYRA framework built-in data
    β”‚   β”‚    => message name starts with `nyra:`
    β”‚   └── Non-NYRA framework built-in data
    β”‚        => message name does not start with `nyra:`
    β”œβ”€β”€ Video Frame
    β”‚   β”œβ”€β”€ NYRA framework built-in video frame
    β”‚   β”‚    => message name starts with `nyra:`
    β”‚   └── Non-NYRA framework built-in video frame
    β”‚        => message name does not start with `nyra:`
    └── Audio Frame
        β”œβ”€β”€ NYRA framework built-in audio frame
        β”‚    => message name starts with `nyra:`
        └── Non-NYRA framework built-in audio frame
             => message name does not start with `nyra:`

Message Name

A message name in the NYRA framework distinguishes messages of the same type but with different purposes. Extensions rely on unique message names to determine the appropriate actions.

Naming rules for message names:

  1. The first character must be a letter (a-z, A-Z) or an underscore (_).

  2. Following characters can be letters (a-z, A-Z), digits (0-9), or underscores (_).

Message Flow

Message Flow

The NYRA framework supports three message flow patterns:

  1. One message, one result For actions that produce a single outcome.

  2. One message, multiple results For actions that yield more than one outcome.

  3. Multiple messages For actions that do not require any result data.

Extension Message Interface

The api field in an extension’s manifest describes the extension’s external message interface. It may include the following entries:

  • cmd_in

  • cmd_out

  • data_in

  • data_out

  • audio_frame_in

  • audio_frame_out

  • video_frame_in

  • video_frame_out

Below is an example definition:

{
  "api": {
    "cmd_in": [
      {
        "name": "cmd_foo",
        "property": {
          "foo": {
            "type": "int8"
          },
          "bar": {
            "type": "string"
          }
        },
        "result": {
          "property": {
            "aaa": {
              "type": "int8"
            },
            "bbb": {
              "type": "string"
            }
          }
        }
      }
    ],
    "cmd_out": [],
    "data_in": [
      {
        "name": "data_foo",
        "property": {
          "foo": {
            "type": "int8"
          },
          "bar": {
            "type": "string"
          }
        }
      }
    ],
    "data_out": [],
    "video_frame_in": [],
    "video_frame_out": [],
    "audio_frame_in": [],
    "audio_frame_out": []
  }
}

Message Pairing Analogy

The NYRA framework’s message pairing between extensions resembles function calls in traditional programming:

  • The message name is like the function name.

  • Message properties are like function parameters.

  • Pairing is based exclusively on the message name, not properties. (No function overloading equivalent.)

Hence, consistent naming is key for input/output messages in each extension, providing a β€œcontrol plane” for that extension.

Although the NYRA framework offers a language-agnostic message call system, it also supports static and dynamic checks (via NYRA schemas) to catch issues like mismatched property types between source and destination extensions.

Message Ownership in the NYRA Framework

Message Processing Follows the Concept of Ownership

Once a message is successfully sent, the sending extension loses ownership of the message. This ensures both thread safety and message safety within the framework. If one extension could continue using a message while another thread processes it, undefined behavior could occur.

The NYRA runtime enforces this rule, preventing an extension from interacting with a message after it’s been sent.

Message Ownership Transfer to the Extension

When the NYRA runtime delivers a message to an extension through OnCmd, OnData, OnVideoFrame, or OnAudioFrame, ownership of that message passes to the receiving extension. Only that extension can now safely modify or reference the message. When it’s done, it must return ownership to the NYRA runtime.

Message Ownership Transfer to the NYRA Runtime

Conversely, when an extension uses APIs such as SendCmd, ReturnResult, SendData, SendVideoFrame, or SendAudioFrame, it transfers message ownership back to the NYRA runtime. Afterward, the extension must not interact with the message again.

Ownership of Data Tied to Messages

Ownership extends beyond the message structure itself to all resources associated with it (like buffers). This design ensures that messages and their data are safely handled within the NYRA framework.

Copy Semantics by Default

By default, the NYRA framework copies data when messages cross boundaries between the runtime and extensions. This prevents data races, since each resource is safely managed.

Borrowing Semantics

NYRA also supports borrowing semantics to improve performance. Extensions can β€œborrow” resources without taking full ownership. However, borrowed resources must be returned via GiveBack APIs before the message ownership is released back to the runtime. If not, the NYRA framework rejects the message send or return operation.

Command

Commands allow NYRA clients and extensions to trigger actions in other extensions. If a command’s result is not needed, it can be safely discarded by the runtime.

Result

A result is the response to a command. For instance, if extension A sends command X to extension B, after processing, extension B returns a result. The result may contain data that gives extension A information about what happened.

A typical result in JSON might look like this:

{
  "_nyra": {
    "status_code": 400
  }
}

This JSON could provide a status code or other details relevant to command processing.

Last updated