Skip to content

Commit

Permalink
Unifies nodes fetching and caching under a dedicated class
Browse files Browse the repository at this point in the history
  • Loading branch information
ygrishajev committed Apr 1, 2024
1 parent 5d44037 commit 15fd8ba
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 27 deletions.
22 changes: 22 additions & 0 deletions api/src/caching/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,28 @@ interface CachedObject<T> {
data: T;
}

interface MemoizeOptions {
keepData?: boolean;
ttlInSeconds?: number;
key?: string;
}

export const Memoize = (options?: MemoizeOptions) => (target: object, propertyName: string, descriptor: PropertyDescriptor) => {
const originalMethod = descriptor.value;

const cacheKeySymbol = options?.key || `${target.constructor.name}#${propertyName}`;

descriptor.value = async function memoizedFunction(...args: unknown[]) {
return await cacheResponse(
options?.ttlInSeconds || 60 * 2,
cacheKeySymbol,
originalMethod.bind(this, ...args),
options?.keepData
);
}
}


export async function cacheResponse<T>(seconds: number, key: string, refreshRequest: () => Promise<T>, keepData?: boolean): Promise<T> {
const duration = seconds * 1000;
const cachedObject = cacheEngine.getFromCache(key) as CachedObject<T> | undefined;
Expand Down
11 changes: 2 additions & 9 deletions api/src/routes/v1/nodes/mainnet.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
import { cacheKeys, cacheResponse } from "@src/caching/helpers";
import axios from "axios";
import { nodeClient } from '@src/routes/v1/nodes/node-client';

const route = createRoute({
method: "get",
Expand All @@ -26,11 +25,5 @@ const route = createRoute({
});

export default new OpenAPIHono().openapi(route, async (c) => {
const response = await cacheResponse(60 * 2, cacheKeys.getMainnetNodes, async () => {
const res = await axios.get<{ id: string; api: string; rpc: string }[]>(
"https://raw.githubusercontent.com/akash-network/cloudmos/main/config/mainnet-nodes.json"
);
return res.data;
});
return c.json(response);
return c.json(await nodeClient.getMainnetNodes());
});
66 changes: 66 additions & 0 deletions api/src/routes/v1/nodes/nodeClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import axios, { AxiosInstance } from 'axios';
import { Memoize } from '@src/caching/helpers';

interface Node {
id: string;
api: string;
rpc: string
}

export class NodeClient {
constructor(private readonly http: AxiosInstance = axios.create({
baseURL: "https://raw.githubusercontent.com/akash-network",
})) {}

@Memoize()
async getMainnetNodes() {
return await this.get<Node[]>(
"cloudmos/main/config/mainnet-nodes.json"
);
}

@Memoize()
async getMainnetVersion() {
return await this.get<string>(
"net/master/mainnet/version.txt"
);
}

@Memoize()
async getSandboxNodes() {
return await this.get<Node[]>(
"cloudmos/main/config/sandbox-nodes.json"
);
}

@Memoize()
async getSandboxVersion() {
return await this.get<string>(
"net/master/sandbox/version.txt"
);
}

@Memoize()
async getTestnetNodes() {
return await this.get<Node[]>(
"cloudmos/main/config/testnet-nodes.json"
);
}

@Memoize()
async getTestnetVersion() {
return await this.get<string>(
"net/master/testnet-02/version.txt"
);
}

private async get<T>(path: string) {
const response = await this.http.get<T>(
path
);

return response.data;
}
}

export const nodeClient = new NodeClient();
11 changes: 2 additions & 9 deletions api/src/routes/v1/nodes/sandbox.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
import { cacheKeys, cacheResponse } from "@src/caching/helpers";
import axios from "axios";
import { nodeClient } from '@src/routes/v1/nodes/node-client';

const route = createRoute({
method: "get",
Expand All @@ -26,11 +25,5 @@ const route = createRoute({
});

export default new OpenAPIHono().openapi(route, async (c) => {
const response = await cacheResponse(60 * 2, cacheKeys.getSandboxNodes, async () => {
const res = await axios.get<{ id: string; api: string; rpc: string }[]>(
"https://raw.githubusercontent.com/akash-network/cloudmos/main/config/sandbox-nodes.json"
);
return res.data;
});
return c.json(response);
return c.json(await nodeClient.getSandboxNodes());
});
11 changes: 2 additions & 9 deletions api/src/routes/v1/nodes/testnet.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
import { cacheKeys, cacheResponse } from "@src/caching/helpers";
import axios from "axios";
import { nodeClient } from '@src/routes/v1/nodes/node-client';

const route = createRoute({
method: "get",
Expand All @@ -26,11 +25,5 @@ const route = createRoute({
});

export default new OpenAPIHono().openapi(route, async (c) => {
const response = await cacheResponse(60 * 2, cacheKeys.getTestnetNodes, async () => {
const res = await axios.get<{ id: string; api: string; rpc: string }[]>(
"https://raw.githubusercontent.com/akash-network/cloudmos/main/config/testnet-nodes.json"
);
return res.data;
});
return c.json(response);
return c.json(await nodeClient.getTestnetNodes());
});

0 comments on commit 15fd8ba

Please sign in to comment.