etreschenkov 2026-01-21 09:00:45 +03:00
parent 52d526757b
commit 0f2e41611a
11 changed files with 69 additions and 42 deletions

View file

@ -8,7 +8,7 @@ import ru.nbch.credit_tracker.entities.app.PhonesMap;
@Mapper @Mapper
public interface PhonesMapMapper { public interface PhonesMapMapper {
List<PhonesMap> getCachedData(@Param("phones") List<Long> phones); List<PhonesMap> getCachedData(@Param("phones") List<Long> phones);
List<PhonesMap> searchedAtLessThan(@Param("daysCount") Integer daysCount, @Param("limit") int limit, @Param("offset") int offset); List<PhonesMap> searchedAtLessThan(@Param("daysCount") Integer daysCount, @Param("batchSize") int batchSize, @Param("lastId") Long lastId);
PhonesMap findByPhone(@Param("phone") Long phone); PhonesMap findByPhone(@Param("phone") Long phone);
List<PhonesMap> findEligibleForFlagsUpdate(@Param("lastId") Long lastId, List<PhonesMap> findEligibleForFlagsUpdate(@Param("lastId") Long lastId,
@Param("batchSize") Integer batchSize); @Param("batchSize") Integer batchSize);
@ -16,6 +16,7 @@ public interface PhonesMapMapper {
void updateNameCachedData(@Param("json") String json); void updateNameCachedData(@Param("json") String json);
void updateFlagCachedData(@Param("json") String json); void updateFlagCachedData(@Param("json") String json);
void resetFidAndPD(@Param("json") String json); void resetFidAndPD(@Param("json") String json);
void updateSearchedAt(@Param("json") String json);
void registerJson(@Param("json") String json); void registerJson(@Param("json") String json);
void setFidJson(@Param("json") String json); void setFidJson(@Param("json") String json);
void deleteUnusedPhones(); void deleteUnusedPhones();

View file

@ -94,17 +94,4 @@ public class UpdateProcessingPackagesService {
} }
} }
private void processingRepeatedRestore() {
List<UserPackage> packages = userPackageMapper.findAllPackagesByStatus(Status.PROCESSING_REPEATED.name());
log.debug("Found {} packages in status PROCESSING_REPEATED", packages.size());
for (UserPackage userPackage : packages) {
try {
Pipeline pipeline = pipelinePackageManager.build(new SetupParam(userPackage.getId(), null, PipelineMode.REPEATED_RESTORE));
pipelineOrchestrator.startOrDelay(pipeline, userPackage.getId());
} catch (Exception e) {
log.error("Error build restore pipeline for packageId {}: {}", userPackage.getId(), ExceptionUtils.getStackTrace(e));
}
}
}
} }

View file

