Skip to content

Commit

Permalink
handle external service host
Browse files Browse the repository at this point in the history
  • Loading branch information
dragazo committed Feb 8, 2024
1 parent 8bc9b2c commit 7f8a21a
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 23 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "netsblox-vm"
version = "0.4.2"
version = "0.4.3"
edition = "2021"
license = "MIT OR Apache-2.0"
authors = ["Devin Jean <emailcruzjean@yahoo.com>"]
Expand Down Expand Up @@ -72,7 +72,7 @@ rustls-tls-webpki-roots = [
# core deps
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
gc-arena = { version = "=0.4.0", default-features = false }
netsblox-ast = { version = "=0.5.4", default-features = false }
netsblox-ast = { version = "=0.5.5", default-features = false }
# netsblox-ast = { path = "../netsblox-ast", default-features = false }
num-traits = { version = "0.2.17", default-features = false }
num-derive = { version = "0.4.1", default-features = false }
Expand Down
6 changes: 4 additions & 2 deletions src/bytecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1677,8 +1677,9 @@ impl<'a: 'b, 'b> ByteCodeBuilder<'a, 'b> {
}
self.ins.push(Instruction::CallClosure { new_entity: new_entity.is_some(), args: args.len() }.into());
}
ast::ExprKind::CallRpc { service, rpc, args } => {
ast::ExprKind::CallRpc { host, service, rpc, args } => {
let mut tokens = LosslessJoin::new();
tokens.push(host.as_deref().unwrap_or(""));
tokens.push(service);
tokens.push(rpc);
for (arg_name, arg) in args {
Expand Down Expand Up @@ -2181,8 +2182,9 @@ impl<'a: 'b, 'b> ByteCodeBuilder<'a, 'b> {
Some(target) => self.append_simple_ins(entity, &[msg_type, target], Instruction::SendLocalMessage { wait: *wait, target: true })?,
None => self.append_simple_ins(entity, &[msg_type], Instruction::SendLocalMessage { wait: *wait, target: false })?,
}
ast::StmtKind::CallRpc { service, rpc, args } => {
ast::StmtKind::CallRpc { host, service, rpc, args } => {
let mut tokens = LosslessJoin::new();
tokens.push(host.as_deref().unwrap_or(""));
tokens.push(service);
tokens.push(rpc);
for (arg_name, arg) in args {
Expand Down
6 changes: 5 additions & 1 deletion src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1023,6 +1023,10 @@ impl<'gc, C: CustomTypes<S>, S: System<C>> Process<'gc, C, S> {
}
Instruction::CallRpc { tokens } => {
let mut tokens = lossless_split(tokens);
let host = match tokens.next().unwrap() {
"" => None,
x => Some(CompactString::new(x)),
};
let service = CompactString::new(tokens.next().unwrap());
let rpc = CompactString::new(tokens.next().unwrap());

Expand All @@ -1032,7 +1036,7 @@ impl<'gc, C: CustomTypes<S>, S: System<C>> Process<'gc, C, S> {

drop(global_context_raw);
self.defer = Some(Defer::Request {
key: system.perform_request(mc, Request::Rpc { service, rpc, args }, self)?,
key: system.perform_request(mc, Request::Rpc { host, service, rpc, args }, self)?,
action: RequestAction::Rpc,
aft_pos
});
Expand Down
2 changes: 1 addition & 1 deletion src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1612,7 +1612,7 @@ pub enum Request<'gc, C: CustomTypes<S>, S: System<C>> {
/// Performs a system call on the local hardware to access device resources.
Syscall { name: CompactString, args: Vec<Value<'gc, C, S>> },
/// Requests the system to execute the given RPC.
Rpc { service: CompactString, rpc: CompactString, args: VecMap<CompactString, Value<'gc, C, S>, false> },
Rpc { host: Option<CompactString>, service: CompactString, rpc: CompactString, args: VecMap<CompactString, Value<'gc, C, S>, false> },
/// Request to get the current value of an entity property.
Property { prop: Property },
/// Request to run a block which was not known by the ast parser or bytecode compiler.
Expand Down
26 changes: 13 additions & 13 deletions src/std_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ use crate::*;

const MESSAGE_REPLY_TIMEOUT: Duration = Duration::from_millis(1500);

async fn call_rpc_async<C: CustomTypes<S>, S: System<C>>(context: &NetsBloxContext, client: &reqwest::Client, service: &str, rpc: &str, args: &[(&str, &Json)]) -> Result<SimpleValue, CompactString> {
async fn call_rpc_async<C: CustomTypes<S>, S: System<C>>(context: &NetsBloxContext, client: &reqwest::Client, host: Option<&str>, service: &str, rpc: &str, args: &[(&str, &Json)]) -> Result<SimpleValue, CompactString> {
let time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis();
let url = format!("{services_url}/{service}/{rpc}?clientId={client_id}&t={time}",
services_url = context.services_url, client_id = context.client_id);
let url = format!("{service_host}/{service}/{rpc}?clientId={client_id}&t={time}",
service_host = host.unwrap_or(context.default_service_host.as_str()), client_id = context.client_id);
let args = args.iter().copied().collect::<BTreeMap<_,_>>();

let res = match client.post(url).json(&args).send().await {
Expand Down Expand Up @@ -96,15 +96,15 @@ impl<C: CustomTypes<StdSystem<C>>> StdSystem<C> {
/// Initializes a new instance of [`StdSystem`] targeting the given NetsBlox server base url, e.g., `https://cloud.netsblox.org`.
pub async fn new_async(base_url: CompactString, project_name: Option<&str>, config: Config<C, Self>, clock: Arc<Clock>) -> Self {
let client = reqwest::Client::builder().build().unwrap();
let services_url = {
let default_service_host = {
let configuration = client.get(format!("{base_url}/configuration")).send().await.unwrap().json::<BTreeMap<CompactString, Json>>().await.unwrap();
let services_hosts = configuration["servicesHosts"].as_array().unwrap();
services_hosts[0].as_object().unwrap().get("url").unwrap().as_str().unwrap().into()
};

let mut context = NetsBloxContext {
base_url,
services_url,
default_service_host,
client_id: format_compact!("_vm-{}", names::Generator::default().next().unwrap()),
project_name: project_name.unwrap_or("untitled").into(),

Expand Down Expand Up @@ -256,11 +256,11 @@ impl<C: CustomTypes<StdSystem<C>>> StdSystem<C> {

#[tokio::main(flavor = "multi_thread", worker_threads = 1)]
async fn handler<C: CustomTypes<StdSystem<C>>>(client: reqwest::Client, context: Arc<NetsBloxContext>, receiver: Receiver<RpcRequest<C, StdSystem<C>>>) {
while let Ok(request) = receiver.recv() {
while let Ok(RpcRequest { key, host, service, rpc, args }) = receiver.recv() {
let (client, context) = (client.clone(), context.clone());
tokio::spawn(async move {
let res = call_rpc_async::<C, StdSystem<C>>(&context, &client, &request.service, &request.rpc, &request.args.iter().map(|x| (x.0.as_str(), x.1)).collect::<Vec<_>>()).await;
request.key.complete(res.map(Into::into));
let res = call_rpc_async::<C, StdSystem<C>>(&context, &client, host.as_deref(), &service, &rpc, &args.iter().map(|x| (x.0.as_str(), x.1)).collect::<Vec<_>>()).await;
key.complete(res.map(Into::into));
});
}
}
Expand All @@ -276,14 +276,14 @@ impl<C: CustomTypes<StdSystem<C>>> StdSystem<C> {
let config = config.fallback(&Config {
request: Some(Rc::new(move |_, key, request, proc| {
match request {
Request::Rpc { service, rpc, args } => match (service.as_str(), rpc.as_str(), args.as_slice()) {
("PublicRoles", "getPublicRoleId", []) => {
Request::Rpc { host, service, rpc, args } => match (host.as_deref(), service.as_str(), rpc.as_str(), args.as_slice()) {
(_, "PublicRoles", "getPublicRoleId", []) => {
key.complete(Ok(SimpleValue::String(format_compact!("{}@{}#vm", context_clone.project_name, context_clone.client_id)).into()));
RequestStatus::Handled
}
_ => {
match args.into_iter().map(|(k, v)| Ok((k, v.to_simple()?.into_netsblox_json()))).collect::<Result<_,ToSimpleError<_,_>>>() {
Ok(args) => proc.global_context.borrow().system.rpc_request_pipe.send(RpcRequest { service, rpc, args, key }).unwrap(),
Ok(args) => proc.global_context.borrow().system.rpc_request_pipe.send(RpcRequest { host, service, rpc, args, key }).unwrap(),
Err(err) => key.complete(Err(format_compact!("failed to convert RPC args to json: {err:?}"))),
}
RequestStatus::Handled
Expand All @@ -305,8 +305,8 @@ impl<C: CustomTypes<StdSystem<C>>> StdSystem<C> {

/// Asynchronously calls an RPC and returns the result.
/// This function directly makes requests to NetsBlox, bypassing any RPC hook defined by [`Config`].
pub async fn call_rpc_async(&self, service: &str, rpc: &str, args: &[(&str, &Json)]) -> Result<SimpleValue, CompactString> {
call_rpc_async::<C, Self>(&self.context, &self.client, service, rpc, args).await
pub async fn call_rpc_async(&self, host: Option<&str>, service: &str, rpc: &str, args: &[(&str, &Json)]) -> Result<SimpleValue, CompactString> {
call_rpc_async::<C, Self>(&self.context, &self.client, host, service, rpc, args).await
}

/// Gets the public id of the running system that can be used to send messages to this client.
Expand Down
3 changes: 2 additions & 1 deletion src/std_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ use crate::*;
pub struct NetsBloxContext {
pub base_url: CompactString,
pub client_id: CompactString,
pub services_url: CompactString,
pub default_service_host: CompactString,

pub project_name: CompactString,
pub project_id: CompactString,
pub role_name: CompactString,
pub role_id: CompactString,
}
pub struct RpcRequest<C: CustomTypes<S>, S: System<C>> {
pub host: Option<CompactString>,
pub service: CompactString,
pub rpc: CompactString,
pub args: VecMap<CompactString, Json, false>,
Expand Down
6 changes: 3 additions & 3 deletions src/test/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1156,18 +1156,18 @@ fn test_proj_sizes() {
check_bytecode_size!("projects/broadcast-to.xml", 379);
check_bytecode_size!("projects/broadcast.xml", 239);
check_bytecode_size!("projects/cloning.xml", 86);
check_bytecode_size!("projects/costumes.xml", 278);
check_bytecode_size!("projects/costumes.xml", 280);
check_bytecode_size!("projects/counting.xml", 97);
check_bytecode_size!("projects/custom-events.xml", 180);
check_bytecode_size!("projects/delayed-capture-upvar.xml", 808);
check_bytecode_size!("projects/delete-clone.xml", 438);
check_bytecode_size!("projects/effects.xml", 236);
check_bytecode_size!("projects/launch.xml", 150);
check_bytecode_size!("projects/loop-yields.xml", 218);
check_bytecode_size!("projects/messaging.xml", 386);
check_bytecode_size!("projects/messaging.xml", 387);
check_bytecode_size!("projects/motion.xml", 230);
check_bytecode_size!("projects/nested-lists-consts.xml", 0);
check_bytecode_size!("projects/parallel-rpcs.xml", 419);
check_bytecode_size!("projects/parallel-rpcs.xml", 420);
check_bytecode_size!("projects/pause.xml", 16);
check_bytecode_size!("projects/pen-basic.xml", 336);
check_bytecode_size!("projects/run-call-ask-tell.xml", 334);
Expand Down

0 comments on commit 7f8a21a

Please sign in to comment.