Split reader and writer logic up

This commit is contained in:
Thomas Lisankie 2021-05-06 13:57:50 -05:00
parent 9258da9096
commit efedb30fff
4 changed files with 115 additions and 48 deletions

View File

@ -2,7 +2,7 @@
"name": "rpc-cache-server",
"version": "0.0.1",
"description": "A server to cache results of (expensive) RPC requests made to the Solana JSON RPC API",
"main": "src/index.js",
"main": "src/reader.js",
"author": "Thomas Lisankie (Monadical)",
"license": "MIT",
"private": false,

View File

@ -1,47 +0,0 @@
const { JSONRPCServer } = require("json-rpc-2.0");
const express = require("express");
const bodyParser = require("body-parser");
const redis = require("redis");
const crypto = require("crypto");
const server = new JSONRPCServer();
const redisClient = redis.createClient();
const getProgramAccounts = function({ wormholeID })
{
return new Promise((resolve, reject) => {
redisClient.get(wormholeID, function(err, reply) {
if (err) {
reject(err);
} else {
if (reply === null) {
let uuid = crypto.randomUUID();
redisClient.set(wormholeID, uuid, redis.print);
resolve(uuid);
return;
}
resolve(reply);
}
});
});
};
server.addMethod("getProgramAccounts", getProgramAccounts);
const app = express();
app.use(bodyParser.json());
app.post("/json-rpc", (req, res) => {
const jsonRPCRequest = req.body;
// server.receive takes a JSON-RPC request and returns a Promise of a JSON-RPC response.
console.log("received request");
console.log(jsonRPCRequest);
server.receive(jsonRPCRequest).then((jsonRPCResponse) => {
if (jsonRPCResponse) {
res.json(jsonRPCResponse);
} else {
console.log("no response");
res.sendStatus(204);
}
});
});
app.listen(80);

View File

@ -0,0 +1,78 @@
const { JSONRPCServer } = require("json-rpc-2.0");
const express = require("express");
const bodyParser = require("body-parser");
const redis = require("redis");
const crypto = require("crypto");
const axios = require("axios");
const server = new JSONRPCServer();
const redisClient = redis.createClient();
const getProgramAccounts = function({ wormholeID })
{
return new Promise((resolve, reject) => {
redisClient.get(wormholeID, function(err, reply) {
if (err) {
reject(err);
} else {
if (reply === null) { // if cache miss
let uuid = crypto.randomUUID();
redisClient.set(wormholeID, uuid, redis.print);
// What it needs to do:
// 1. Notify the writer
axios({
method : "post",
url : "http://localhost:3001/",
data : {identifier : wormholeID}
});
// 2. Send an RPC request to the full node on behalf of the client
const client = new JSONRPCClient((jsonRPCRequest) =>
axios({
method: "post",
url: "http://127.0.0.1:8899", // localnet url
headers: {
"content-type": "application/json",
},
data: jsonRPCRequest,
}).then((response) => {
if (response.status === 200) {
// Use client.receive when you received a JSON-RPC response.
return client.receive(response.data);
} else if (jsonRPCRequest.id !== undefined) {
return Promise.reject(new Error(response.statusText));
}
})
);
var val = null;
client
.request("getProgramAccounts", { wormholeID: wormholeID })
.then((result) => val = result);
resolve(val);
return;
}
resolve(reply);
}
});
});
};
server.addMethod("getProgramAccounts", getProgramAccounts);
const app = express();
app.use(bodyParser.json());
app.post("/json-rpc", (req, res) => {
const jsonRPCRequest = req.body;
// server.receive takes a JSON-RPC request and returns a Promise of a JSON-RPC response.
console.log("received request");
console.log(jsonRPCRequest);
server.receive(jsonRPCRequest).then((jsonRPCResponse) => {
if (jsonRPCResponse) {
res.json(jsonRPCResponse);
} else {
console.log("no response");
res.sendStatus(204);
}
});
});
app.listen(3000);

View File

@ -0,0 +1,36 @@
const { JSONRPCClient } = require("json-rpc-2.0");
const express = require("express");
const bodyParser = require("body-parser");
const redis = require("redis");
redisClient = redis.createClient();
const app = express();
app.use(bodyParser.json());
app.post("/", (req, res) => {
// when this is called, it means a cache miss happened and the cache needs to be written to.
// to do this, make an RPC call to the full node and write the value to cache.
const client = new JSONRPCClient((jsonRPCRequest) =>
axios({
method: "post",
url: "http://127.0.0.1:8899", // localnet url
headers: {
"content-type": "application/json",
},
data: jsonRPCRequest,
}).then((response) => {
if (response.status === 200) {
// Use client.receive when you received a JSON-RPC response.
return client.receive(response.data);
} else if (jsonRPCRequest.id !== undefined) {
return Promise.reject(new Error(response.statusText));
}
})
);
client.request("getProgramAccounts", {wormholdID: req.body.wormholeID})
.then((result) => redis.set(req.body.wormholeID, result));
// also going to want some cache eviction logic
});
app.listen(3001);