update
This commit is contained in:
@@ -9,16 +9,16 @@
|
||||
* File Server Handler Architecture:
|
||||
* The system uses handler functions to abstract file server operations, allowing support
|
||||
* for different file server implementations (e.g., Plik, AWS S3, custom HTTP server).
|
||||
*
|
||||
*
|
||||
* Handler Function Signatures:
|
||||
*
|
||||
*
|
||||
* ```javascript
|
||||
* // Upload handler - uploads data to file server and returns URL
|
||||
* // The handler is passed to smartsend as fileserverUploadHandler parameter
|
||||
* // It receives: (fileserver_url, dataname, data)
|
||||
* // Returns: { status, uploadid, fileid, url }
|
||||
* async function fileserverUploadHandler(fileserver_url, dataname, data) { ... }
|
||||
*
|
||||
* async function plik_oneshot_upload(fileserver_url, dataname, data) { ... }
|
||||
*
|
||||
* // Download handler - fetches data from file server URL with exponential backoff
|
||||
* // The handler is passed to smartreceive as fileserverDownloadHandler parameter
|
||||
* // It receives: (url, max_retries, base_delay, max_delay, correlation_id)
|
||||
@@ -213,73 +213,16 @@ function _deserialize_data(data, type, correlation_id) {
|
||||
}
|
||||
|
||||
// Helper: Upload data to file server
|
||||
// Internal wrapper that adds correlation_id logging for smartsend
|
||||
async function _upload_to_fileserver(fileserver_url, dataname, data, correlation_id) {
|
||||
/**
|
||||
* Upload data to HTTP file server (plik-like API)
|
||||
*
|
||||
* This function implements the plik one-shot upload mode:
|
||||
* 1. Creates a one-shot upload session by sending POST request with {"OneShot": true}
|
||||
* 2. Uploads the file data as multipart form data
|
||||
* 3. Returns identifiers and download URL for the uploaded file
|
||||
* Internal upload helper - wraps plik_oneshot_upload to add correlation_id logging
|
||||
* This allows smartsend to pass correlation_id for tracing without changing the handler signature
|
||||
*/
|
||||
log_trace(correlation_id, `Uploading ${dataname} to fileserver: ${fileserver_url}`);
|
||||
|
||||
// Step 1: Get upload ID and token
|
||||
const url_getUploadID = `${fileserver_url}/upload`;
|
||||
const headers = {
|
||||
"Content-Type": "application/json"
|
||||
};
|
||||
const body = JSON.stringify({ OneShot: true });
|
||||
|
||||
let response = await fetch(url_getUploadID, {
|
||||
method: "POST",
|
||||
headers: headers,
|
||||
body: body
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to get upload ID: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
const responseJson = await response.json();
|
||||
const uploadid = responseJson.id;
|
||||
const uploadtoken = responseJson.uploadToken;
|
||||
|
||||
// Step 2: Upload file data
|
||||
const url_upload = `${fileserver_url}/file/${uploadid}`;
|
||||
|
||||
// Create multipart form data
|
||||
const formData = new FormData();
|
||||
// Create a Blob from the Uint8Array
|
||||
const blob = new Blob([data], { type: "application/octet-stream" });
|
||||
formData.append("file", blob, dataname);
|
||||
|
||||
response = await fetch(url_upload, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"X-UploadToken": uploadtoken
|
||||
},
|
||||
body: formData
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to upload file: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
const fileResponseJson = await response.json();
|
||||
const fileid = fileResponseJson.id;
|
||||
|
||||
// Build the download URL
|
||||
const url = `${fileserver_url}/file/${uploadid}/${fileid}/${encodeURIComponent(dataname)}`;
|
||||
|
||||
log_trace(correlation_id, `Uploaded to URL: ${url}`);
|
||||
|
||||
return {
|
||||
status: response.status,
|
||||
uploadid: uploadid,
|
||||
fileid: fileid,
|
||||
url: url
|
||||
};
|
||||
const result = await plik_oneshot_upload(fileserver_url, dataname, data);
|
||||
log_trace(correlation_id, `Uploaded to URL: ${result.url}`);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Helper: Fetch data from URL with exponential backoff
|
||||
@@ -481,11 +424,14 @@ async function smartsend(subject, data, options = {}) {
|
||||
* @param {string} options.receiver_name - Name of the receiver (default: "")
|
||||
* @param {string} options.receiver_id - UUID of the receiver (default: "")
|
||||
* @param {string} options.reply_to - Topic to reply to (default: "")
|
||||
* @param {string} options.reply_to_msg_id - Message ID this message is replying to (default: "")
|
||||
* @param {boolean} options.is_publish - Whether to automatically publish the message to NATS (default: true)
|
||||
*
|
||||
* @returns {Promise<Object>} - A tuple-like object with { env: MessageEnvelope, env_json_str: string }
|
||||
*/
|
||||
* @param {string} options.reply_to_msg_id - Message ID this message is replying to (default: "")
|
||||
* @param {boolean} options.is_publish - Whether to automatically publish the message to NATS (default: true)
|
||||
* - When true: Message is published to NATS automatically
|
||||
* - When false: Returns (env, env_json_str) without publishing, allowing manual publishing
|
||||
* @returns {Promise<Object>} - A tuple-like object with { env: MessageEnvelope, env_json_str: string }
|
||||
* - env: MessageEnvelope object with all metadata and payloads
|
||||
* - env_json_str: JSON string representation of the envelope for manual publishing
|
||||
*/
|
||||
const {
|
||||
broker_url = DEFAULT_NATS_URL,
|
||||
fileserver_url = DEFAULT_FILESERVER_URL,
|
||||
@@ -541,8 +487,8 @@ async function smartsend(subject, data, options = {}) {
|
||||
// Link path - Upload to HTTP server, send URL via NATS
|
||||
log_trace(correlation_id, `Using link transport, uploading to fileserver`);
|
||||
|
||||
// Upload to HTTP server
|
||||
const response = await fileserver_upload_handler(fileserver_url, dataname, payloadBytes, correlation_id);
|
||||
// Upload to HTTP server using plik_oneshot_upload handler
|
||||
const response = await fileserver_upload_handler(fileserver_url, dataname, payloadBytes);
|
||||
|
||||
if (response.status !== 200) {
|
||||
throw new Error(`Failed to upload data to fileserver: ${response.status}`);
|
||||
@@ -705,13 +651,18 @@ async function smartreceive(msg, options = {}) {
|
||||
}
|
||||
|
||||
// plik_oneshot_upload - matches Julia plik_oneshot_upload function
|
||||
// Upload handler signature: plik_oneshot_upload(fileserver_url, dataname, data)
|
||||
// Returns: { status, uploadid, fileid, url }
|
||||
async function plik_oneshot_upload(file_server_url, dataname, data) {
|
||||
/**
|
||||
* Upload a single file to a plik server using one-shot mode
|
||||
* This function uploads raw byte array to a plik server in one-shot mode (no upload session).
|
||||
* It first creates a one-shot upload session by sending a POST request with {"OneShot": true},
|
||||
* retrieves an upload ID and token, then uploads the file data as multipart form data using the token.
|
||||
*
|
||||
*
|
||||
* This is the default upload handler used by smartsend.
|
||||
* Custom handlers can be passed via the fileserver_upload_handler option.
|
||||
*
|
||||
* @param {string} file_server_url - Base URL of the plik server (e.g., "http://localhost:8080")
|
||||
* @param {string} dataname - Name of the file being uploaded
|
||||
* @param {Uint8Array} data - Raw byte data of the file content
|
||||
|
||||
Reference in New Issue
Block a user