1+ import { queue } from 'async' ;
12import * as needle from 'needle' ;
23import { NeedleResponse , NeedleHttpVerbs , NeedleOptions } from 'needle' ;
34import * as sleep from 'sleep-promise' ;
@@ -14,15 +15,37 @@ import {
1415} from './types' ;
1516import { getProxyAgent } from './proxy' ;
1617
18+ interface HomebaseRequest {
19+ method : NeedleHttpVerbs ;
20+ url : string ;
21+ payload :
22+ IDependencyGraphPayload |
23+ ScanResultsPayload |
24+ IWorkloadMetadataPayload |
25+ IDeleteWorkloadPayload ;
26+ }
27+
1728const upstreamUrl = config . INTEGRATION_API || config . DEFAULT_KUBERNETES_UPSTREAM_URL ;
1829
30+ // Async queue wraps around the call to retryRequest in order to limit
31+ // the number of requests in flight to Homebase at any one time.
32+ const reqQueue = queue ( async function ( req : HomebaseRequest ) {
33+ return await retryRequest ( req . method , req . url , req . payload ) ;
34+ } , config . REQUEST_QUEUE_LENGTH ) ;
35+
1936export async function sendDepGraph ( ...payloads : IDependencyGraphPayload [ ] ) : Promise < void > {
2037 for ( const payload of payloads ) {
2138 // Intentionally removing dependencyGraph as it would be too big to log
2239 // eslint-disable-next-line @typescript-eslint/no-unused-vars
2340 const { dependencyGraph, ...payloadWithoutDepGraph } = payload ;
2441 try {
25- const { response, attempt} = await retryRequest ( 'post' , `${ upstreamUrl } /api/v1/dependency-graph` , payload ) ;
42+ const request : HomebaseRequest = {
43+ method : 'post' ,
44+ url : `${ upstreamUrl } /api/v1/dependency-graph` ,
45+ payload : payload ,
46+ } ;
47+
48+ const { response, attempt } = await reqQueue . pushAsync ( request ) ;
2649 if ( ! isSuccessStatusCode ( response . statusCode ) ) {
2750 throw new Error ( `${ response . statusCode } ${ response . statusMessage } ` ) ;
2851 } else {
@@ -40,7 +63,13 @@ export async function sendScanResults(payloads: ScanResultsPayload[]): Promise<b
4063 // eslint-disable-next-line @typescript-eslint/no-unused-vars
4164 const { scanResults, ...payloadWithoutScanResults } = payload ;
4265 try {
43- const { response, attempt} = await retryRequest ( 'post' , `${ upstreamUrl } /api/v1/scan-results` , payload ) ;
66+ const request : HomebaseRequest = {
67+ method : 'post' ,
68+ url : `${ upstreamUrl } /api/v1/scan-results` ,
69+ payload : payload ,
70+ } ;
71+
72+ const { response, attempt } = await reqQueue . pushAsync ( request ) ;
4473 if ( ! isSuccessStatusCode ( response . statusCode ) ) {
4574 throw new Error ( `${ response . statusCode } ${ response . statusMessage } ` ) ;
4675 } else {
@@ -59,7 +88,13 @@ export async function sendWorkloadMetadata(payload: IWorkloadMetadataPayload): P
5988 try {
6089 logger . info ( { workloadLocator : payload . workloadLocator } , 'attempting to send workload metadata upstream' ) ;
6190
62- const { response, attempt} = await retryRequest ( 'post' , `${ upstreamUrl } /api/v1/workload` , payload ) ;
91+ const request : HomebaseRequest = {
92+ method : 'post' ,
93+ url : `${ upstreamUrl } /api/v1/workload` ,
94+ payload : payload ,
95+ } ;
96+
97+ const { response, attempt } = await reqQueue . pushAsync ( request ) ;
6398 if ( ! isSuccessStatusCode ( response . statusCode ) ) {
6499 throw new Error ( `${ response . statusCode } ${ response . statusMessage } ` ) ;
65100 } else {
@@ -96,7 +131,13 @@ export async function sendWorkloadAutoImportPolicy(payload: WorkloadAutoImportPo
96131
97132export async function deleteWorkload ( payload : IDeleteWorkloadPayload ) : Promise < void > {
98133 try {
99- const { response, attempt} = await retryRequest ( 'delete' , `${ upstreamUrl } /api/v1/workload` , payload ) ;
134+ const request : HomebaseRequest = {
135+ method : 'delete' ,
136+ url : `${ upstreamUrl } /api/v1/workload` ,
137+ payload : payload ,
138+ } ;
139+
140+ const { response, attempt } = await reqQueue . pushAsync ( request ) ;
100141 if ( response . statusCode === 404 ) {
101142 // TODO: maybe we're still building it?
102143 const msg = 'attempted to delete a workload the Upstream service could not find' ;
0 commit comments