Skip to content

Commit

Permalink
Deno.core.getOps()
Browse files Browse the repository at this point in the history
  • Loading branch information
bartlomieju committed Sep 24, 2019
1 parent 04e4516 commit 94c3bdb
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 71 deletions.
50 changes: 41 additions & 9 deletions core/examples/http_bench.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,47 @@
// This is not a real HTTP server. We read blindly one time into 'requestBuf',
// then write this fixed 'responseBuf'. The point of this benchmark is to
// exercise the event loop in a simple yet semi-realistic way.
class HttpOp extends Deno.core.Op {
const registry = {};

function initOps(opsMap) {
for (const [name, opId] of Object.entries(opsMap)) {
const op = registry[name];

if (!op) {
continue;
}

op.setOpId(opId);
}
}

class Op {
constructor(name) {
if (typeof registry[name] !== "undefined") {
throw new Error(`Duplicate op: ${name}`);
}

this.name = name;
this.opId = 0;
registry[name] = this;
}

setOpId(opId) {
this.opId = opId;
}

static handleAsyncMsgFromRust(opId, buf) {
const record = recordFromBuf(buf);
const { promiseId, result } = record;
const { promiseId } = record;
const p = promiseMap.get(promiseId);
promiseMap.delete(promiseId);
p.resolve(result);
p.resolve(record);
}

/** Returns i32 number */
static sendSync(opId, arg, zeroCopy) {
const buf = send(0, opId, arg, zeroCopy);
const record = recordFromBuf(buf);
return record.result;
return recordFromBuf(buf);
}

/** Returns Promise<number> */
Expand All @@ -25,13 +52,17 @@ class HttpOp extends Deno.core.Op {
send(promiseId, opId, arg, zeroCopy);
return p;
}
}

class HttpOp extends Op {
sendSync(arg, zeroCopy = null) {
return HttpOp.sendSync(this.opId, arg, zeroCopy);
const res = HttpOp.sendSync(this.opId, arg, zeroCopy);
return res.result;
}

sendAsync(arg, zeroCopy = null) {
return HttpOp.sendAsync(this.opId, arg, zeroCopy);
async sendAsync(arg, zeroCopy = null) {
const res = await HttpOp.sendAsync(this.opId, arg, zeroCopy);
return res.result;
}
}

Expand Down Expand Up @@ -132,7 +163,8 @@ async function serve(rid) {
}

async function main() {
Deno.core.initOps();
Deno.core.setAsyncHandler(Op.handleAsyncMsgFromRust);
initOps(Deno.core.getOps());
Deno.core.print("http_bench.js start\n");

const listenerRid = listen();
Expand Down
73 changes: 13 additions & 60 deletions core/shared_queue.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ SharedQueue Binary Layout

let sharedBytes;
let shared32;
let rustOpsMap;
const jsOpsMap = new Map();
let jsOpsAsyncHandlers;
let initialized = false;

function maybeInit() {
Expand All @@ -61,24 +58,10 @@ SharedQueue Binary Layout
Deno.core.recv(handleAsyncMsgFromRust);
}

function initOps() {
function getOps() {
const opsMapBytes = Deno.core.send(0, new Uint8Array([]), null);
const opsMapJson = String.fromCharCode.apply(null, opsMapBytes);
rustOpsMap = JSON.parse(opsMapJson);
const opVector = new Array(Object.keys(rustOpsMap).length);

for (const [name, opId] of Object.entries(rustOpsMap)) {
const op = jsOpsMap.get(name);

if (!op) {
continue;
}

op.setOpId(opId);
opVector[opId] = op.constructor.handleAsyncMsgFromRust;
}

jsOpsAsyncHandlers = opVector;
return JSON.parse(opsMapJson);
}

function assert(cond) {
Expand Down Expand Up @@ -107,17 +90,18 @@ SharedQueue Binary Layout
return shared32[INDEX_NUM_RECORDS] - shared32[INDEX_NUM_SHIFTED_OFF];
}

// TODO(ry) rename to setMeta
function setMeta(index, end, opId) {
function setMeta(index, end, opId, promiseId) {
shared32[INDEX_OFFSETS + 2 * index] = end;
shared32[INDEX_OFFSETS + 2 * index + 1] = opId;
shared32[INDEX_OFFSETS + 2 * index + 2] = promiseId;
}

function getMeta(index) {
if (index < numRecords()) {
const buf = shared32[INDEX_OFFSETS + 2 * index];
const opId = shared32[INDEX_OFFSETS + 2 * index + 1];
return [opId, buf];
const promiseId = shared32[INDEX_OFFSETS + 2 * index + 2];
return [opId, promiseId, buf];
} else {
return null;
}
Expand All @@ -135,15 +119,15 @@ SharedQueue Binary Layout
}
}

function push(opId, buf) {
function push(opId, promiseId, buf) {
const off = head();
const end = off + buf.byteLength;
const index = numRecords();
if (end > shared32.byteLength || index >= MAX_RECORDS) {
// console.log("shared_queue.js push fail");
return false;
}
setMeta(index, end, opId);
setMeta(index, end, opId, promiseId);
assert(end - off == buf.byteLength);
sharedBytes.set(buf, off);
shared32[INDEX_NUM_RECORDS] += 1;
Expand All @@ -160,7 +144,7 @@ SharedQueue Binary Layout
}

const off = getOffset(i);
const [opId, end] = getMeta(i);
const [opId, promiseId, end] = getMeta(i);

if (size() > 1) {
shared32[INDEX_NUM_SHIFTED_OFF] += 1;
Expand All @@ -171,7 +155,7 @@ SharedQueue Binary Layout
assert(off != null);
assert(end != null);
const buf = sharedBytes.subarray(off, end);
return [opId, buf];
return [opId, promiseId, buf];
}

let asyncHandler;
Expand All @@ -184,16 +168,14 @@ SharedQueue Binary Layout
function handleAsyncMsgFromRust(opId, buf) {
if (buf) {
// This is the overflow_response case of deno::Isolate::poll().
const cb = asyncHandler ? asyncHandler : jsOpsAsyncHandlers[opId];
cb(opId, buf);
asyncHandler(opId, buf);
} else {
while (true) {
const opIdBuf = shift();
if (opIdBuf == null) {
break;
}
const cb = asyncHandler ? asyncHandler : jsOpsAsyncHandlers[opIdBuf[0]];
cb(...opIdBuf);
asyncHandler(opId, buf);
}
}
}
Expand All @@ -203,34 +185,6 @@ SharedQueue Binary Layout
return Deno.core.send(opId, control, zeroCopy);
}

class Op {
constructor(name) {
if (typeof jsOpsMap.get(name) !== "undefined") {
throw new Error(`Duplicate op: ${name}`);
}

this.name = name;
this.opId = 0;
jsOpsMap.set(name, this);
}

setOpId(opId) {
this.opId = opId;
}

static handleAsyncMsgFromRust(_opId, _buf) {
throw new Error("Unimplemented");
}

static sendSync(_opId, _control, _zeroCopy = null) {
throw new Error("Unimplemented");
}

static sendAsync(_opId, _control, _zeroCopy = null) {
throw new Error("Unimplemented");
}
}

const denoCore = {
setAsyncHandler,
dispatch,
Expand All @@ -243,8 +197,7 @@ SharedQueue Binary Layout
reset,
shift
},
initOps,
Op
getOps
};

assert(window[GLOBAL_NAMESPACE] != null);
Expand Down
3 changes: 1 addition & 2 deletions deno_typescript/lib.deno_core.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ declare interface DenoCore {
shift(): Uint8Array | null;
};

Op: typeof Op;
initOps(): void;
getOps(): Record<string, number>;

recv(cb: MessageCallback): void;

Expand Down

0 comments on commit 94c3bdb

Please sign in to comment.