@ -42,7 +42,11 @@ public class UpdatingFidAndPdService {
@Scheduled(cron = "${ct.update-fid-cron-expression}") @Scheduled(cron = "${ct.update-fid-cron-expression}")
public void update() { public void update() {
log.info("Delete delete unused phones"); if (!pipelineRecalcPDOrchestrator.checkPermits()) {
log.info("The previous task has not yet been completed.");
return;
}
log.info("Delete unused phones");
phonesMapService.deleteUnusedPhones(); phonesMapService.deleteUnusedPhones();
log.info("Start updating fids and PD"); log.info("Start updating fids and PD");
try { try {

View file

@ -33,6 +33,19 @@ public class PhonesMapService {
} }
} }
public void updateSearchedAt(List<Long> phones) {
try {
String json = entityToJsonMapper.writeValueAsString(phones.stream()
.filter(Objects::nonNull)
.map(phone -> new HashMap<String, Object>() {{
put("phone", phone);
}}).toList());
phonesMapMapper.updateSearchedAt(json);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
public void updateNameCachedData(List<SubjectProfile> subjectProfiles) { public void updateNameCachedData(List<SubjectProfile> subjectProfiles) {
try { try {
String json = entityToJsonMapper.writeValueAsString(subjectProfiles.stream() String json = entityToJsonMapper.writeValueAsString(subjectProfiles.stream()

View file

@ -36,6 +36,11 @@ public class PipelineRecalcPDOrchestrator {
return innerStart(pipeline); return innerStart(pipeline);
} }
public boolean checkPermits() {
synchronized (lock) {
return semaphore.availablePermits() > 0;
}
}
private CompletableFuture<?> innerStart(Pipeline pipeline) { private CompletableFuture<?> innerStart(Pipeline pipeline) {
try { try {
pipeline.start(pipelineExecutorService); pipeline.start(pipelineExecutorService);

View file

@ -51,10 +51,12 @@ public class FidIdEnricher implements Handler<SubjectPayload, PartFilePayload> {
log.debug("FidIdEnricher handle by packageId: {}; size: {}", taskPayload.getPackageId(), subjectsProfile.size()); log.debug("FidIdEnricher handle by packageId: {}; size: {}", taskPayload.getPackageId(), subjectsProfile.size());
List<Integer> noIdDataFids = subjectsProfile.stream() List<Integer> noIdDataFids = subjectsProfile.stream()
.filter(subjectProfile -> subjectProfile.getIdData() == null) .filter(subjectProfile -> subjectProfile.getIdData() == null && subjectProfile.getFid() != null)
.map(SubjectProfile::getFid) .map(SubjectProfile::getFid)
.toList(); .toList();
long countEmptyFid = subjectsProfile.stream().filter(subjectProfile -> subjectProfile.getFid() == null).count();
log.info("Count with empty fid: {}", countEmptyFid);
Map<Integer, Id> idByFid; Map<Integer, Id> idByFid;
if (!noIdDataFids.isEmpty()) { if (!noIdDataFids.isEmpty()) {
idByFid = personService.filledPassportsData(noIdDataFids); idByFid = personService.filledPassportsData(noIdDataFids);
@ -64,6 +66,7 @@ public class FidIdEnricher implements Handler<SubjectPayload, PartFilePayload> {
List<IdData> idCacheOnUpdate = new ArrayList<>(); List<IdData> idCacheOnUpdate = new ArrayList<>();
List<Person> personOnProcessing = subjectsProfile.stream() List<Person> personOnProcessing = subjectsProfile.stream()
.filter(subjectProfile -> subjectProfile.getFid() != null)
.flatMap(subjectProfile -> { .flatMap(subjectProfile -> {
if (subjectProfile.getIdData() == null) { if (subjectProfile.getIdData() == null) {
Id id = idByFid.get(subjectProfile.getFid()); Id id = idByFid.get(subjectProfile.getFid());

View file

@ -1,6 +1,5 @@
package ru.nbch.credit_tracker.service.task.impl; package ru.nbch.credit_tracker.service.task.impl;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -36,14 +35,13 @@ public class FidIdUpdater implements Handler<SubjectPayload, VoidPayload> {
@Override @Override
public VoidPayload handle(SubjectPayload taskPayload) { public VoidPayload handle(SubjectPayload taskPayload) {
List<SubjectProfile> subjectsProfile = taskPayload.getSubjects(); List<SubjectProfile> subjectsProfile = taskPayload.getSubjects();
log.debug("FidIdEnricher handle by packageId: {}; size: {}", taskPayload.getPackageId(), subjectsProfile.size()); log.debug("FidIdUpdater handle; size: {}", subjectsProfile.size());
List<Integer> noIdDataFids = subjectsProfile.stream() List<Integer> noIdDataFids = subjectsProfile.stream()
.map(SubjectProfile::getFid) .map(SubjectProfile::getFid)
.toList(); .toList();
Map<Integer, Id> idByFid = personService.filledPassportsData(noIdDataFids); Map<Integer, Id> idByFid = personService.filledPassportsData(noIdDataFids);
List<IdData> idCacheOnUpdate = new ArrayList<>();
List<IdData> personOnProcessing = subjectsProfile.stream() List<IdData> personOnProcessing = subjectsProfile.stream()
.flatMap(subjectProfile -> { .flatMap(subjectProfile -> {
Id id = idByFid.get(subjectProfile.getFid()); Id id = idByFid.get(subjectProfile.getFid());

View file

@ -3,6 +3,7 @@ package ru.nbch.credit_tracker.service.task.impl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Stream;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings; import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
@ -47,7 +48,7 @@ public class FidNameUpdater implements Handler<SubjectPayload, SubjectPayload> {
List<SubjectProfile> changingFidPhones = new ArrayList<>(); List<SubjectProfile> changingFidPhones = new ArrayList<>();
List<Long> notFoundFidPhones = new ArrayList<>(); List<Long> notFoundFidPhones = new ArrayList<>();
subjects.forEach(subjectProfile -> { List<Long> notChangedPhones = subjects.stream().flatMap(subjectProfile -> {
Name name = nameByPhone.get(CTUtil.normalizePhoneNumber(subjectProfile.getPhone())); Name name = nameByPhone.get(CTUtil.normalizePhoneNumber(subjectProfile.getPhone()));
if (name != null) { if (name != null) {
if (subjectProfile.getFid() == null || !subjectProfile.getFid().equals(name.getFid())) { if (subjectProfile.getFid() == null || !subjectProfile.getFid().equals(name.getFid())) {
@ -57,11 +58,14 @@ public class FidNameUpdater implements Handler<SubjectPayload, SubjectPayload> {
subjectProfile.getNameData().setMiddleName(name.getMiddle()); subjectProfile.getNameData().setMiddleName(name.getMiddle());
subjectProfile.getNameData().setBirthDate(name.getBirthDate()); subjectProfile.getNameData().setBirthDate(name.getBirthDate());
changingFidPhones.add(subjectProfile); changingFidPhones.add(subjectProfile);
return Stream.empty();
} }
} else if (subjectProfile.getFid() != null) { } else if (subjectProfile.getFid() != null) {
notFoundFidPhones.add(subjectProfile.getPhone()); notFoundFidPhones.add(subjectProfile.getPhone());
return Stream.empty();
} }
}); return Stream.of(subjectProfile.getPhone());
}).toList();
List<Long> changingFids = new ArrayList<>(); List<Long> changingFids = new ArrayList<>();
if (!notFoundFidPhones.isEmpty()) { if (!notFoundFidPhones.isEmpty()) {
phonesMapService.resetFidAndPDByPhones(notFoundFidPhones); phonesMapService.resetFidAndPDByPhones(notFoundFidPhones);
@ -73,6 +77,10 @@ public class FidNameUpdater implements Handler<SubjectPayload, SubjectPayload> {
changingFids.addAll(changingFidPhones.stream().map(SubjectProfile::getPhone).toList()); changingFids.addAll(changingFidPhones.stream().map(SubjectProfile::getPhone).toList());
} }
if (!notChangedPhones.isEmpty()) {
phonesMapService.updateSearchedAt(notChangedPhones);
}
if (!changingFids.isEmpty()) { if (!changingFids.isEmpty()) {
List<Long> packageIds = packageRecordsService.selectUniquePackageIds(changingFids); List<Long> packageIds = packageRecordsService.selectUniquePackageIds(changingFids);
if (!packageIds.isEmpty()) { if (!packageIds.isEmpty()) {

View file

@ -64,8 +64,8 @@ public class KickRecalcPipeLine implements IPipeLineStarter<SubjectPayload> {
public void startFillingQueue(BlockingQueue<SubjectPayload> firstQueue) { public void startFillingQueue(BlockingQueue<SubjectPayload> firstQueue) {
try { try {
log.info("Start kicker: mode:{};", mode()); log.info("Start kicker: mode:{};", mode());
int offset = 0; long lastId = 0;
List<PhonesMap> page = nextPage(offset); List<PhonesMap> page = nextPage(lastId);
while (!page.isEmpty()) { while (!page.isEmpty()) {
log.debug("Get page {}", page.size()); log.debug("Get page {}", page.size());
List<SubjectProfile> subjectProfiles = page.stream().map(phoneFidMap -> SubjectProfile.builder() List<SubjectProfile> subjectProfiles = page.stream().map(phoneFidMap -> SubjectProfile.builder()
@ -92,8 +92,8 @@ public class KickRecalcPipeLine implements IPipeLineStarter<SubjectPayload> {
log.error("Pipeline starter was interrupted!"); log.error("Pipeline starter was interrupted!");
throw new PipelineStarterException(); throw new PipelineStarterException();
} }
offset += BATCH_SIZE; lastId = page.getLast().getId();
page = nextPage(offset); page = nextPage(lastId);
} }
} catch (PipelineStarterException e) { } catch (PipelineStarterException e) {
log.info("Pipeline starter shutting down..."); log.info("Pipeline starter shutting down...");
@ -115,7 +115,7 @@ public class KickRecalcPipeLine implements IPipeLineStarter<SubjectPayload> {
protected PipelineMode mode() { protected PipelineMode mode() {
return PipelineMode.REPEATED_RESTORE; return PipelineMode.REPEATED_RESTORE;
} }
protected List<PhonesMap> nextPage(int offset) { protected List<PhonesMap> nextPage(long lastId) {
return phonesMapMapper.searchedAtLessThan(daysToUpdateFids.intValue(), BATCH_SIZE, offset); return phonesMapMapper.searchedAtLessThan(daysToUpdateFids.intValue(), BATCH_SIZE, lastId);
} }
} }

View file

@ -54,9 +54,9 @@
searched_at, searched_at,
calculated_at calculated_at
FROM signals_phones_map FROM signals_phones_map
WHERE searched_at &lt; now() - make_interval(days => #{daysCount}) WHERE searched_at &lt; now() - make_interval(days => #{daysCount}) and id > #{lastId}
ORDER BY id order by id
LIMIT #{limit} OFFSET #{offset} limit #{batchSize}
</select> </select>
<select id="getCachedData" resultMap="PhoneMap" resultType="java.util.List"> <select id="getCachedData" resultMap="PhoneMap" resultType="java.util.List">
@ -201,6 +201,14 @@
where dst.phone = src.phone where dst.phone = src.phone
</update> </update>
<update id="updateSearchedAt" parameterType="string">
update signals_phones_map dst
set searched_at = now()
FROM json_to_recordset(#{json}::json) AS src(
phone bigint)
where dst.phone = src.phone
</update>
<delete id="deleteUnusedPhones"> <delete id="deleteUnusedPhones">
DELETE DELETE
FROM signals_phones_map spm FROM signals_phones_map spm

View file

@ -92,7 +92,7 @@
<update id="updatePackageOnMonitoringSuccess"> <update id="updatePackageOnMonitoringSuccess">
UPDATE signals_user_packages UPDATE signals_user_packages
SET monitoring_at = #{monitoringAt}, status = 'ON_MONITORING' SET monitoring_at = #{monitoringAt}, status = 'ON_MONITORING', fid_changed = null
WHERE id = #{id} WHERE id = #{id}
</update> </update>