use gantry_protocol as protocol;
use nats::Connection;
use protocol::catalog::*;
use protocol::stream::*;
use protocol::PingResponse;
use protocol::{deserialize, serialize};
use std::time::Duration;
pub const CHUNK_SIZE: u64 = 256 * 1024; pub const DOWNLOAD_TIMEOUT_SECONDS: u64 = 3;
pub const MIN_WASM_SIZE: usize = 2 * 1024;
pub(crate) fn query(
client: &Connection,
query: &CatalogQuery,
timeout: Duration,
) -> Result<CatalogQueryResults, Box<dyn ::std::error::Error>> {
let buf = serialize(&query)?;
let reply = client.request_timeout("gantry.catalog.tokens.query", &buf, timeout)?;
Ok(deserialize::<CatalogQueryResults>(reply.data.as_ref())?)
}
pub(crate) fn get_detail(
client: &Connection,
key: &str,
timeout: Duration,
) -> Result<TokenDetail, Box<dyn ::std::error::Error>> {
let reply = client.request_timeout("gantry.catalog.tokens.get", key.as_bytes(), timeout)?;
Ok(deserialize::<TokenDetail>(reply.data.as_ref())?)
}
pub(crate) fn put(
client: &Connection,
token: &Token,
timeout: Duration,
) -> Result<PutTokenResponse, Box<dyn ::std::error::Error>> {
let buf = serialize(token)?;
let reply = client.request_timeout("gantry.catalog.tokens.put", &buf, timeout)?;
let res = deserialize::<PutTokenResponse>(reply.data.as_ref())?;
Ok(res)
}
pub(crate) fn ping(
client: &Connection,
timeout: Duration,
) -> Result<PingResponse, Box<dyn ::std::error::Error>> {
let res = client.request_timeout("gantry.ping", &[], timeout)?;
let pong = deserialize::<PingResponse>(res.data.as_ref())?;
Ok(pong)
}
pub(crate) fn start_upload(
client: &Connection,
req: &UploadRequest,
timeout: Duration,
) -> Result<TransferAck, Box<dyn ::std::error::Error>> {
let buf = serialize(req)?;
let res = client.request_timeout(protocol::stream::SUBJECT_STREAM_UPLOAD, &buf, timeout)?;
let tack = deserialize::<TransferAck>(res.data.as_ref())?;
Ok(tack)
}
pub(crate) fn request_download(
client: &Connection,
req: DownloadRequest,
) -> Result<Vec<u8>, Box<dyn ::std::error::Error>> {
let buf = serialize(&req)?;
let mut res = Vec::new();
for (idx, msg) in client
.request_multi(SUBJECT_STREAM_DOWNLOAD, &buf)?
.timeout_iter(Duration::from_secs(DOWNLOAD_TIMEOUT_SECONDS))
.enumerate()
{
if idx > 0 {
let chunk: FileChunk = deserialize(&msg.data)?;
res.extend_from_slice(&chunk.chunk_bytes);
if res.len() == chunk.total_bytes as usize {
break;
}
}
}
if res.len() > MIN_WASM_SIZE {
Ok(res)
} else {
Err("Did not receive an actor from Gantry".into())
}
}
pub(crate) fn upload_chunk(
c: &Connection,
sequence_no: u64,
actor: &str,
chunk_size: u64,
total_bytes: u64,
total_chunks: u64,
bytes: Vec<u8>,
timeout: Duration,
) -> Result<(), Box<dyn ::std::error::Error>> {
let chunk = protocol::stream::FileChunk {
actor: actor.to_string(),
chunk_bytes: bytes,
chunk_size,
sequence_no,
total_bytes,
total_chunks,
};
let buf = serialize(&chunk)?;
let subject = format!(
"{}{}",
protocol::stream::SUBJECT_STREAM_UPLOAD_PREFIX,
actor
);
let _res = c.request_timeout(&subject, &buf, timeout)?;
Ok(())
}