Merge pull request #2661 from 0xProject/feature/keepAlive

added keepAlive
This commit is contained in:
Daniel Pyrathon 2020-08-10 21:12:20 -07:00 committed by GitHub
commit ece93fed78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 100 additions and 77 deletions

View File

@ -56,7 +56,7 @@
"@0x/quote-server": "^2.0.2", "@0x/quote-server": "^2.0.2",
"@0x/utils": "^5.5.1", "@0x/utils": "^5.5.1",
"@0x/web3-wrapper": "^7.2.0", "@0x/web3-wrapper": "^7.2.0",
"@balancer-labs/sor": "^0.3.0", "@balancer-labs/sor": "0.3.2",
"axios": "^0.19.2", "axios": "^0.19.2",
"axios-mock-adapter": "^1.18.1", "axios-mock-adapter": "^1.18.1",
"decimal.js": "^10.2.0", "decimal.js": "^10.2.0",

View File

@ -101,3 +101,5 @@ export { QuoteRequestor } from './utils/quote_requestor';
export { rfqtMocker } from './utils/rfqt_mocker'; export { rfqtMocker } from './utils/rfqt_mocker';
import { ERC20BridgeSource } from './utils/market_operation_utils/types'; import { ERC20BridgeSource } from './utils/market_operation_utils/types';
export type Native = ERC20BridgeSource.Native; export type Native = ERC20BridgeSource.Native;
export { AxiosInstance } from 'axios';

View File

