From 3e0927e38196656a892ae22af89527ab2c30b90f Mon Sep 17 00:00:00 2001 From: Luke Kim <80174+lukekim@users.noreply.github.com> Date: Sat, 24 Jun 2023 14:36:53 -0700 Subject: [PATCH] Use https keep-alive agent (#74) * Use https keep-alive agent * Update tests --- src/client.ts | 76 +++++++++++++++++++++++++-------------------- test/client.test.ts | 31 +++++++----------- 2 files changed, 54 insertions(+), 53 deletions(-) diff --git a/src/client.ts b/src/client.ts index e146898..57f05c7 100644 --- a/src/client.ts +++ b/src/client.ts @@ -1,4 +1,5 @@ import path from 'path'; +import * as https from 'https'; import * as grpc from '@grpc/grpc-js'; import * as protoLoader from '@grpc/proto-loader'; import { EventEmitter } from 'stream'; @@ -23,6 +24,7 @@ import { } from './interfaces'; const fetch = require('node-fetch'); +const httpsAgent = new https.Agent({ keepAlive: true }); const HTTP_DATA_PATH = 'https://data.spiceai.io'; const FLIGHT_PATH = 'flight.spiceai.io:443'; @@ -98,7 +100,7 @@ class SpiceClient { throw new Error('Pair is required'); } - const resp = await this.fetch(`/v0.1/prices/${pair}`); + const resp = await this.fetchInternal(`/v0.1/prices/${pair}`); if (!resp.ok) { throw new Error( `Failed to get latest price: ${resp.statusText} (${await resp.text()})` @@ -132,7 +134,7 @@ class SpiceClient { params.granularity = granularity; } - const resp = await this.fetch(`/v0.1/prices/${pair}`, params); + const resp = await this.fetchInternal(`/v0.1/prices/${pair}`, params); if (!resp.ok) { throw new Error( `Failed to get prices: ${resp.statusText} (${await resp.text()})` @@ -145,42 +147,43 @@ class SpiceClient { public async getMultiplePrices( convert: string, symbols: string[] - ): Promise { - if (symbols?.length < 1) { - throw new Error('At least 1 symbol is required'); - } + ): Promise { + if (symbols?.length < 1) { + throw new Error('At least 1 symbol is required'); + } - // Defaults to USD if no conversion symbol provided - if (!convert) { - convert = 'USD'; - } + // Defaults to USD if no conversion symbol provided + if (!convert) { + convert = 'USD'; + } - const asyncMultiplePricesRequest : AsyncMultiplePricesRequest = { - symbols: symbols, - convert: convert - }; - - const prices = await fetch(`${HTTP_DATA_PATH}/v0.1/prices`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Accept-Encoding': 'br, gzip, deflate', - 'X-API-Key': this._apiKey, - }, - body: JSON.stringify(asyncMultiplePricesRequest), - }); + const asyncMultiplePricesRequest: AsyncMultiplePricesRequest = { + symbols: symbols, + convert: convert, + }; - if (!prices.ok) { - throw new Error( - `Failed to get prices: ${prices.status} ${ - prices.statusText - } ${await prices.text()}` - ); - } + const prices = await fetch(`${HTTP_DATA_PATH}/v0.1/prices`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Accept-Encoding': 'br, gzip, deflate', + 'X-API-Key': this._apiKey, + }, + body: JSON.stringify(asyncMultiplePricesRequest), + agent: httpsAgent, + }); - return prices.json() as Promise; + if (!prices.ok) { + throw new Error( + `Failed to get prices: ${prices.status} ${ + prices.statusText + } ${await prices.text()}` + ); } + return prices.json() as Promise; + } + public async query( queryText: string, onData: ((data: Table) => void) | undefined = undefined @@ -240,6 +243,7 @@ class SpiceClient { 'X-API-Key': this._apiKey, }, body: JSON.stringify(asyncQueryRequest), + agent: httpsAgent, }); if (!resp.ok) { @@ -281,7 +285,7 @@ class SpiceClient { } } - const resp = await this.fetch(`/v0.1/sql/${queryId}`, params); + const resp = await this.fetchInternal(`/v0.1/sql/${queryId}`, params); if (!resp.ok) { throw new Error( `Failed to get query results: ${resp.status} ${ @@ -343,7 +347,10 @@ class SpiceClient { return await this.getQueryResultsAll(notification.queryId); } - private fetch = async (path: string, params?: { [key: string]: string }) => { + private fetchInternal = async ( + path: string, + params?: { [key: string]: string } + ) => { let url; if (params && Object.keys(params).length) { url = `${HTTP_DATA_PATH}${path}?${new URLSearchParams(params)}`; @@ -357,6 +364,7 @@ class SpiceClient { 'Accept-Encoding': 'br, gzip, deflate', 'X-API-Key': this._apiKey, }, + agent: httpsAgent, }); }; } diff --git a/test/client.test.ts b/test/client.test.ts index 82b22c7..d2b8bdb 100644 --- a/test/client.test.ts +++ b/test/client.test.ts @@ -179,20 +179,16 @@ test('test historical prices works', async () => { expect(prices.prices[23].price).toEqual(16612.22); }); - test('test get multiple prices works, when convert is provided and symbols array is not empty', async () => { - var symbolsText = ["cbETH", "stETH", "rETH"]; - const multiplePrices1 = await client.getMultiplePrices( - 'AUD', - symbolsText - ); + var symbolsText = ['ETH', 'LTC']; + const multiplePrices1 = await client.getMultiplePrices('ETH', symbolsText); expect(multiplePrices1).toBeTruthy(); - expect(multiplePrices1[0].pair).toEqual("CBETH-AUD"); + expect(multiplePrices1[0].pair).toEqual('ETH-ETH'); expect(multiplePrices1[0].minPrice).toBeTruthy; expect(multiplePrices1[0].maxPrice).toBeTruthy; expect(multiplePrices1[0].avePrice).toBeTruthy; - expect(multiplePrices1[1].pair).toEqual("STETH-AUD"); + expect(multiplePrices1[1].pair).toEqual('LTC-ETH'); expect(multiplePrices1[1].minPrice).toBeTruthy; expect(multiplePrices1[1].maxPrice).toBeTruthy; expect(multiplePrices1[1].avePrice).toBeTruthy; @@ -200,18 +196,15 @@ test('test get multiple prices works, when convert is provided and symbols array }); test('test get multiple prices works, when convert is not provided and symbols array is not empty', async () => { - var symbolsText = ["cbETH", "stETH", "rETH"]; - const multiplePrices2 = await client.getMultiplePrices( - '', - symbolsText - ); + const symbolsText = ['ETH', 'LTC']; + const multiplePrices2 = await client.getMultiplePrices('', symbolsText); expect(multiplePrices2).toBeTruthy(); - expect(multiplePrices2[0].pair).toEqual("CBETH-USD"); + expect(multiplePrices2[0].pair).toEqual('ETH-USD'); expect(multiplePrices2[0].minPrice).toBeTruthy; expect(multiplePrices2[0].maxPrice).toBeTruthy; expect(multiplePrices2[0].avePrice).toBeTruthy; - expect(multiplePrices2[1].pair).toEqual("STETH-USD"); + expect(multiplePrices2[1].pair).toEqual('LTC-USD'); expect(multiplePrices2[1].minPrice).toBeTruthy; expect(multiplePrices2[1].maxPrice).toBeTruthy; expect(multiplePrices2[1].avePrice).toBeTruthy; @@ -219,7 +212,7 @@ test('test get multiple prices works, when convert is not provided and symbols a }); test('test get multiple prices works, when symbols is an empty array', async () => { - expect(async() => { - await client.getMultiplePrices('', []) - }).rejects.toThrow('At least 1 symbol is required') -}); \ No newline at end of file + expect(async () => { + await client.getMultiplePrices('', []); + }).rejects.toThrow('At least 1 symbol is required'); +});