"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;