@ -3,11 +3,18 @@ import { assetDataUtils, orderCalculationUtils, orderHashUtils, SignedOrder } fr
import { RFQTFirmQuote, RFQTIndicativeQuote, TakerRequest } from '@0x/quote-server'; import { RFQTFirmQuote, RFQTIndicativeQuote, TakerRequest } from '@0x/quote-server';
import { ERC20AssetData } from '@0x/types'; import { ERC20AssetData } from '@0x/types';
import { BigNumber, logUtils } from '@0x/utils'; import { BigNumber, logUtils } from '@0x/utils';
import Axios from 'axios'; import Axios, { AxiosInstance } from 'axios';
import { Agent as HttpAgent } from 'http';
import { Agent as HttpsAgent } from 'https';
import { constants } from '../constants'; import { constants } from '../constants';
import { MarketOperation, RfqtMakerAssetOfferings, RfqtRequestOpts } from '../types'; import { MarketOperation, RfqtMakerAssetOfferings, RfqtRequestOpts } from '../types';
export const quoteRequestorHttpClient: AxiosInstance = Axios.create({
httpAgent: new HttpAgent({ keepAlive: true }),
httpsAgent: new HttpsAgent({ keepAlive: true }),
});
/** /**
* Request quotes from RFQ-T providers * Request quotes from RFQ-T providers
*/ */
@ -330,7 +337,7 @@ export class QuoteRequestor {
throw new Error(`Unexpected quote type ${quoteType}`); throw new Error(`Unexpected quote type ${quoteType}`);
} }
})(); })();
const response = await Axios.get<ResponseT>(`${url}/${quotePath}`, { const response = await quoteRequestorHttpClient.get<ResponseT>(`${url}/${quotePath}`, {
headers: { '0x-api-key': options.apiKey }, headers: { '0x-api-key': options.apiKey },
params: requestParams, params: requestParams,
timeout: options.makerEndpointMaxResponseTimeMs, timeout: options.makerEndpointMaxResponseTimeMs,

View File

@ -1,4 +1,4 @@
import axios from 'axios'; import axios, { AxiosInstance } from 'axios';
import AxiosMockAdapter from 'axios-mock-adapter'; import AxiosMockAdapter from 'axios-mock-adapter';
import { MockedRfqtFirmQuoteResponse } from '../types'; import { MockedRfqtFirmQuoteResponse } from '../types';
@ -16,8 +16,9 @@ export const rfqtMocker = {
withMockedRfqtFirmQuotes: async ( withMockedRfqtFirmQuotes: async (
mockedResponses: MockedRfqtFirmQuoteResponse[], mockedResponses: MockedRfqtFirmQuoteResponse[],
performFn: () => Promise<void>, performFn: () => Promise<void>,
axiosClient: AxiosInstance = axios,
) => { ) => {
const mockedAxios = new AxiosMockAdapter(axios); const mockedAxios = new AxiosMockAdapter(axiosClient);
try { try {
// Mock out RFQT responses // Mock out RFQT responses
for (const mockedResponse of mockedResponses) { for (const mockedResponse of mockedResponses) {
@ -37,8 +38,9 @@ export const rfqtMocker = {
withMockedRfqtIndicativeQuotes: async ( withMockedRfqtIndicativeQuotes: async (
mockedResponses: MockedRfqtFirmQuoteResponse[], mockedResponses: MockedRfqtFirmQuoteResponse[],
performFn: () => Promise<void>, performFn: () => Promise<void>,
axiosClient: AxiosInstance = axios,
) => { ) => {
const mockedAxios = new AxiosMockAdapter(axios); const mockedAxios = new AxiosMockAdapter(axiosClient);
try { try {
// Mock out RFQT responses // Mock out RFQT responses
for (const mockedResponse of mockedResponses) { for (const mockedResponse of mockedResponses) {

View File

@ -7,7 +7,7 @@ import 'mocha';
import { constants } from '../src/constants'; import { constants } from '../src/constants';
import { MarketOperation, MockedRfqtFirmQuoteResponse, MockedRfqtIndicativeQuoteResponse } from '../src/types'; import { MarketOperation, MockedRfqtFirmQuoteResponse, MockedRfqtIndicativeQuoteResponse } from '../src/types';
import { QuoteRequestor } from '../src/utils/quote_requestor'; import { QuoteRequestor, quoteRequestorHttpClient } from '../src/utils/quote_requestor';
import { rfqtMocker } from '../src/utils/rfqt_mocker'; import { rfqtMocker } from '../src/utils/rfqt_mocker';
import { chaiSetup } from './utils/chai_setup'; import { chaiSetup } from './utils/chai_setup';
@ -153,35 +153,39 @@ describe('QuoteRequestor', async () => {
responseCode: StatusCodes.Success, responseCode: StatusCodes.Success,
}); });
return rfqtMocker.withMockedRfqtFirmQuotes(mockedRequests, async () => { return rfqtMocker.withMockedRfqtFirmQuotes(
const qr = new QuoteRequestor({ mockedRequests,
'https://1337.0.0.1': [[makerToken, takerToken]], async () => {
'https://420.0.0.1': [[makerToken, takerToken]], const qr = new QuoteRequestor({
'https://421.0.0.1': [[makerToken, takerToken]], 'https://1337.0.0.1': [[makerToken, takerToken]],
'https://421.1.0.1': [[makerToken, takerToken]], 'https://420.0.0.1': [[makerToken, takerToken]],
'https://422.0.0.1': [[makerToken, takerToken]], 'https://421.0.0.1': [[makerToken, takerToken]],
'https://423.0.0.1': [[makerToken, takerToken]], 'https://421.1.0.1': [[makerToken, takerToken]],
'https://424.0.0.1': [[makerToken, takerToken]], 'https://422.0.0.1': [[makerToken, takerToken]],
'https://425.0.0.1': [[makerToken, takerToken]], 'https://423.0.0.1': [[makerToken, takerToken]],
'https://426.0.0.1': [] /* Shouldn't ping an RFQ-T 'https://424.0.0.1': [[makerToken, takerToken]],
'https://425.0.0.1': [[makerToken, takerToken]],
'https://426.0.0.1': [] /* Shouldn't ping an RFQ-T
provider when they don't support the requested asset pair. */, provider when they don't support the requested asset pair. */,
'https://37.0.0.1': [[makerToken, takerToken]], 'https://37.0.0.1': [[makerToken, takerToken]],
}); });
const resp = await qr.requestRfqtFirmQuotesAsync( const resp = await qr.requestRfqtFirmQuotesAsync(
makerAssetData, makerAssetData,
takerAssetData, takerAssetData,
new BigNumber(10000), new BigNumber(10000),
MarketOperation.Sell, MarketOperation.Sell,
{ {
apiKey, apiKey,
takerAddress, takerAddress,
intentOnFilling: true, intentOnFilling: true,
}, },
); );
expect(resp.sort()).to.eql( expect(resp.sort()).to.eql(
[{ signedOrder: successfulOrder1 }, { signedOrder: successfulOrder2 }].sort(), [{ signedOrder: successfulOrder1 }, { signedOrder: successfulOrder2 }].sort(),
); );
}); },
quoteRequestorHttpClient,
);
}); });
}); });
describe('requestRfqtIndicativeQuotesAsync for Indicative quotes', async () => { describe('requestRfqtIndicativeQuotesAsync for Indicative quotes', async () => {
@ -255,29 +259,33 @@ describe('QuoteRequestor', async () => {
responseCode: StatusCodes.Success, responseCode: StatusCodes.Success,
}); });
return rfqtMocker.withMockedRfqtIndicativeQuotes(mockedRequests, async () => { return rfqtMocker.withMockedRfqtIndicativeQuotes(
const qr = new QuoteRequestor({ mockedRequests,
'https://1337.0.0.1': [[makerToken, takerToken]], async () => {
'https://420.0.0.1': [[makerToken, takerToken]], const qr = new QuoteRequestor({
'https://421.0.0.1': [[makerToken, takerToken]], 'https://1337.0.0.1': [[makerToken, takerToken]],
'https://422.0.0.1': [[makerToken, takerToken]], 'https://420.0.0.1': [[makerToken, takerToken]],
'https://423.0.0.1': [[makerToken, takerToken]], 'https://421.0.0.1': [[makerToken, takerToken]],
'https://424.0.0.1': [[makerToken, takerToken]], 'https://422.0.0.1': [[makerToken, takerToken]],
'https://37.0.0.1': [[makerToken, takerToken]], 'https://423.0.0.1': [[makerToken, takerToken]],
}); 'https://424.0.0.1': [[makerToken, takerToken]],
const resp = await qr.requestRfqtIndicativeQuotesAsync( 'https://37.0.0.1': [[makerToken, takerToken]],
makerAssetData, });
takerAssetData, const resp = await qr.requestRfqtIndicativeQuotesAsync(
new BigNumber(10000), makerAssetData,
MarketOperation.Sell, takerAssetData,
{ new BigNumber(10000),
apiKey, MarketOperation.Sell,
takerAddress, {
intentOnFilling: true, apiKey,
}, takerAddress,
); intentOnFilling: true,
expect(resp.sort()).to.eql([successfulQuote1, successfulQuote1].sort()); },
}); );
expect(resp.sort()).to.eql([successfulQuote1, successfulQuote1].sort());
},
quoteRequestorHttpClient,
);
}); });
it('should return successful RFQT indicative quote requests', async () => { it('should return successful RFQT indicative quote requests', async () => {
const takerAddress = '0xd209925defc99488e3afff1174e48b4fa628302a'; const takerAddress = '0xd209925defc99488e3afff1174e48b4fa628302a';
@ -309,21 +317,25 @@ describe('QuoteRequestor', async () => {
responseCode: StatusCodes.Success, responseCode: StatusCodes.Success,
}); });
return rfqtMocker.withMockedRfqtIndicativeQuotes(mockedRequests, async () => { return rfqtMocker.withMockedRfqtIndicativeQuotes(
const qr = new QuoteRequestor({ 'https://1337.0.0.1': [[makerToken, takerToken]] }); mockedRequests,
const resp = await qr.requestRfqtIndicativeQuotesAsync( async () => {
makerAssetData, const qr = new QuoteRequestor({ 'https://1337.0.0.1': [[makerToken, takerToken]] });
takerAssetData, const resp = await qr.requestRfqtIndicativeQuotesAsync(
new BigNumber(10000), makerAssetData,
MarketOperation.Buy, takerAssetData,
{ new BigNumber(10000),
apiKey, MarketOperation.Buy,
takerAddress, {
intentOnFilling: true, apiKey,
}, takerAddress,
); intentOnFilling: true,
expect(resp.sort()).to.eql([successfulQuote1].sort()); },
}); );
expect(resp.sort()).to.eql([successfulQuote1].sort());
},
quoteRequestorHttpClient,
);
}); });
}); });
}); });

