Browse Source
			
			
			Feature/execute scraper configuration instantly (#3723)
			
				* Execute scraper configuration instantly
* Update changelog
---------
Co-authored-by: Thomas Kaul <4159106+dtslvr@users.noreply.github.com>
			
			
				pull/3731/head
			
			
		 
		
			
				
					
						
						Shaunak Das
					
					1 year ago
					
						
							committed by
							
								
								GitHub
							
						 
					
				 
				
			 
		 
		
			
				
					
					No known key found for this signature in database
					
						
							GPG Key ID: B5690EEEBB952194
						
					
				
			
		
		
		
	
		
			
				 4 changed files with 
37 additions and 
2 deletions
			 
			
		 
		
			
				- 
					
					
					 
					CHANGELOG.md
				
 
			
				- 
					
					
					 
					apps/api/src/services/data-provider/manual/manual.service.ts
				
 
			
				- 
					
					
					 
					apps/api/src/services/symbol-profile/symbol-profile.service.ts
				
 
			
				- 
					
					
					 
					libs/common/src/lib/interfaces/scraper-configuration.interface.ts
				
 
			
		
		
			
			
			
			
			
			
				
				
					
						
							
								
									
	
		
			
				
					| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					### Added | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					- Set up a performance logging service | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					- Added the attribute `mode` to the scraper configuration to get quotes instantly | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					### Changed | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  | 
				
			
			
		
	
								
							
						
					 
					
				 
			 
		
			
			
			
			
			
			
				
				
					
						
							
								
									
	
		
			
				
					| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -166,11 +166,42 @@ export class ManualService implements DataProviderInterface { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      const symbolProfilesWithScraperConfigurationAndInstantMode = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        symbolProfiles.filter(({ scraperConfiguration }) => { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          return scraperConfiguration?.mode === 'instant'; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      const scraperResultPromises = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        symbolProfilesWithScraperConfigurationAndInstantMode.map( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          async ({ scraperConfiguration, symbol }) => { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            try { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              const marketPrice = await this.scrape(scraperConfiguration); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              return { marketPrice, symbol }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } catch (error) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              Logger.error( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                `Could not get quote for ${symbol} (${this.getName()}): [${error.name}] ${error.message}`, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                'ManualService' | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              return { symbol, marketPrice: undefined }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      // Wait for all scraping requests to complete concurrently
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      const scraperResults = await Promise.all(scraperResultPromises); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      for (const { currency, symbol } of symbolProfiles) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        let marketPrice = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        let { marketPrice } = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          scraperResults.find((result) => { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            return result.symbol === symbol; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          }) ?? {}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        marketPrice = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          marketPrice ?? | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          marketData.find((marketDataItem) => { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            return marketDataItem.symbol === symbol; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          })?.marketPrice ?? 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          })?.marketPrice ?? | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        response[symbol] = { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          currency, | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  | 
				
			
			
		
	
								
							
						
					 
					
				 
			 
		
			
			
			
			
			
			
				
				
					
						
							
								
									
	
		
			
				
					| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -275,6 +275,8 @@ export class SymbolProfileService { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        headers: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          scraperConfiguration.headers as ScraperConfiguration['headers'], | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        locale: scraperConfiguration.locale as string, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        mode: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          (scraperConfiguration.mode as ScraperConfiguration['mode']) ?? 'lazy', | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        selector: scraperConfiguration.selector as string, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        url: scraperConfiguration.url as string | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      }; | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  | 
				
			
			
		
	
								
							
						
					 
					
				 
			 
		
			
			
			
			
			
			
				
				
					
						
							
								
									
	
		
			
				
					| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -2,6 +2,7 @@ export interface ScraperConfiguration { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  defaultMarketPrice?: number; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  headers?: { [key: string]: string }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  locale?: string; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  mode?: 'instant' | 'lazy'; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  selector: string; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  url: string; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
					 | 
				
				 | 
				
					
  |