Merge branch 'main' of github.com:ghostfolio/ghostfolio
All checks were successful
Docker image CD / build_and_push (push) Successful in 14m0s
All checks were successful
Docker image CD / build_and_push (push) Successful in 14m0s
This commit is contained in:
commit
48a0a28d23
@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Deactivated asset profiles automatically on delisting in the _Yahoo Finance_ service
|
||||||
|
|
||||||
## 2.151.0 - 2025-04-11
|
## 2.151.0 - 2025-04-11
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@ -9,8 +9,8 @@ import { DataGatheringService } from '@ghostfolio/api/services/queues/data-gathe
|
|||||||
import {
|
import {
|
||||||
DATA_GATHERING_QUEUE_PRIORITY_HIGH,
|
DATA_GATHERING_QUEUE_PRIORITY_HIGH,
|
||||||
DATA_GATHERING_QUEUE_PRIORITY_MEDIUM,
|
DATA_GATHERING_QUEUE_PRIORITY_MEDIUM,
|
||||||
GATHER_ASSET_PROFILE_PROCESS,
|
GATHER_ASSET_PROFILE_PROCESS_JOB_NAME,
|
||||||
GATHER_ASSET_PROFILE_PROCESS_OPTIONS
|
GATHER_ASSET_PROFILE_PROCESS_JOB_OPTIONS
|
||||||
} from '@ghostfolio/common/config';
|
} from '@ghostfolio/common/config';
|
||||||
import { getAssetProfileIdentifier } from '@ghostfolio/common/helper';
|
import { getAssetProfileIdentifier } from '@ghostfolio/common/helper';
|
||||||
import {
|
import {
|
||||||
@ -92,9 +92,9 @@ export class AdminController {
|
|||||||
dataSource,
|
dataSource,
|
||||||
symbol
|
symbol
|
||||||
},
|
},
|
||||||
name: GATHER_ASSET_PROFILE_PROCESS,
|
name: GATHER_ASSET_PROFILE_PROCESS_JOB_NAME,
|
||||||
opts: {
|
opts: {
|
||||||
...GATHER_ASSET_PROFILE_PROCESS_OPTIONS,
|
...GATHER_ASSET_PROFILE_PROCESS_JOB_OPTIONS,
|
||||||
jobId: getAssetProfileIdentifier({ dataSource, symbol }),
|
jobId: getAssetProfileIdentifier({ dataSource, symbol }),
|
||||||
priority: DATA_GATHERING_QUEUE_PRIORITY_MEDIUM
|
priority: DATA_GATHERING_QUEUE_PRIORITY_MEDIUM
|
||||||
}
|
}
|
||||||
@ -119,9 +119,9 @@ export class AdminController {
|
|||||||
dataSource,
|
dataSource,
|
||||||
symbol
|
symbol
|
||||||
},
|
},
|
||||||
name: GATHER_ASSET_PROFILE_PROCESS,
|
name: GATHER_ASSET_PROFILE_PROCESS_JOB_NAME,
|
||||||
opts: {
|
opts: {
|
||||||
...GATHER_ASSET_PROFILE_PROCESS_OPTIONS,
|
...GATHER_ASSET_PROFILE_PROCESS_JOB_OPTIONS,
|
||||||
jobId: getAssetProfileIdentifier({ dataSource, symbol }),
|
jobId: getAssetProfileIdentifier({ dataSource, symbol }),
|
||||||
priority: DATA_GATHERING_QUEUE_PRIORITY_MEDIUM
|
priority: DATA_GATHERING_QUEUE_PRIORITY_MEDIUM
|
||||||
}
|
}
|
||||||
@ -142,9 +142,9 @@ export class AdminController {
|
|||||||
dataSource,
|
dataSource,
|
||||||
symbol
|
symbol
|
||||||
},
|
},
|
||||||
name: GATHER_ASSET_PROFILE_PROCESS,
|
name: GATHER_ASSET_PROFILE_PROCESS_JOB_NAME,
|
||||||
opts: {
|
opts: {
|
||||||
...GATHER_ASSET_PROFILE_PROCESS_OPTIONS,
|
...GATHER_ASSET_PROFILE_PROCESS_JOB_OPTIONS,
|
||||||
jobId: getAssetProfileIdentifier({ dataSource, symbol }),
|
jobId: getAssetProfileIdentifier({ dataSource, symbol }),
|
||||||
priority: DATA_GATHERING_QUEUE_PRIORITY_HIGH
|
priority: DATA_GATHERING_QUEUE_PRIORITY_HIGH
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,8 @@ import { DataGatheringService } from '@ghostfolio/api/services/queues/data-gathe
|
|||||||
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service';
|
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service';
|
||||||
import {
|
import {
|
||||||
DATA_GATHERING_QUEUE_PRIORITY_HIGH,
|
DATA_GATHERING_QUEUE_PRIORITY_HIGH,
|
||||||
GATHER_ASSET_PROFILE_PROCESS,
|
GATHER_ASSET_PROFILE_PROCESS_JOB_NAME,
|
||||||
GATHER_ASSET_PROFILE_PROCESS_OPTIONS
|
GATHER_ASSET_PROFILE_PROCESS_JOB_OPTIONS
|
||||||
} from '@ghostfolio/common/config';
|
} from '@ghostfolio/common/config';
|
||||||
import { getAssetProfileIdentifier } from '@ghostfolio/common/helper';
|
import { getAssetProfileIdentifier } from '@ghostfolio/common/helper';
|
||||||
import {
|
import {
|
||||||
@ -144,9 +144,9 @@ export class OrderService {
|
|||||||
dataSource: data.SymbolProfile.connectOrCreate.create.dataSource,
|
dataSource: data.SymbolProfile.connectOrCreate.create.dataSource,
|
||||||
symbol: data.SymbolProfile.connectOrCreate.create.symbol
|
symbol: data.SymbolProfile.connectOrCreate.create.symbol
|
||||||
},
|
},
|
||||||
name: GATHER_ASSET_PROFILE_PROCESS,
|
name: GATHER_ASSET_PROFILE_PROCESS_JOB_NAME,
|
||||||
opts: {
|
opts: {
|
||||||
...GATHER_ASSET_PROFILE_PROCESS_OPTIONS,
|
...GATHER_ASSET_PROFILE_PROCESS_JOB_OPTIONS,
|
||||||
jobId: getAssetProfileIdentifier({
|
jobId: getAssetProfileIdentifier({
|
||||||
dataSource: data.SymbolProfile.connectOrCreate.create.dataSource,
|
dataSource: data.SymbolProfile.connectOrCreate.create.dataSource,
|
||||||
symbol: data.SymbolProfile.connectOrCreate.create.symbol
|
symbol: data.SymbolProfile.connectOrCreate.create.symbol
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { UserService } from '@ghostfolio/api/app/user/user.service';
|
import { UserService } from '@ghostfolio/api/app/user/user.service';
|
||||||
import {
|
import {
|
||||||
DATA_GATHERING_QUEUE_PRIORITY_LOW,
|
DATA_GATHERING_QUEUE_PRIORITY_LOW,
|
||||||
GATHER_ASSET_PROFILE_PROCESS,
|
GATHER_ASSET_PROFILE_PROCESS_JOB_NAME,
|
||||||
GATHER_ASSET_PROFILE_PROCESS_OPTIONS,
|
GATHER_ASSET_PROFILE_PROCESS_JOB_OPTIONS,
|
||||||
PROPERTY_IS_DATA_GATHERING_ENABLED
|
PROPERTY_IS_DATA_GATHERING_ENABLED
|
||||||
} from '@ghostfolio/common/config';
|
} from '@ghostfolio/common/config';
|
||||||
import { getAssetProfileIdentifier } from '@ghostfolio/common/helper';
|
import { getAssetProfileIdentifier } from '@ghostfolio/common/helper';
|
||||||
@ -66,9 +66,9 @@ export class CronService {
|
|||||||
dataSource,
|
dataSource,
|
||||||
symbol
|
symbol
|
||||||
},
|
},
|
||||||
name: GATHER_ASSET_PROFILE_PROCESS,
|
name: GATHER_ASSET_PROFILE_PROCESS_JOB_NAME,
|
||||||
opts: {
|
opts: {
|
||||||
...GATHER_ASSET_PROFILE_PROCESS_OPTIONS,
|
...GATHER_ASSET_PROFILE_PROCESS_JOB_OPTIONS,
|
||||||
jobId: getAssetProfileIdentifier({ dataSource, symbol }),
|
jobId: getAssetProfileIdentifier({ dataSource, symbol }),
|
||||||
priority: DATA_GATHERING_QUEUE_PRIORITY_LOW
|
priority: DATA_GATHERING_QUEUE_PRIORITY_LOW
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { CryptocurrencyService } from '@ghostfolio/api/services/cryptocurrency/cryptocurrency.service';
|
import { CryptocurrencyService } from '@ghostfolio/api/services/cryptocurrency/cryptocurrency.service';
|
||||||
|
import { AssetProfileDelistedError } from '@ghostfolio/api/services/data-provider/errors/asset-profile-delisted.error';
|
||||||
import { DataEnhancerInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-enhancer.interface';
|
import { DataEnhancerInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-enhancer.interface';
|
||||||
import {
|
import {
|
||||||
DEFAULT_CURRENCY,
|
DEFAULT_CURRENCY,
|
||||||
@ -236,7 +237,13 @@ export class YahooFinanceDataEnhancerService implements DataEnhancerInterface {
|
|||||||
response.url = url;
|
response.url = url;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.error(error, 'YahooFinanceService');
|
if (error.message === `Quote not found for symbol: ${aSymbol}`) {
|
||||||
|
throw new AssetProfileDelistedError(
|
||||||
|
`No data found, ${aSymbol} (${this.getName()}) may be delisted`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Logger.error(error, 'YahooFinanceService');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
|
@ -114,7 +114,13 @@ export class DataProviderService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await Promise.all(promises);
|
try {
|
||||||
|
await Promise.all(promises);
|
||||||
|
} catch (error) {
|
||||||
|
Logger.error(error, 'DataProviderService');
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
export class AssetProfileDelistedError extends Error {
|
||||||
|
public constructor(message: string) {
|
||||||
|
super(message);
|
||||||
|
|
||||||
|
this.name = 'AssetProfileDelistedError';
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
import { CryptocurrencyService } from '@ghostfolio/api/services/cryptocurrency/cryptocurrency.service';
|
import { CryptocurrencyService } from '@ghostfolio/api/services/cryptocurrency/cryptocurrency.service';
|
||||||
import { YahooFinanceDataEnhancerService } from '@ghostfolio/api/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service';
|
import { YahooFinanceDataEnhancerService } from '@ghostfolio/api/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service';
|
||||||
|
import { AssetProfileDelistedError } from '@ghostfolio/api/services/data-provider/errors/asset-profile-delisted.error';
|
||||||
import {
|
import {
|
||||||
DataProviderInterface,
|
DataProviderInterface,
|
||||||
GetAssetProfileParams,
|
GetAssetProfileParams,
|
||||||
@ -143,12 +144,18 @@ export class YahooFinanceService implements DataProviderInterface {
|
|||||||
|
|
||||||
return response;
|
return response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(
|
if (error.message === 'No data found, symbol may be delisted') {
|
||||||
`Could not get historical market data for ${symbol} (${this.getName()}) from ${format(
|
throw new AssetProfileDelistedError(
|
||||||
from,
|
`No data found, ${symbol} (${this.getName()}) may be delisted`
|
||||||
DATE_FORMAT
|
);
|
||||||
)} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}`
|
} else {
|
||||||
);
|
throw new Error(
|
||||||
|
`Could not get historical market data for ${symbol} (${this.getName()}) from ${format(
|
||||||
|
from,
|
||||||
|
DATE_FORMAT
|
||||||
|
)} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}`
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
|
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
|
||||||
|
import { AssetProfileDelistedError } from '@ghostfolio/api/services/data-provider/errors/asset-profile-delisted.error';
|
||||||
import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
|
import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
|
||||||
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
|
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
|
||||||
|
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service';
|
||||||
import {
|
import {
|
||||||
DATA_GATHERING_QUEUE,
|
DATA_GATHERING_QUEUE,
|
||||||
DEFAULT_PROCESSOR_GATHER_ASSET_PROFILE_CONCURRENCY,
|
DEFAULT_PROCESSOR_GATHER_ASSET_PROFILE_CONCURRENCY,
|
||||||
DEFAULT_PROCESSOR_GATHER_HISTORICAL_MARKET_DATA_CONCURRENCY,
|
DEFAULT_PROCESSOR_GATHER_HISTORICAL_MARKET_DATA_CONCURRENCY,
|
||||||
GATHER_ASSET_PROFILE_PROCESS,
|
GATHER_ASSET_PROFILE_PROCESS_JOB_NAME,
|
||||||
GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME
|
GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME
|
||||||
} from '@ghostfolio/common/config';
|
} from '@ghostfolio/common/config';
|
||||||
import { DATE_FORMAT, getStartOfUtcDate } from '@ghostfolio/common/helper';
|
import { DATE_FORMAT, getStartOfUtcDate } from '@ghostfolio/common/helper';
|
||||||
@ -33,7 +35,8 @@ export class DataGatheringProcessor {
|
|||||||
public constructor(
|
public constructor(
|
||||||
private readonly dataGatheringService: DataGatheringService,
|
private readonly dataGatheringService: DataGatheringService,
|
||||||
private readonly dataProviderService: DataProviderService,
|
private readonly dataProviderService: DataProviderService,
|
||||||
private readonly marketDataService: MarketDataService
|
private readonly marketDataService: MarketDataService,
|
||||||
|
private readonly symbolProfileService: SymbolProfileService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Process({
|
@Process({
|
||||||
@ -42,28 +45,49 @@ export class DataGatheringProcessor {
|
|||||||
DEFAULT_PROCESSOR_GATHER_ASSET_PROFILE_CONCURRENCY.toString(),
|
DEFAULT_PROCESSOR_GATHER_ASSET_PROFILE_CONCURRENCY.toString(),
|
||||||
10
|
10
|
||||||
),
|
),
|
||||||
name: GATHER_ASSET_PROFILE_PROCESS
|
name: GATHER_ASSET_PROFILE_PROCESS_JOB_NAME
|
||||||
})
|
})
|
||||||
public async gatherAssetProfile(job: Job<AssetProfileIdentifier>) {
|
public async gatherAssetProfile(job: Job<AssetProfileIdentifier>) {
|
||||||
|
const { dataSource, symbol } = job.data;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Logger.log(
|
Logger.log(
|
||||||
`Asset profile data gathering has been started for ${job.data.symbol} (${job.data.dataSource})`,
|
`Asset profile data gathering has been started for ${symbol} (${dataSource})`,
|
||||||
`DataGatheringProcessor (${GATHER_ASSET_PROFILE_PROCESS})`
|
`DataGatheringProcessor (${GATHER_ASSET_PROFILE_PROCESS_JOB_NAME})`
|
||||||
);
|
);
|
||||||
|
|
||||||
await this.dataGatheringService.gatherAssetProfiles([job.data]);
|
await this.dataGatheringService.gatherAssetProfiles([job.data]);
|
||||||
|
|
||||||
Logger.log(
|
Logger.log(
|
||||||
`Asset profile data gathering has been completed for ${job.data.symbol} (${job.data.dataSource})`,
|
`Asset profile data gathering has been completed for ${symbol} (${dataSource})`,
|
||||||
`DataGatheringProcessor (${GATHER_ASSET_PROFILE_PROCESS})`
|
`DataGatheringProcessor (${GATHER_ASSET_PROFILE_PROCESS_JOB_NAME})`
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
if (error instanceof AssetProfileDelistedError) {
|
||||||
|
await this.symbolProfileService.updateSymbolProfile(
|
||||||
|
{
|
||||||
|
dataSource,
|
||||||
|
symbol
|
||||||
|
},
|
||||||
|
{
|
||||||
|
isActive: false
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Logger.log(
|
||||||
|
`Asset profile data gathering has been discarded for ${symbol} (${dataSource})`,
|
||||||
|
`DataGatheringProcessor (${GATHER_ASSET_PROFILE_PROCESS_JOB_NAME})`
|
||||||
|
);
|
||||||
|
|
||||||
|
return job.discard();
|
||||||
|
}
|
||||||
|
|
||||||
Logger.error(
|
Logger.error(
|
||||||
error,
|
error,
|
||||||
`DataGatheringProcessor (${GATHER_ASSET_PROFILE_PROCESS})`
|
`DataGatheringProcessor (${GATHER_ASSET_PROFILE_PROCESS_JOB_NAME})`
|
||||||
);
|
);
|
||||||
|
|
||||||
throw new Error(error);
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,8 +100,9 @@ export class DataGatheringProcessor {
|
|||||||
name: GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME
|
name: GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME
|
||||||
})
|
})
|
||||||
public async gatherHistoricalMarketData(job: Job<IDataGatheringItem>) {
|
public async gatherHistoricalMarketData(job: Job<IDataGatheringItem>) {
|
||||||
|
const { dataSource, date, symbol } = job.data;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { dataSource, date, symbol } = job.data;
|
|
||||||
let currentDate = parseISO(date as unknown as string);
|
let currentDate = parseISO(date as unknown as string);
|
||||||
|
|
||||||
Logger.log(
|
Logger.log(
|
||||||
@ -142,12 +167,31 @@ export class DataGatheringProcessor {
|
|||||||
`DataGatheringProcessor (${GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME})`
|
`DataGatheringProcessor (${GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME})`
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
if (error instanceof AssetProfileDelistedError) {
|
||||||
|
await this.symbolProfileService.updateSymbolProfile(
|
||||||
|
{
|
||||||
|
dataSource,
|
||||||
|
symbol
|
||||||
|
},
|
||||||
|
{
|
||||||
|
isActive: false
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Logger.log(
|
||||||
|
`Historical market data gathering has been discarded for ${symbol} (${dataSource})`,
|
||||||
|
`DataGatheringProcessor (${GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME})`
|
||||||
|
);
|
||||||
|
|
||||||
|
return job.discard();
|
||||||
|
}
|
||||||
|
|
||||||
Logger.error(
|
Logger.error(
|
||||||
error,
|
error,
|
||||||
`DataGatheringProcessor (${GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME})`
|
`DataGatheringProcessor (${GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME})`
|
||||||
);
|
);
|
||||||
|
|
||||||
throw new Error(error);
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,9 @@
|
|||||||
<button
|
<button
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
type="button"
|
type="button"
|
||||||
[disabled]="assetProfileForm.dirty"
|
[disabled]="
|
||||||
|
assetProfileForm.dirty || !assetProfileForm.controls.isActive.value
|
||||||
|
"
|
||||||
(click)="
|
(click)="
|
||||||
onGatherSymbol({ dataSource: data.dataSource, symbol: data.symbol })
|
onGatherSymbol({ dataSource: data.dataSource, symbol: data.symbol })
|
||||||
"
|
"
|
||||||
@ -29,7 +31,9 @@
|
|||||||
<button
|
<button
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
type="button"
|
type="button"
|
||||||
[disabled]="assetProfileForm.dirty"
|
[disabled]="
|
||||||
|
assetProfileForm.dirty || !assetProfileForm.controls.isActive.value
|
||||||
|
"
|
||||||
(click)="
|
(click)="
|
||||||
onGatherProfileDataBySymbol({
|
onGatherProfileDataBySymbol({
|
||||||
dataSource: data.dataSource,
|
dataSource: data.dataSource,
|
||||||
|
@ -78,8 +78,8 @@ export const DERIVED_CURRENCIES = [
|
|||||||
|
|
||||||
export const EMERGENCY_FUND_TAG_ID = '4452656d-9fa4-4bd0-ba38-70492e31d180';
|
export const EMERGENCY_FUND_TAG_ID = '4452656d-9fa4-4bd0-ba38-70492e31d180';
|
||||||
|
|
||||||
export const GATHER_ASSET_PROFILE_PROCESS = 'GATHER_ASSET_PROFILE';
|
export const GATHER_ASSET_PROFILE_PROCESS_JOB_NAME = 'GATHER_ASSET_PROFILE';
|
||||||
export const GATHER_ASSET_PROFILE_PROCESS_OPTIONS: JobOptions = {
|
export const GATHER_ASSET_PROFILE_PROCESS_JOB_OPTIONS: JobOptions = {
|
||||||
attempts: 12,
|
attempts: 12,
|
||||||
backoff: {
|
backoff: {
|
||||||
delay: ms('1 minute'),
|
delay: ms('1 minute'),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user