View File

@ -1047,10 +1047,10 @@
lodash "^4.17.13" lodash "^4.17.13"
to-fast-properties "^2.0.0" to-fast-properties "^2.0.0"
"@balancer-labs/sor@^0.3.0": "@balancer-labs/sor@0.3.2":
version "0.3.0" version "0.3.2"
resolved "https://registry.yarnpkg.com/@balancer-labs/sor/-/sor-0.3.0.tgz#c221225d9a3d1791ebfc3c566f7a76843bca98fa" resolved "https://registry.yarnpkg.com/@balancer-labs/sor/-/sor-0.3.2.tgz#b05c63a07031c2ea13ed0d2670f5105cfaa40523"
integrity sha512-QTVkeDmcGCaEgBhcVSu8c7cz6HA1ueWRbniuT+Yh0N/sqcZIcDMdoCFcpq66SD+hOxQ88RvzShmJ+P/3vKbXfg== integrity sha512-wmYmTm/zhnRPd/OaqzJJGo9mRIp4PvNNS/AG0EVWJmLmZvYkm2sl6/dBL3KC88rub9duVQr2M8BHCosseFuGLw==
dependencies: dependencies:
bignumber.js "^9.0.0" bignumber.js "^9.0.0"
ethers "^4.0.39" ethers "^4.0.39"