Skip to content

Commit

Permalink
feat: batching
Browse files Browse the repository at this point in the history
  • Loading branch information
BelfordZ committed Jul 24, 2019
1 parent 4c97406 commit 5cc5887
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 2 deletions.
48 changes: 46 additions & 2 deletions src/RequestManager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import ITransport from "./transports/Transport";
let id = 1;

interface IJSONRPCRequest {
jsonrpc: "2.0";
id: number;
method: string;
params: any[] | object;
}

/*
** Naive Request Manager, only use 1st transport.
* A more complex request manager could try each transport.
Expand All @@ -10,11 +17,15 @@ class RequestManager {
public transports: ITransport[];
private requests: any;
private connectPromise: Promise<any>;
private batchStarted: boolean = false;
private batch: IJSONRPCRequest[] = [];

constructor(transports: ITransport[]) {
this.transports = transports;
this.requests = {};
this.connectPromise = this.connect();
}

public connect(): Promise<any> {
const promises = this.transports.map((transport) => {
return new Promise(async (resolve, reject) => {
Expand All @@ -27,6 +38,7 @@ class RequestManager {
});
return Promise.all(promises);
}

public async request(method: string, params: any): Promise<any> {
await this.connectPromise;
return new Promise((resolve, reject) => {
Expand All @@ -37,19 +49,51 @@ class RequestManager {
resolve,
reject,
};
transport.sendData(JSON.stringify({
const payload: IJSONRPCRequest = {
jsonrpc: "2.0",
id: i,
method,
params,
}));
};
if (this.batchStarted) {
this.batch.push(payload); // could dedupe
} else {
transport.sendData(JSON.stringify(payload));
}
});
}

public close(): void {
this.transports.forEach((transport) => {
transport.close();
});
}

/**
*
*/
public startBatch(): void {
if (this.batchStarted) { return; }
this.batchStarted = true;
}

/**
*
*/
public endBatch(): void {
if (this.batchStarted === false) {
throw new Error("cannot end that which has never started");
}

if (this.batch.length === 0) {
return;
}

const batch = JSON.stringify(this.batch);
this.batch = [];
this.transports[0].sendData(batch);
}

private onData(data: string): void {
const parsedData = JSON.parse(data);
if (typeof parsedData.result === "undefined" && typeof parsedData.error === "undefined") {
Expand Down
27 changes: 27 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ interface IClient {
/**
* OpenRPC Client JS is a browser-compatible JSON-RPC client with multiple transports and
* multiple request managers to enable features like round-robin or fallback-by-position.
*
* @example
* ```typescript
* import { RequestManager, HTTPTransport, Client } from '@open-rpc/client-js';
Expand All @@ -18,6 +19,7 @@ interface IClient {
* const result = await client.request(‘addition’, [2, 2]);
* // => { jsonrpc: '2.0', id: 1, result: 4 }
* ```
*
*/

class Client implements IClient {
Expand All @@ -26,6 +28,31 @@ class Client implements IClient {
this.requestManager = requestManager;
}

/**
* A JSON-RPC call is represented by sending a Request object to a Server.
*
* @param method A String containing the name of the method to be invoked.
* Method names that begin with the word rpc followed by a
* period character (U+002E or ASCII 46) are reserved for rpc-internal
* methods and extensions and MUST NOT be used for anything else.
* @param params A Structured value that holds the parameter values to be used during the invocation of the method.
*/
public startBatch(): void {
return this.requestManager.startBatch();
}

/**
* A JSON-RPC call is represented by sending a Request object to a Server. See [[RequestManager#endBatch]]
*
* @param method A String containing the name of the method to be invoked.
* Method names that begin with the word rpc followed by a
* period character (U+002E or ASCII 46) are reserved for rpc-internal
* methods and extensions and MUST NOT be used for anything else.
* @param params A Structured value that holds the parameter values to be used during the invocation of the method.
*/
public endBatch(): void {
return this.requestManager.endBatch();
}
/**
* A JSON-RPC call is represented by sending a Request object to a Server.
*
Expand Down

0 comments on commit 5cc5887

Please sign in to comment.