wip: Working experiment

This commit is contained in:
Jeremy Wall 2025-04-15 21:38:41 -04:00
parent a216275eb5
commit ade221003e
2 changed files with 67 additions and 25 deletions

View File

@ -133,7 +133,7 @@ async fn handle_socket(
))) )))
.await .await
{ {
eprintln!("Error sending bootstrap reference: {:?}", e); println!("Error sending bootstrap reference: {:?}", e);
continue; continue;
} }
} }
@ -143,11 +143,11 @@ async fn handle_socket(
.send(Message::Item(ServerMsg::Reference((**reference).clone()))) .send(Message::Item(ServerMsg::Reference((**reference).clone())))
.await .await
{ {
eprintln!("Error sending reference: {:?}", e); println!("Error sending reference: {:?}", e);
continue; continue;
} }
} else { } else {
eprintln!("Reference not found: {}", path); println!("Reference not found: {}", path);
} }
} }
Message::Item(ClientMsg::GetObject(address)) => { Message::Item(ClientMsg::GetObject(address)) => {
@ -156,21 +156,21 @@ async fn handle_socket(
.send(Message::Item(ServerMsg::Object(object.content.clone()))) .send(Message::Item(ServerMsg::Object(object.content.clone())))
.await .await
{ {
eprintln!("Error sending object: {:?}", e); println!("Error sending object: {:?}", e);
continue; continue;
} }
} else { } else {
eprintln!("Object not found: {}", address); println!("Object not found: {}", address);
} }
} }
Message::Ping(items) => { Message::Ping(items) => {
eprintln!("unhandled ping msg: {:?}", items); println!("unhandled ping msg: {:?}", items);
} }
Message::Pong(items) => { Message::Pong(items) => {
eprintln!("unhandled pong msg: {:?}", items); println!("unhandled pong msg: {:?}", items);
} }
Message::Close(_close_frame) => { Message::Close(_close_frame) => {
eprintln!("closing websocket connection at client request"); println!("closing websocket connection at client request");
break; break;
} }
} }
@ -206,7 +206,7 @@ pub fn endpoints(
pub async fn serve() { pub async fn serve() {
// run our app with hyper, listening globally on port 3000 // run our app with hyper, listening globally on port 3000
let (root_ref, refs, objects) = random_references_and_objects(); let (root_ref, refs, objects) = random_references_and_objects();
println!("Server starting on http://127.0.0.1:3000"); println!("Server ui starting on http://127.0.0.1:3000/ui/");
println!("WebSocket endpoint available at ws://127.0.0.1:3000/api/v1/ws"); println!("WebSocket endpoint available at ws://127.0.0.1:3000/api/v1/ws");
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000") let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
.await .await

View File

@ -8,12 +8,44 @@ export { bootstrap };
* @property {string} content_address * @property {string} content_address
*/ */
async function load_bootstrap() { /**
let response = await fetch("/api/v1/ref/all/username"); * @typedef {Object} ServerMsg
if (!response.ok) { * @property {Reference?} Reference
throw new Error("Network response was not ok: " + response.statusText); * @property {string?} Object
} */
return await response.json();
/**
* @param {WebSocket} socket
* @returns {Promise<ServerMsg>}
*/
async function load_bootstrap(socket) {
// Wait for the connection to be established
const data = await send_socket_msg(socket,
JSON.stringify("Bootstrap"));
return data;
}
/**
* @param {WebSocket} socket
* @param {string} msg
* @returns {Promise<ServerMsg>}
*/
async function send_socket_msg(socket, msg) {
// Send a request for all references
socket.send(msg);
// Wait for the response
/** @type {Promise<String>} */
const stream = await new Promise((resolve, reject) => {
socket.onmessage = (event) => {
resolve(event.data.text());
};
socket.onerror = (_error) => reject(new Error("WebSocket error occurred"));
});
let data = await stream;
return JSON.parse(data);
} }
/** /**
@ -72,7 +104,7 @@ function storeObject(store, reference, root_path) {
* @returns {Promise<Array<Reference>>} An array of references * @returns {Promise<Array<Reference>>} An array of references
*/ */
function load_reference_paths(refStore, reference) { function load_reference_paths(refStore, reference) {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, _reject) => {
let references = []; let references = [];
references.push(reference); references.push(reference);
if (reference.dependents) { if (reference.dependents) {
@ -87,23 +119,24 @@ function load_reference_paths(refStore, reference) {
} }
/** /**
* @param {WebSocket} socket
* @param {IDBDatabase} db * @param {IDBDatabase} db
* @param {string} storeName * @param {string} storeName
* @param {Array<Reference>} references * @param {Array<Reference>} references
*/ */
async function load_objects_and_store(db, references, storeName) { async function load_objects_and_store(socket, db, references, storeName) {
let objects = [] let objects = []
for (var ref of references) { for (var ref of references) {
/** @type {Response} */ /** @type {Response} */
if (ref.dependents && ref.dependents.length != 0) { if (ref.dependents && ref.dependents.length != 0) {
continue; // not a leaf object continue; // not a leaf object
} }
let response = await fetch("/api/v1/object/" + ref.content_address);
if (!response.ok) { let data = await send_socket_msg(socket, JSON.stringify({ "GetObject": ref.content_address }));
throw new Error("Network response was not ok: " + response.statusText); if (!data.Object) {
throw { error: "Not an object" };
} }
const object = await response.text(); objects.push({ id: ref.content_address, content: data.Object });
objects.push({ id: ref.content_address, content: object });
} }
const objectTrxAndStore = await getStoreAndTransaction(db, storeName); const objectTrxAndStore = await getStoreAndTransaction(db, storeName);
for (var obj of objects) { for (var obj of objects) {
@ -133,7 +166,16 @@ async function bootstrap() {
const objectStoreName = "objects"; const objectStoreName = "objects";
const databaseName = "MerkleStore"; const databaseName = "MerkleStore";
const start = new Date().getTime(); const start = new Date().getTime();
const root = await load_bootstrap(); const socket = new WebSocket(`ws://${window.location.host}/api/v1/ws`);
await new Promise((resolve, reject) => {
socket.onopen = () => resolve();
socket.onerror = (error) => reject(new Error("WebSocket connection failed" + error));
});
const data = await load_bootstrap(socket);
if (!data.Reference) {
throw { error: "Not a Reference" };
}
const db = await openDatabase(databaseName, [refStoreName, objectStoreName]); const db = await openDatabase(databaseName, [refStoreName, objectStoreName]);
const refTrxAndStore = await getStoreAndTransaction(db, refStoreName); const refTrxAndStore = await getStoreAndTransaction(db, refStoreName);
@ -143,12 +185,12 @@ async function bootstrap() {
refTrxAndStore.trx.onerror = (event) => reject(event.target.error); refTrxAndStore.trx.onerror = (event) => reject(event.target.error);
}); });
const refs = await load_reference_paths(refTrxAndStore.store, root); const refs = await load_reference_paths(refTrxAndStore.store, data.Reference);
// Wait for the transaction to complete // Wait for the transaction to complete
await transactionComplete; await transactionComplete;
await load_objects_and_store(db, refs, objectStoreName); await load_objects_and_store(socket, db, refs, objectStoreName);
const end = new Date().getTime(); const end = new Date().getTime();
return end - start; return end - start;