Skip to content

Commit

Permalink
Add resources op (#1119)
Browse files Browse the repository at this point in the history
  • Loading branch information
bartlomieju authored and ry committed Oct 30, 2018
1 parent 8b39d2c commit 946acbc
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 0 deletions.
1 change: 1 addition & 0 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ ts_sources = [
"js/read_link.ts",
"js/remove.ts",
"js/rename.ts",
"js/resources.ts",
"js/stat.ts",
"js/symlink.ts",
"js/text_encoding.ts",
Expand Down
1 change: 1 addition & 0 deletions js/deno.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export { truncateSync, truncate } from "./truncate";
export { FileInfo } from "./file_info";
export { connect, dial, listen, Listener, Conn } from "./net";
export { metrics } from "./metrics";
export { resources } from "./resources";
export const args: string[] = [];

// Provide the compiler API in an obfuscated way
Expand Down
25 changes: 25 additions & 0 deletions js/resources.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
import * as msg from "gen/msg_generated";
import * as flatbuffers from "./flatbuffers";
import { assert } from "./util";
import * as dispatch from "./dispatch";

export function resources(): { [key: number]: string } {
const builder = flatbuffers.createBuilder();
msg.Resources.startResources(builder);
const inner = msg.Resource.endResource(builder);
const baseRes = dispatch.sendSync(builder, msg.Any.Resources, inner);
assert(baseRes !== null);
assert(msg.Any.ResourcesRes === baseRes!.innerType());
const res = new msg.ResourcesRes();
assert(baseRes!.inner(res) !== null);

const resources: { [key: number]: string } = {};

for (let i = 0; i < res.resourcesLength(); i++) {
const item = res.resources(i)!;
resources[item.rid()!] = item.repr()!;
}

return resources;
}
43 changes: 43 additions & 0 deletions js/resources_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
import { test, testPerm, assert, assertEqual } from "./test_util.ts";
import * as deno from "deno";

test(function resourcesStdio() {
const res = deno.resources();

assertEqual(res[0], "stdin");
assertEqual(res[1], "stdout");
assertEqual(res[2], "stderr");
});

testPerm({ net: true }, async function resourcesNet() {
const addr = "127.0.0.1:4501";
const listener = deno.listen("tcp", addr);

const dialerConn = await deno.dial("tcp", addr);
const listenerConn = await listener.accept();

const res = deno.resources();
assertEqual(Object.values(res).filter(r => r === "tcpListener").length, 1);
assertEqual(Object.values(res).filter(r => r === "tcpStream").length, 2);

listenerConn.close();
dialerConn.close();
listener.close();
});

test(async function resourcesFile() {
const resourcesBefore = deno.resources();
await deno.open("tests/hello.txt");
const resourcesAfter = deno.resources();

// check that exactly one new resource (file) was added
assertEqual(
Object.keys(resourcesAfter).length,
Object.keys(resourcesBefore).length + 1
);
const newRid = Object.keys(resourcesAfter).find(rid => {
return !resourcesBefore.hasOwnProperty(rid);
});
assertEqual(resourcesAfter[newRid], "fsFile");
});
1 change: 1 addition & 0 deletions js/unit_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import "./read_dir_test.ts";
import "./read_file_test.ts";
import "./read_link_test.ts";
import "./rename_test.ts";
import "./resources_test.ts";
import "./stat_test.ts";
import "./symlink_test.ts";
import "./text_encoding_test.ts";
Expand Down
13 changes: 13 additions & 0 deletions src/msg.fbs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ union Any {
Rename,
Readlink,
ReadlinkRes,
Resources,
ResourcesRes,
Symlink,
Stat,
StatRes,
Expand Down Expand Up @@ -270,6 +272,17 @@ table ReadlinkRes {
path: string;
}

table Resources {}

table Resource {
rid: int;
repr: string;
}

table ResourcesRes {
resources: [Resource];
}

table Symlink {
oldname: string;
newname: string;
Expand Down
48 changes: 48 additions & 0 deletions src/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use futures::Poll;
use hyper;
use hyper::rt::{Future, Stream};
use remove_dir_all::remove_dir_all;
use resources::table_entries;
use std;
use std::fs;
use std::net::{Shutdown, SocketAddr};
Expand Down Expand Up @@ -94,6 +95,7 @@ pub fn dispatch(
msg::Any::Read => op_read,
msg::Any::Remove => op_remove,
msg::Any::Rename => op_rename,
msg::Any::Resources => op_resources,
msg::Any::SetEnv => op_set_env,
msg::Any::Shutdown => op_shutdown,
msg::Any::Start => op_start,
Expand Down Expand Up @@ -1288,3 +1290,49 @@ fn op_metrics(
},
))
}

fn op_resources(
_state: Arc<IsolateState>,
base: &msg::Base,
data: &'static mut [u8],
) -> Box<Op> {
assert_eq!(data.len(), 0);
let cmd_id = base.cmd_id();

let builder = &mut FlatBufferBuilder::new();
let serialized_resources = table_entries();

let res: Vec<_> = serialized_resources
.iter()
.map(|(key, value)| {
let repr = builder.create_string(value);

msg::Resource::create(
builder,
&msg::ResourceArgs {
rid: key.clone(),
repr: Some(repr),
..Default::default()
},
)
}).collect();

let resources = builder.create_vector(&res);
let inner = msg::ResourcesRes::create(
builder,
&msg::ResourcesResArgs {
resources: Some(resources),
..Default::default()
},
);

ok_future(serialize_response(
cmd_id,
builder,
msg::BaseArgs {
inner: Some(inner.as_union_value()),
inner_type: msg::Any::ResourcesRes,
..Default::default()
},
))
}
34 changes: 34 additions & 0 deletions src/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,40 @@ enum Repr {
TcpStream(tokio::net::TcpStream),
}

pub fn table_entries() -> Vec<(i32, String)> {
let table = RESOURCE_TABLE.lock().unwrap();

let tuples = table
.iter()
.map(|(key, value)| (key.clone(), inspect_repr(&value)))
.collect();

tuples
}

#[test]
fn test_table_entries() {
let mut entries = table_entries();
entries.sort();
assert_eq!(entries.len(), 3);
assert_eq!(entries[0], (0, String::from("stdin")));
assert_eq!(entries[1], (1, String::from("stdout")));
assert_eq!(entries[2], (2, String::from("stderr")));
}

fn inspect_repr(repr: &Repr) -> String {
let h_repr = match repr {
Repr::Stdin(_) => "stdin",
Repr::Stdout(_) => "stdout",
Repr::Stderr(_) => "stderr",
Repr::FsFile(_) => "fsFile",
Repr::TcpListener(_) => "tcpListener",
Repr::TcpStream(_) => "tcpStream",
};

String::from(h_repr)
}

// Abstract async file interface.
// Ideally in unix, if Resource represents an OS rid, it will be the same.
#[derive(Debug)]
Expand Down
1 change: 1 addition & 0 deletions tests/hello.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello world!

0 comments on commit 946acbc

Please sign in to comment.