update
This commit is contained in:
@@ -369,6 +369,25 @@ graph TD
|
|||||||
|
|
||||||
## Implementation Details
|
## Implementation Details
|
||||||
|
|
||||||
|
### API Consistency Across Languages
|
||||||
|
|
||||||
|
**High-Level API (Consistent Across All Languages):**
|
||||||
|
- `smartsend(subject, data, ...)` - Main publishing function
|
||||||
|
- `smartreceive(msg, ...)` - Main receiving function
|
||||||
|
- Message envelope structure (`msg_envelope_v1` / `MessageEnvelope`)
|
||||||
|
- Payload structure (`msg_payload_v1` / `MessagePayload`)
|
||||||
|
- Transport strategy (direct vs link based on size threshold)
|
||||||
|
- Supported payload types: text, dictionary, table, image, audio, video, binary
|
||||||
|
|
||||||
|
**Low-Level Native Functions (Language-Specific Conventions):**
|
||||||
|
- Julia: `NATS.connect()`, `publish_message()`, function overloading
|
||||||
|
- JavaScript: `nats.js` client, native async/await patterns
|
||||||
|
- Python: `nats-python` client, native async/await patterns
|
||||||
|
|
||||||
|
**Connection Reuse Pattern:**
|
||||||
|
- **Julia:** Uses `NATS_connection` keyword parameter with function overloading
|
||||||
|
- **JavaScript/Python:** Achieved by creating NATS client outside the function and reusing it in custom handlers
|
||||||
|
|
||||||
### Julia Implementation
|
### Julia Implementation
|
||||||
|
|
||||||
#### Dependencies
|
#### Dependencies
|
||||||
@@ -400,7 +419,7 @@ function smartsend(
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
**New Keyword Parameter:**
|
**Keyword Parameter - NATS_connection:**
|
||||||
- `NATS_connection::Union{NATS.Connection, Nothing} = nothing` - Pre-existing NATS connection. When provided, `smartsend` uses this connection instead of creating a new one, avoiding the overhead of connection establishment. This is useful for high-frequency publishing scenarios where connection reuse provides performance benefits.
|
- `NATS_connection::Union{NATS.Connection, Nothing} = nothing` - Pre-existing NATS connection. When provided, `smartsend` uses this connection instead of creating a new one, avoiding the overhead of connection establishment. This is useful for high-frequency publishing scenarios where connection reuse provides performance benefits.
|
||||||
|
|
||||||
**Connection Handling Logic:**
|
**Connection Handling Logic:**
|
||||||
@@ -498,7 +517,7 @@ function publish_message(conn::NATS.Connection, subject::String, message::String
|
|||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
**Use Case:** Use the connection-based overload when you already have an established NATS connection and want to publish multiple messages without the overhead of creating a new connection for each publish.
|
**Use Case:** Use the connection-based overload when you already have an established NATS connection and want to publish multiple messages without the overhead of creating a new connection for each publish. This is a Julia-specific optimization that leverages function overloading.
|
||||||
|
|
||||||
**Integration with smartsend:**
|
**Integration with smartsend:**
|
||||||
```julia
|
```julia
|
||||||
@@ -521,6 +540,10 @@ env, env_json_str = smartsend(
|
|||||||
# Uses: publish_message(broker_url, subject, env_json_str, cid)
|
# Uses: publish_message(broker_url, subject, env_json_str, cid)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**API Consistency Note:**
|
||||||
|
- **High-level API (smartsend, smartreceive):** Uses consistent naming across all three languages (Julia, JavaScript, Python/Micropython)
|
||||||
|
- **Low-level native functions (NATS.connect(), publish_message()):** Follow the conventions of the specific language ecosystem and do not require cross-language consistency
|
||||||
|
|
||||||
### JavaScript Implementation
|
### JavaScript Implementation
|
||||||
|
|
||||||
#### Dependencies
|
#### Dependencies
|
||||||
@@ -551,8 +574,11 @@ async function smartsend(
|
|||||||
- `receiver_id` (String) - Message receiver ID (default: `""`)
|
- `receiver_id` (String) - Message receiver ID (default: `""`)
|
||||||
- `reply_to` (String) - Topic to reply to (default: `""`)
|
- `reply_to` (String) - Topic to reply to (default: `""`)
|
||||||
- `reply_to_msg_id` (String) - Message ID this message is replying to (default: `""`)
|
- `reply_to_msg_id` (String) - Message ID this message is replying to (default: `""`)
|
||||||
|
- `is_publish` (Boolean) - Whether to automatically publish the message to NATS (default: `true`)
|
||||||
- `fileserver_upload_handler` (Function) - Custom upload handler function
|
- `fileserver_upload_handler` (Function) - Custom upload handler function
|
||||||
|
|
||||||
|
**Note:** JavaScript uses `is_publish` option (instead of `NATS_connection` keyword) to control automatic publishing behavior. Connection reuse can be achieved by creating a NATS client outside the function and reusing it in a custom `fileserver_upload_handler` or custom publish implementation.
|
||||||
|
|
||||||
**Return Value:**
|
**Return Value:**
|
||||||
- Returns a Promise that resolves to an object containing:
|
- Returns a Promise that resolves to an object containing:
|
||||||
- `env` - The envelope object containing all metadata and payloads
|
- `env` - The envelope object containing all metadata and payloads
|
||||||
@@ -618,26 +644,40 @@ async function smartreceive(msg, options = {})
|
|||||||
#### smartsend Function
|
#### smartsend Function
|
||||||
|
|
||||||
```python
|
```python
|
||||||
async def smartsend(
|
def smartsend(
|
||||||
subject: str,
|
subject: str,
|
||||||
data: List[Tuple[str, Any, str]], # List of (dataname, data, type) tuples
|
data: List[Tuple[str, Any, str]], # List of (dataname, data, type) tuples
|
||||||
options: Dict = {}
|
broker_url: str = DEFAULT_BROKER_URL,
|
||||||
)
|
fileserver_url: str = DEFAULT_FILESERVER_URL,
|
||||||
|
fileserver_upload_handler: Callable = plik_oneshot_upload,
|
||||||
|
size_threshold: int = DEFAULT_SIZE_THRESHOLD,
|
||||||
|
correlation_id: Union[str, None] = None,
|
||||||
|
msg_purpose: str = "chat",
|
||||||
|
sender_name: str = "NATSBridge",
|
||||||
|
receiver_name: str = "",
|
||||||
|
receiver_id: str = "",
|
||||||
|
reply_to: str = "",
|
||||||
|
reply_to_msg_id: str = "",
|
||||||
|
is_publish: bool = True
|
||||||
|
) -> Tuple[MessageEnvelope, str]
|
||||||
```
|
```
|
||||||
|
|
||||||
**Options:**
|
**Options:**
|
||||||
- `broker_url` (str) - NATS server URL (default: `"nats://localhost:4222"`)
|
- `broker_url` (str) - NATS server URL (default: `"nats://localhost:4222"`)
|
||||||
- `fileserver_url` (str) - Base URL of the file server (default: `"http://localhost:8080"`)
|
- `fileserver_url` (str) - Base URL of the file server (default: `"http://localhost:8080"`)
|
||||||
- `size_threshold` (int) - Threshold in bytes for transport selection (default: `1048576` = 1MB)
|
- `size_threshold` (int) - Threshold in bytes for transport selection (default: `1048576` = 1MB)
|
||||||
- `correlation_id` (str) - Optional correlation ID for tracing
|
- `correlation_id` (str) - Optional correlation ID for tracing (auto-generated if None)
|
||||||
- `msg_purpose` (str) - Purpose of the message (default: `"chat"`)
|
- `msg_purpose` (str) - Purpose of the message (default: `"chat"`)
|
||||||
- `sender_name` (str) - Sender name (default: `"NATSBridge"`)
|
- `sender_name` (str) - Sender name (default: `"NATSBridge"`)
|
||||||
- `receiver_name` (str) - Message receiver name (default: `""`)
|
- `receiver_name` (str) - Message receiver name (default: `""`)
|
||||||
- `receiver_id` (str) - Message receiver ID (default: `""`)
|
- `receiver_id` (str) - Message receiver ID (default: `""`)
|
||||||
- `reply_to` (str) - Topic to reply to (default: `""`)
|
- `reply_to` (str) - Topic to reply to (default: `""`)
|
||||||
- `reply_to_msg_id` (str) - Message ID this message is replying to (default: `""`)
|
- `reply_to_msg_id` (str) - Message ID this message is replying to (default: `""`)
|
||||||
|
- `is_publish` (bool) - Whether to automatically publish the message to NATS (default: `True`)
|
||||||
- `fileserver_upload_handler` (Callable) - Custom upload handler function
|
- `fileserver_upload_handler` (Callable) - Custom upload handler function
|
||||||
|
|
||||||
|
**Note:** Python uses `is_publish` parameter (instead of `NATS_connection` keyword) to control automatic publishing behavior. Connection reuse can be achieved by creating a NATS client outside the function and reusing it in a custom `fileserver_upload_handler` or custom publish implementation.
|
||||||
|
|
||||||
**Return Value:**
|
**Return Value:**
|
||||||
- Returns a tuple `(env, env_json_str)` where:
|
- Returns a tuple `(env, env_json_str)` where:
|
||||||
- `env` - The envelope dictionary containing all metadata and payloads
|
- `env` - The envelope dictionary containing all metadata and payloads
|
||||||
|
|||||||
@@ -316,6 +316,30 @@ julia test/scenario3_julia_to_julia.jl
|
|||||||
node test/scenario3_julia_to_julia.js
|
node test/scenario3_julia_to_julia.js
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## API Consistency Across Languages
|
||||||
|
|
||||||
|
**High-Level API (Consistent Across All Languages):**
|
||||||
|
- `smartsend(subject, data, ...)` - Main publishing function
|
||||||
|
- `smartreceive(msg, ...)` - Main receiving function
|
||||||
|
- Message envelope structure (`msg_envelope_v1` / `MessageEnvelope`)
|
||||||
|
- Payload structure (`msg_payload_v1` / `MessagePayload`)
|
||||||
|
- Transport strategy (direct vs link based on size threshold)
|
||||||
|
- Supported payload types: text, dictionary, table, image, audio, video, binary
|
||||||
|
|
||||||
|
**Low-Level Native Functions (Language-Specific Conventions):**
|
||||||
|
- Julia: `NATS.connect()`, `publish_message()`, function overloading
|
||||||
|
- JavaScript: `nats.js` client, native async/await patterns
|
||||||
|
- Python: `nats-python` client, native async/await patterns
|
||||||
|
|
||||||
|
**Connection Reuse Pattern - Key Differences:**
|
||||||
|
- **Julia:** Uses `NATS_connection` keyword parameter with function overloading for automatic connection management
|
||||||
|
- **JavaScript/Python:** Achieved by creating NATS client outside the function and reusing it in custom handlers or custom publish implementations
|
||||||
|
|
||||||
|
**Why the Difference?**
|
||||||
|
- Julia supports function overloading and keyword arguments, allowing `NATS_connection` to be passed as an optional parameter
|
||||||
|
- JavaScript/Python use a simpler `is_publish` option to control automatic publishing
|
||||||
|
- For connection reuse in JavaScript/Python, create a NATS client once and reuse it in your custom `fileserver_upload_handler` or custom publish logic
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
### Scenario 1: Command & Control (Small Dictionary)
|
### Scenario 1: Command & Control (Small Dictionary)
|
||||||
@@ -373,9 +397,39 @@ const config = {
|
|||||||
threshold: 0.5
|
threshold: 0.5
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Use is_publish option to control automatic publishing
|
||||||
await smartsend("control", [
|
await smartsend("control", [
|
||||||
{ dataname: "config", data: config, type: "dictionary" }
|
{ dataname: "config", data: config, type: "dictionary" }
|
||||||
]);
|
], {
|
||||||
|
is_publish: true // Automatically publish to NATS
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Connection Reuse in JavaScript:**
|
||||||
|
To achieve connection reuse in JavaScript, create a NATS client outside the function and use it in a custom `fileserver_upload_handler` or custom publish implementation:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const { connect } = require('nats');
|
||||||
|
const { smartsend } = require('./src/NATSBridge');
|
||||||
|
|
||||||
|
// Create connection once
|
||||||
|
const nc = await connect({ servers: ['nats://localhost:4222'] });
|
||||||
|
|
||||||
|
// Send multiple messages using the same connection
|
||||||
|
for (let i = 0; i < 100; i++) {
|
||||||
|
const config = { iteration: i, data: Math.random() };
|
||||||
|
|
||||||
|
// Option 1: Use is_publish=false and publish manually with your connection
|
||||||
|
const { env, env_json_str } = await smartsend("control", [
|
||||||
|
{ dataname: "config", data: config, type: "dictionary" }
|
||||||
|
], { is_publish: false });
|
||||||
|
|
||||||
|
// Publish with your existing connection
|
||||||
|
await nc.publish("control", env_json_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close connection when done
|
||||||
|
await nc.close();
|
||||||
```
|
```
|
||||||
|
|
||||||
**Python/Micropython (Sender/Receiver):**
|
**Python/Micropython (Sender/Receiver):**
|
||||||
@@ -390,7 +444,32 @@ config = {
|
|||||||
"threshold": 0.5
|
"threshold": 0.5
|
||||||
}
|
}
|
||||||
|
|
||||||
smartsend("control", [("config", config, "dictionary")])
|
# Use is_publish parameter to control automatic publishing
|
||||||
|
smartsend("control", [("config", config, "dictionary")], is_publish=True)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Connection Reuse in Python:**
|
||||||
|
To achieve connection reuse in Python, create a NATS client outside the function and use it in a custom `fileserver_upload_handler` or custom publish implementation:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from nats_bridge import smartsend
|
||||||
|
import nats
|
||||||
|
|
||||||
|
# Create connection once
|
||||||
|
nc = await nats.connect("nats://localhost:4222")
|
||||||
|
|
||||||
|
# Send multiple messages using the same connection
|
||||||
|
for i in range(100):
|
||||||
|
config = {"iteration": i, "data": random.random()}
|
||||||
|
|
||||||
|
# Option 1: Use is_publish=False and publish manually with your connection
|
||||||
|
env, env_json_str = smartsend("control", [("config", config, "dictionary")], is_publish=False)
|
||||||
|
|
||||||
|
# Publish with your existing connection
|
||||||
|
await nc.publish("control", env_json_str)
|
||||||
|
|
||||||
|
# Close connection when done
|
||||||
|
await nc.close()
|
||||||
```
|
```
|
||||||
|
|
||||||
### Basic Multi-Payload Example
|
### Basic Multi-Payload Example
|
||||||
@@ -607,6 +686,10 @@ env, env_json_str = smartsend(
|
|||||||
# Uses: publish_message(broker_url, subject, env_json_str, cid)
|
# Uses: publish_message(broker_url, subject, env_json_str, cid)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**API Consistency Note:**
|
||||||
|
- **Julia:** Uses `NATS_connection` keyword parameter with function overloading for automatic connection management
|
||||||
|
- **JavaScript/Python:** Use `is_publish` option and achieve connection reuse by creating NATS client outside the function and reusing it in custom handlers or custom publish implementations
|
||||||
|
|
||||||
#### JavaScript (Receiver)
|
#### JavaScript (Receiver)
|
||||||
```javascript
|
```javascript
|
||||||
const { smartreceive } = require('./src/NATSBridge');
|
const { smartreceive } = require('./src/NATSBridge');
|
||||||
|
|||||||
Reference in New Issue
Block a user