Best JavaScript code snippet using best
hub.ts
Source:hub.ts
1/*2 * Copyright (c) 2019, salesforce.com, inc.3 * All rights reserved.4 * SPDX-License-Identifier: MIT5 * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT6 */7import { EventEmitter } from "events";8import { Server } from "http";9import { HubConfig, RemoteClientConfig, BrowserSpec, BenchmarkRuntimeConfig, BestAgentState, BenchmarkUpdateState } from "@best/types";10import { normalizeClientConfig , normalizeSpecs } from '@best/utils';11import { Server as SocketIOServer, Socket } from "socket.io";12import { BEST_RPC } from "@best/shared";13import { RemoteClient } from "@best/agent";14import { matchSpecs } from "@best/utils";15import RemoteAgent from "./remote-agent";16import { validateConfig, validateToken } from './utils/validate';17export class Hub extends EventEmitter {18 private activeClients: Map<RemoteClient, RemoteAgent> = new Map();19 private agentsSocketServer: SocketIOServer;20 private clientsSocketServer: SocketIOServer;21 private connectedAgents = new Set<RemoteAgent>();22 private connectedClients = new Set<RemoteClient>();23 private hubConfig: HubConfig;24 constructor(server: Server, hubConfig: HubConfig) {25 super();26 this.hubConfig = hubConfig;27 this.clientsSocketServer = new SocketIOServer(server, { path: '/best' });28 this.clientsSocketServer.on('connect', this.onClientConnect.bind(this));29 this.agentsSocketServer = new SocketIOServer(server, { path: '/agents' });30 this.agentsSocketServer.on('connect', this.onAgentConnect.bind(this));31 }32 // -- Client lifecycle ---------------------------------------------------------------33 onClientConnect(clientSocket: Socket) {34 const query = clientSocket.handshake.query;35 const config = normalizeClientConfig(query);36 const invalidConfig = validateConfig(config, this.hubConfig, this.getAgentSpecs(), clientSocket.id);37 if (invalidConfig) {38 clientSocket.emit(BEST_RPC.AGENT_REJECTION, invalidConfig);39 return clientSocket.disconnect(true);40 }41 const remoteClient = this.setupNewClient(clientSocket, config);42 console.log(`[HUB] Connected clients: ${this.connectedClients.size}`);43 if (this.idleAgentMatchingSpecs(remoteClient)) {44 this.runBenchmarks(remoteClient);45 } else {46 remoteClient.log(`Client enqueued. Waiting for an agent to be free...`);47 this.emit(BEST_RPC.AGENT_QUEUED_CLIENT, { clientId: remoteClient.getId(), jobs: config.jobs, specs: config.specs });48 }49 }50 setupNewClient(socketClient: Socket, clientConfig: RemoteClientConfig): RemoteClient {51 // Create and new RemoteClient and add it to the pool52 const remoteClient = new RemoteClient(socketClient, clientConfig);53 this.connectedClients.add(remoteClient);54 console.log(`[HUB] New client ${remoteClient.getId()} connected. Jobs requested ${clientConfig.jobs} | specs: ${JSON.stringify(clientConfig.specs)}`);55 this.emit(BEST_RPC.AGENT_CONNECTED_CLIENT, { clientId: remoteClient.getId(), jobs: clientConfig.jobs, specs: remoteClient.getSpecs() });56 // Make sure we remove it from an agent's perspective if the client is disconnected57 remoteClient.on(BEST_RPC.DISCONNECT, () => {58 console.log(`[HUB] Disconnected client ${remoteClient.getId()}`);59 this.emit(BEST_RPC.AGENT_DISCONNECTED_CLIENT, remoteClient.getId());60 this.connectedClients.delete(remoteClient);61 console.log(`[HUB] Connected clients: ${this.connectedClients.size}`);62 // If the client is actively running something we need to kill it63 if (this.activeClients.has(remoteClient)) {64 const remoteAgent = this.activeClients.get(remoteClient);65 if (remoteAgent && remoteAgent.isBusy()) {66 remoteAgent.interruptRunner();67 }68 this.activeClients.delete(remoteClient);69 }70 });71 remoteClient.on(BEST_RPC.BENCHMARK_START, (benchmarkId: string) => {72 const agent = this.activeClients.get(remoteClient);73 this.emit(BEST_RPC.BENCHMARK_START, { agentId: agent && agent.getId(), clientId: remoteClient.getId(), benchmarkId });74 });75 remoteClient.on(BEST_RPC.BENCHMARK_END, (benchmarkId: string) => {76 const agent = this.activeClients.get(remoteClient);77 this.emit(BEST_RPC.BENCHMARK_END, { agentId: agent && agent.getId(), clientId: remoteClient.getId(), benchmarkId });78 });79 remoteClient.on(BEST_RPC.BENCHMARK_UPDATE, (benchmarkId: string, state: BenchmarkUpdateState, opts: BenchmarkRuntimeConfig) => {80 const agent = this.activeClients.get(remoteClient);81 this.emit(BEST_RPC.BENCHMARK_UPDATE, { agentId: agent && agent.getId(), clientId: remoteClient.getId(), benchmarkId, state, opts });82 });83 // If we are done with the job, make sure after a short time the client gets removed84 remoteClient.on(BEST_RPC.REMOTE_CLIENT_EMPTY_QUEUE, () => {85 console.log(`[HUB] Remote client ${remoteClient.getId()} is done. Scheduling a force disconnect.`);86 setTimeout(() => {87 if (this.connectedClients.has(remoteClient)) {88 console.log(`[HUB] Force client disconnect (${remoteClient.getId()}): With no more jobs to run an agent must disconnect`);89 remoteClient.disconnectClient(`Forced disconnect: With no more jobs client should have disconnected`);90 }91 }, 10000);92 });93 return remoteClient;94 }95 // -- Agent lifecycle ---------------------------------------------------------------96 onAgentConnect(agentSocket: Socket) {97 const query = agentSocket.handshake.query;98 const specs = normalizeSpecs(query);99 const validToken = validateToken(query.authToken as string, this.hubConfig.authToken);100 const hasSpecs = specs.length > 0;101 if (!validToken) {102 agentSocket.emit(BEST_RPC.AGENT_REJECTION, 'Invalid Token');103 return agentSocket.disconnect(true);104 }105 if (!hasSpecs) {106 agentSocket.emit(BEST_RPC.AGENT_REJECTION, 'An agent must provide specs');107 return agentSocket.disconnect(true);108 }109 if (!query.agentUri) {110 agentSocket.emit(BEST_RPC.AGENT_REJECTION, 'An agent must provide a URI');111 return agentSocket.disconnect(true);112 }113 const remoteAgent = this.setupNewAgent(agentSocket, specs, { agentUri: query.agentUri, agentToken: query.agentAuthToken });114 if (remoteAgent) {115 // If queued jobs with those specs, run them...116 }117 }118 setupNewAgent(socketAgent: Socket, specs: BrowserSpec[], { agentUri, agentToken }: any): RemoteAgent {119 // Create and new RemoteAgent and add it to the pool120 const remoteAgent = new RemoteAgent(socketAgent, { uri: agentUri, token: agentToken, specs });121 this.connectedAgents.add(remoteAgent);122 console.log(`[HUB] New Agent ${remoteAgent.getId()} connected with specs: ${JSON.stringify(remoteAgent.getSpecs())}`);123 this.emit(BEST_RPC.HUB_CONNECTED_AGENT, { agentId: remoteAgent.getId(), specs: remoteAgent.getSpecs(), uri: remoteAgent.getUri()});124 // Make sure we remove it from an agent's perspective if the client is disconnected125 remoteAgent.on(BEST_RPC.DISCONNECT, () => {126 console.log(`[HUB] Disconnected Agent ${remoteAgent.getId()}`);127 this.emit(BEST_RPC.HUB_DISCONNECTED_AGENT, { agentId: remoteAgent.getId() });128 this.connectedAgents.delete(remoteAgent);129 if (remoteAgent.isBusy()) {130 remoteAgent.interruptRunner();131 }132 });133 return remoteAgent;134 }135 // -- Private methods ---------------------------------------------------------------136 async runBenchmarks(remoteClient: RemoteClient) {137 // New agent setup138 if (!this.activeClients.has(remoteClient)) {139 const matchingAgents = this.findAgentMatchingSpecs(remoteClient, { ignoreBusy: true });140 if (matchingAgents.length > 0) {141 const remoteAgent = matchingAgents[0];142 this.activeClients.set(remoteClient, remoteAgent);143 this.emit(BEST_RPC.AGENT_RUNNING_CLIENT, { clientId: remoteClient.getId(), agentId: remoteAgent.getId(), jobs: remoteClient.getPendingBenchmarks() });144 try {145 await remoteAgent.runBenchmarks(remoteClient);146 } catch(err) {147 console.log(`[HUB] Error running benchmark for remote client ${remoteClient.getId()}`);148 remoteClient.disconnectClient(`Error running benchmark ${err}`); // make sure we disconnect the agent149 } finally {150 this.activeClients.delete(remoteClient);151 queueMicrotask(() => this.runQueuedBenchmarks());152 }153 } else {154 console.log('[HUB] All agents are busy at this moment...');155 }156 } else {157 console.log(`[HUB] Client ${remoteClient.getId()} is actively running already`)158 }159 }160 runQueuedBenchmarks() {161 Array.from(this.connectedClients).forEach((remoteClient) => {162 if (!this.activeClients.has(remoteClient)) {163 if (this.idleAgentMatchingSpecs(remoteClient) && remoteClient.getPendingBenchmarks() > 0) {164 console.log(`[HUB] Running benchmark: "${remoteClient.getId()}" has ${remoteClient.getPendingBenchmarks()} to run`);165 this.runBenchmarks(remoteClient);166 } else {167 console.log(`[HUB] All matching agents still busy for ${remoteClient.getId()}`);168 }169 }170 });171 }172 getAgentSpecs(): BrowserSpec[] {173 const specs: BrowserSpec[] = [];174 for (const agent of this.connectedAgents) {175 specs.push(...agent.getSpecs());176 }177 return specs;178 }179 idleAgentMatchingSpecs(remoteClient: RemoteClient): boolean {180 return this.findAgentMatchingSpecs(remoteClient, { ignoreBusy: true }).length > 0;181 }182 findAgentMatchingSpecs(remoteClient: RemoteClient, { ignoreBusy }: { ignoreBusy?: boolean } = {}): RemoteAgent[] {183 const specs = remoteClient.getSpecs();184 const agents: RemoteAgent[] = [];185 if (specs) {186 for (const agent of this.connectedAgents) {187 const matchesSpecs = matchSpecs(specs, agent.getSpecs() || []);188 const matchesFilterCriteria = ignoreBusy ? !agent.isBusy(): true;189 if (matchesSpecs && matchesFilterCriteria) {190 agents.push(agent);191 }192 }193 }194 return agents;195 }196 // -- Public API ---------------------------------------------------------------197 getState(): BestAgentState {198 const connectedClients = Array.from(this.connectedClients).map((client) => client.getState());199 const connectedAgents = Array.from(this.connectedAgents).map(agent => agent.getState());200 const activeClients = Array.from(this.activeClients).map(([rc, ra]) => ({ clientId: rc.getId(), agentId: ra.getId() }));201 return {202 connectedClients,203 connectedAgents,204 activeClients205 };206 }207 /**208 * Gets a list of all agents connected to the hub209 * @returns an array with connected agents210 */211 getAgents() {212 return Array.from(this.connectedAgents).map(agent => agent.getState());213 }214 /**215 * Gets agent info based on specified identifier.216 * @param id a unique identifier of an agent217 * @returns agent info218 */219 getAgent(id: string) {220 const agents = Array.from(this.connectedAgents)221 .filter((agent) => agent.getId() === id)222 .map(agent => agent.getState());223 if (!agents || agents.length === 0) {224 return;225 }226 if (agents.length > 1) {227 throw new Error(`Multiple agents with the same ID found. ID: ${id}`);228 }229 return agents[0];230 }...
Using AI Code Generation
1var BestBuyStore = require('./BestBuyStore');2var store = new BestBuyStore();3var filterCriteria = {state: 'CA', city: 'San Jose'};4var matches = store.matchesFilterCriteria(filterCriteria);5console.log(matches);6var Store = require('./Store');7var BestBuyStore = function() {8 Store.call(this);9 this.state = 'CA';10 this.city = 'San Jose';11 this.zip = '95112';12};13BestBuyStore.prototype = Object.create(Store.prototype);14BestBuyStore.prototype.constructor = BestBuyStore;15BestBuyStore.prototype.matchesFilterCriteria = function(filterCriteria) {16 var matches = true;17 for (var key in filterCriteria) {18 if (this[key] !== filterCriteria[key]) {19 matches = false;20 break;21 }22 }23 return matches;24};25module.exports = BestBuyStore;26var Store = function() {27};28Store.prototype.matchesFilterCriteria = function(filterCriteria) {29 throw new Error('Not implemented');30};31module.exports = Store;
Using AI Code Generation
1var bestBook = require('./bestBook.js');2var book = new bestBook.BestBook('The Hobbit','J.R.R. Tolkien',1937,'fantasy');3console.log('The Hobbit is a fantasy book: ' + book.matchesFilterCriteria('fantasy'));4console.log('The Hobbit is a mystery book: ' + book.matchesFilterCriteria('mystery'));5console.log('The Hobbit is a book published in 1937: ' + book.matchesFilterCriteria(1937));6console.log('The Hobbit is a book published in 1940: ' + book.matchesFilterCriteria(1940));7console.log('The Hobbit is a book published in 1937 or 1940: ' + book.matchesFilterCriteria([1937,1940]));8console.log('The Hobbit is a book published in 1937 or 1950: ' + book.matchesFilterCriteria([1937,1950]));9console.log('The Hobbit is a book published in 1937 and 1950: ' + book.matchesFilterCriteria([[1937,1950]]));10console.log('The Hobbit is a book published in 1937 and 1950 or 1980: ' + book.matchesFilterCriteria([[1937,1950],1980]));11console.log('The Hobbit is a book published in 1937 and 1950 or 1980 and 2010: ' + book.matchesFilterCriteria([[1937,1950],[1980,2010]]));12console.log('The Hobbit is a book published in 1937 and 1950 or 1980 and 2010 or 2015: ' + book.matchesFilterCriteria([[1937,1950],[1980,2010],2015]));13console.log('The Hobbit is a book published in 1937 and 1950 or 1980 and 2010 or 2015 and 2016: ' + book.matchesFilterCriteria([[1937,1950],[1980,2010],[2015,2016]]));14console.log('The Hobbit is a book published in 1937 and 1950 or 1980 and 2010 or 2015 and 2016 or 2017: ' + book.matchesFilterCriteria([[1937,1950],[1980,2010],[2015,2016],2017]));15console.log('The
Using AI Code Generation
1var BestMatchFilter = require("./bestMatchFilter.js");2var filter = new BestMatchFilter();3var matches = filter.matchesFilterCriteria("xyz");4console.log(matches);5function BestMatchFilter() {6 this.matchesFilterCriteria = function (string) {7 return string === "xyz";8 }9}10module.exports = BestMatchFilter;
Using AI Code Generation
1var product = new BestBuyProduct();2var filteredProducts = [];3var allProducts = [];4var searchCriteria = "";5var searchValue = "";6var count = 0;7var total = 0;8var pages = 1;9var page = 1;10var perPage = 25;11var start = 0;12var end = 0;13var products = [];14var pageProducts = [];15var pageFilteredProducts = [];16 "customerReviewAverage", "customerReviewCount"];17 "Customer Review Average", "Customer Review Count"];18var criteriaTypes = ["number", "text", "text", "text", "number", "number"];19var criteriaIndex = 0;20var criteriaName = criteriaNames[criteriaIndex];21var criteriaType = criteriaTypes[criteriaIndex];22var criteriaValue = criteria[criteriaIndex];23var value = "";24var filter = "";25var filters = [];
Using AI Code Generation
1var BestBuyProduct = require('./BestBuyProduct.js');2var products = require('./products.json');3var criteria = require('./criteria.json');4var filteredProducts = products.filter(function(product) {5 return BestBuyProduct.matchesFilterCriteria(product, criteria);6});7console.log(filteredProducts);8var BestBuyProduct = function() {9};10BestBuyProduct.matchesFilterCriteria = function(product, criteria) {11 var matches = true;12 var productKeys = Object.keys(product);13 var criteriaKeys = Object.keys(criteria);14 for (var i = 0; i < criteriaKeys.length; i++) {15 var key = criteriaKeys[i];16 if (productKeys.indexOf(key) > -1) {17 if (product[key] != criteria[key]) {18 matches = false;19 break;20 }21 }22 }23 return matches;24};25module.exports = BestBuyProduct;26 {27 "name": "Apple iPhone 6 16GB - Space Gray (Verizon Wireless)",28 "shortDescription": "Apple iPhone 6 16GB - Space Gray (Verizon Wireless)",29 "longDescription": "Apple iPhone 6 16GB - Space Gray (Verizon Wireless)",
Using AI Code Generation
1var BestMatchFinder = require('./BestMatchFinder.js');2var bestMatchFinder = new BestMatchFinder();3var string = "I like to play footbal";4var matches = bestMatchFinder.findMatches(string);5console.log("Best match for '" + string + "' is: " + matches[0]);6console.log("Other matches are: " + matches.slice(1));7The findMatches method returns an array of matches, sorted by score (the best match first). Each match is an object with the following
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!