The consumer **must** send [`Drop`](#drop) in reply unless the stream ended because the consumer chose to drop the stream.
Example:
```json
{
"End": 0
}
```
### `Ack`
This message is sent from consumer to producer. The body is a single value, the `id`.
Sent by the consumer in reply to each [`Data`](#data) message, indicating that the consumer has finished processing that message. `Ack` is used for flow control. If a consumer does not need to process a stream immediately, or is having trouble keeping up, it **should not** send `Ack` messages until it is ready to process more `Data`.
Example:
```json
{
"Ack": 0
}
```
### `Drop`
This message is sent from consumer to producer. The body is a single value, the `id`.
Sent by the consumer to indicate disinterest in further messages from a stream. The producer **may** send additional [`Data`](#data) messages after `Drop` has been received, but **should** make an effort to stop sending messages and [`End`](#end) the stream as soon as possible.
The consumer **should not** consider `Data` messages sent after `Drop` to be an error, unless `End` has already been received.
The producer **must** send `End` in reply unless the stream ended because the producer ended the stream.
Example:
```json
{
"Drop": 0
}
```
## Signal Handling in Plugins
Plugins can respond to signals sent from the engine, such as interrupts (Ctrl+C) or resets, by registering handlers. The plugin’s signal handling methods allow for customizable responses to user or system actions, enhancing the plugin's integration with the Nu engine.
### `register_signal_handler`
The `register_signal_handler` method allows a plugin to register a handler that will be called when a signal is received. This method accepts a closure with the following signature:
```rust
|action: SignalAction| { ... }
```
The closure will be invoked with the `SignalAction` variant received from the engine. This method returns an RAII guard that ensures the handler remains active until it is dropped.
#### Example Usage
Below is an example of registering a handler that responds to both `Interrupt` and `Reset` signals:
```rust
let _guard = engine.register_signal_handler(Box::new(move |action| {
match action {
SignalAction::Interrupt => println!("Interrupt signal received"),
SignalAction::Reset => println!("Reset signal received"),
}
}));
```
#### `signals()`
The `signals()` method allows the plugin to check the status of the signal, specifically for `Interrupt`. This method returns a `Signals` struct, which includes the method `interrupted()` that indicates if an interrupt has occurred.
```rust
if engine.signals().interrupted() {
println!("Operation was interrupted.");
}
```
Use `signals().interrupted()` to check for interrupt status, particularly when managing long-running operations.
## Encoding
### JSON
The JSON encoding defines messages as JSON objects. No separator or padding is required. Whitespace within the message object as well as between messages is permitted, including newlines.
The engine is more strict about the format it emits: every message ends with a newline, and unnecessary whitespace and newlines will not be emitted within a message. It is explicitly supported for a plugin to choose to parse the input from the engine by parsing each line received as a separate message, as this is most commonly supported across all languages.
Byte arrays are encoded as plain JSON arrays of numbers representing each byte. While this is inefficient, it is maximally portable.
MessagePack **should** be preferred where possible if performance is desired, especially if byte streams are expected to be a common input or output of the plugin.
### MessagePack
[MessagePack](https://msgpack.org) is a machine-first binary encoding format with a data model very similar to JSON. Messages are encoded as maps. There is no separator between messages, and no padding character is accepted.
Most messages are encoded in the same way as their JSON analogue. For example, the following [`Hello`](#hello) message in JSON: