83 lines
2.4 KiB
JavaScript
83 lines
2.4 KiB
JavaScript
"use strict";
|
|
|
|
import { once, EventEmitter } from 'events';
|
|
|
|
import Agent from './agent/Agent.mjs';
|
|
import InfoBroker from './core/InfoBroker.mjs';
|
|
|
|
class SystemQuery extends EventEmitter {
|
|
constructor(config, mode = "agent") {
|
|
super();
|
|
|
|
// The operating mode. Possible values: agent [default], query_client
|
|
// TODO: Is this the best way of doing this? Maybe we should have a separate class for this? I'm not sure.
|
|
this.mode = mode;
|
|
this.config = config;
|
|
this.info = new InfoBroker();
|
|
}
|
|
|
|
async init() {
|
|
///
|
|
// 1: Create agent
|
|
///
|
|
this.agent = new Agent(this.config);
|
|
await this.agent.init();
|
|
|
|
///
|
|
// 2: Attach listeners
|
|
///
|
|
this.agent.on("message-query", this.handle_query.bind(this));
|
|
this.agent.on("message-query-response", this.handle_query_response.bind(this));
|
|
}
|
|
|
|
async handle_query(peer, msg) {
|
|
// 1: Validate input
|
|
if(typeof msg.table !== "string"
|
|
|| !this.info.is_valid_table(msg.table)) return;
|
|
|
|
// 2: Fetch system info
|
|
let table = await this.info.fetch_table(msg.table);
|
|
if(table === null) return;
|
|
|
|
// 3: Return to requester
|
|
await peer.send("query-response", { result: table });
|
|
}
|
|
async handle_query_response(peer, msg) {
|
|
|
|
}
|
|
|
|
async capture_query_response(event_name, ac) {
|
|
return await once(this.agent, `message-${event_name}`, { signal: ac });
|
|
}
|
|
|
|
*fetch_table(name) {
|
|
// If it isn't valid for us, it ain't gonna be valid for anyone else....
|
|
if(!this.info.is_valid_table(name)) return null;
|
|
|
|
const queue = new p_queue({ })
|
|
const peers_seen = [];
|
|
while(peers_seen.length < this.agent.connected_peers.length) {
|
|
|
|
}
|
|
|
|
const handle_response = (peer, msg) => {
|
|
// TODO: Validate response. Is it the right table? Is it even a table? Note that multiple fetch_table calls may be running in parallel, so we should not make too much of a fuss if we get the wrong table by accident.
|
|
// TODO: It would be seriously cool to have fetch_table() be an async generator that yields pairs of peer ids and tables as they come in.
|
|
if(no_peers_left_or_hit_timeout) {
|
|
this.off("message-query-response", handle_response);
|
|
}
|
|
};
|
|
|
|
this.on("message-query-response", handle_response);
|
|
|
|
// FUTURE: Add a cache here? Note that we also do not listen for query responses unless we've asked for a table.
|
|
}
|
|
}
|
|
|
|
SystemQuery.Create = async function(config) {
|
|
let result = new SystemQuery(config);
|
|
await result.init();
|
|
return result;
|
|
}
|
|
|
|
export default SystemQuery;
|