/// Задача, в рамках которой производится расчет разницы между исходными и новыми данными
private var diffTask: Task<Void, Never>? = nil
@MainActor
func syncDiagrams(isResetValue isReset: Bool) {
// Завершаем процесс загрузки ранее запущенной задачи
syncTask?.cancel()
// Итерируем идентификатор
dataSerialNumber += 1
// Запоминаем для какой итерации мы проводим обновление
let serialNumber = dataSerialNumber
showInfo = false
// Копируем состояние, чтобы потом не столкнуться с проблемой записи+чтения
let oldInfluence = influence
let oldGroupList = groupList
let oldMonitoringType = monitoringType
let oldIncidentList = incidentList
let oldCoordinator = coordinator
// Запускаем новую задачу загрузки в фоновом режиме, НЕ на `main`
syncTask = Task.detached { [weak self] in
guard let self else { return }
var container: SBModelKit.SystemDiagramDataModel?
var syncError: Error?
do {
let idList: [Int]? = oldMonitoringType == .favorite ? nil : oldIncidentList.map { Int($0.configElementId) }
let isWithDeviation = (self.monitoringType == .deviation
&& oldIncidentList.isEmpty
&& oldInfluence.metricDeviations > 0)
? true : nil
let isFavorites = self.monitoringType == .favorite ? true : nil
let activeFilterList: [String]? = oldGroupList.first(where: { $0.content == .filter })?
.filterList.filter { $0.state == true }
.compactMap { $0.model.rawValue }
container = try await self.coordinator?.loadOn(
idList: idList,
isWithDeviation: isWithDeviation,
isFavorites: isFavorites,
metricOwnerList: activeFilterList?.isEmpty == false ? activeFilterList : nil
)
} catch {
syncError = error
}
guard Task.isCancelled == false else { return }
// Завершаем ранее запущенную задачу расчета разници, если она еще не завершилась
self.diffTask?.cancel()
// Запускаем новую задачу на расчет разници
self.diffTask = Task {
guard !Task.isCancelled else { return }
await self.handleDiagramResult(
container != nil ? .success(container!) : .failure(syncError ?? AppError.emptyData),
forDataSerialNumber: serialNumber,
oldGroupList: oldGroupList,
isNeedResetAllData: isReset,
incidentCount: oldIncidentList.count,
influence: oldInfluence
)
}
}
}