Skip to content

Commit

Permalink
[explorer] implement batching requests (MystenLabs#1836)
Browse files Browse the repository at this point in the history
  • Loading branch information
666lcz authored May 5, 2022
1 parent 141d3a9 commit 089e4d1
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 5 deletions.
7 changes: 3 additions & 4 deletions explorer/client/src/components/ownedobjects/OwnedObjects.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,8 @@ function OwnedObjectAPI({ id }: { id: string }) {
// getOwnedObjectRefs will need to return id, type and balance for each owned object
useEffect(() => {
rpc.getOwnedObjectRefs(id).then((objects) => {
Promise.all(
objects.map(({ objectId }) => rpc.getObjectInfo(objectId))
).then((results) => {
const ids = objects.map(({ objectId }) => objectId);
rpc.getObjectInfoBatch(ids).then((results) => {
setResults(
results
.filter(({ status }) => status === 'Exists')
Expand All @@ -98,7 +97,7 @@ function OwnedObjectAPI({ id }: { id: string }) {
balance: balanceValue,
};
}
//TO DO - add back display and version
//TO DO - add back version
)
);
setIsLoaded(true);
Expand Down
18 changes: 18 additions & 0 deletions sdk/typescript/src/providers/json-rpc-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,24 @@ export class JsonRpcProvider extends Provider {
}
}

async getObjectInfoBatch(
objectIds: string[]
): Promise<GetObjectInfoResponse[]> {
const requests = objectIds.map(id => ({
method: 'sui_getObjectTypedInfo',
args: [id],
}));
try {
const responses = await this.client.batchRequestWithType(
requests,
isGetObjectInfoResponse
);
return responses.map(r => transformGetObjectInfoResponse(r));
} catch (err) {
throw new Error(`Error fetching object info: ${err} for id ${objectIds}`);
}
}

// Transactions
async getTransactionWithEffects(
digest: TransactionDigest
Expand Down
12 changes: 11 additions & 1 deletion sdk/typescript/src/rpc/client.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Generated type guards for "client.ts".
* WARNING: Do not manually change this file.
*/
import { HttpHeaders, ValidResponse, ErrorResponse } from "./client";
import { HttpHeaders, RpcParams, ValidResponse, ErrorResponse } from "./client";
import { isTransactionResponse } from "../index.guard";

export function isHttpHeaders(obj: any, _argumentName?: string): obj is HttpHeaders {
Expand All @@ -16,6 +16,16 @@ export function isHttpHeaders(obj: any, _argumentName?: string): obj is HttpHead
)
}

export function isRpcParams(obj: any, _argumentName?: string): obj is RpcParams {
return (
(obj !== null &&
typeof obj === "object" ||
typeof obj === "function") &&
isTransactionResponse(obj.method) as boolean &&
Array.isArray(obj.args)
)
}

export function isValidResponse(obj: any, _argumentName?: string): obj is ValidResponse {
return (
(obj !== null &&
Expand Down
40 changes: 40 additions & 0 deletions sdk/typescript/src/rpc/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ import { isErrorResponse, isValidResponse } from './client.guard';
*/
export type HttpHeaders = { [header: string]: string };

/**
* @internal
*/
export type RpcParams = {
method: string;
args: Array<any>;
};

export class JsonRpcClient {
private rpcClient: RpcClient;

Expand Down Expand Up @@ -83,6 +91,38 @@ export class JsonRpcClient {
});
});
}

async batchRequestWithType<T>(
requests: RpcParams[],
isT: (val: any) => val is T
): Promise<T[]> {
const responses = await this.batchRequest(requests);
// TODO: supports other error modes such as throw or return
const validResponses = responses.filter(
(response: any) => isValidResponse(response) && isT(response.result)
);

return validResponses.map((response: ValidResponse) => response.result);
}

async batchRequest(requests: RpcParams[]): Promise<any> {
return new Promise((resolve, reject) => {
// Do nothing if requests is empty
if (requests.length === 0) resolve([]);

const batch = requests.map(params => {
return this.rpcClient.request(params.method, params.args);
});

this.rpcClient.request(batch, (err: any, response: any) => {
if (err) {
reject(err);
return;
}
resolve(response);
});
});
}
}

export type ValidResponse = {
Expand Down

0 comments on commit 089e4d1

Please sign in to comment.