У нас есть такой код, который трижды повторяет вызов API в рамках механизма опроса. Если он не завершится, он создаст дело, вызвав другой API. Происходит следующее: в журналах я вижу два потока — основной и пул потоков, создающие новые дела. Таким образом, идентификатор отслеживания из пула потоков thead принимает значение null и, таким образом, создает дублирующиеся потоки.
Вот соответствующая часть кода. LLM предлагает мне добавить тайм-аут ниже вызова отмены, однако с этим сталкивается другой API, в котором нет тайм-аута.
Основной поток
if (entity != null && entity.getId() != null) {
Future future = null;
try {
log.info("Waiting for polling result for id : {} trackingId: {}", entity.getId(), trackingId);
OrderRequest finalEntity = entity;
String finalProductOrderId = productOrderId;
Callable task = () -> checkGetStatusAPIForCeaseLine(customerId, finalProductOrderId, routeEnv, sc, trackingId, finalEntity, req);
future = executor.submit(task);
CeaseLineResponse result = future.get(futureTimeoutSecondsForCeaseLine, TimeUnit.SECONDS);
return result;
} catch (TimeoutException te) {
log.warn("Polling did not complete in time for id: {} trackingId: {}", entity.getId(), trackingId);
future.cancel(true);
return handleAmaCaseForCeaseLineTimeout(customerId, entity, productOrderId, req, httpHeaders, trackingId);
} catch (Exception e) {
log.error("Error while waiting for poll result", e);
return CeaseLineResponse.builder()
.httpCode(500)
.message("FAILED")
.orderNo(entity.getBillerOrderNo())
.orderActionId(entity.getBillerOrderActionNo())
.build();
}
}
Вызов исполнителя
@Transactional
public CeaseLineResponse checkGetStatusAPIForCeaseLine(String customerId, String productOrderId, String routeEnv, String sc, String trackingId, OrderRequest entity, CreateAndSubmitSuspendResumeCeaseOrderRequest req) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add(HEADER_TRACKING_ID, trackingId);
httpHeaders.add(HEADER_ROUTE_ENV, routeEnv);
httpHeaders.add(HEADER_SOURCE_SYSTEM_ID, "MATRIX-CEASE-POLL");
httpHeaders.add(HEADER_SOURCE_SERVER_ID, "MATRIX-CEASE-POLL");
httpHeaders.add(HEADER_SERVICE_NAME, "OrderStatus");
httpHeaders.add(HEADER_CACHE_CONTROL, HEADER_CACHE_CONTROL_NO_CACHE);
httpHeaders.add(HEADER_SERVICE_OPERATION_NAME, "MATRIX-CEASE-POLL");
httpHeaders.add(HEADER_TIMESTAMP, String.valueOf(System.currentTimeMillis()));
for (int i = 0; i < maxAttemptForCeaseLine; i++) {
// wait before polling
try {
Thread.sleep(ceaseLineSubmittedPlan * 1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.info("Polling interrupted due to timeout, trackingId: {}", trackingId);
return null;
}
try {
long start = System.nanoTime();
OrderStatusResponse orderStatus = amdocs.getOrderStatus(customerId, productOrderId, sc, trackingId, httpHeaders);
long end = System.nanoTime();
double durationSeconds = (end - start) / 1_000_000_000.0;
log.info("Polling attempt {} for getCeaseLineOrderStatus. Execution time: {} seconds, trackingId: {}", i + 1, durationSeconds, trackingId);
String status = orderStatus != null && orderStatus.getMessage() != null ? orderStatus.getMessage().getStatus() : null;
log.info("Polled status: {} for cease line, trackingId: {}", status, trackingId);
if ("CLOSED".equalsIgnoreCase(status)) {
entity.setStatus(OrderStatus.SUCCESS);
entity.setStatusUpdateDate(Instant.now());
entity.setStatusUpdateSource("API");
entity.setAttemptCount(i + 1);
final OrderRequest save = ceaseOrderRepo.save(entity);
log.info("Obtained CLOSED status for cease line. Updated row: {} trackingId: {}", save, entity.getTrackingId());
return CeaseLineResponse.builder()
.httpCode(200)
.message("SUCCESS")
.orderNo(entity.getBillerOrderNo())
.orderActionId(entity.getBillerOrderActionNo())
.build();
}
} catch (Exception ex) {
entity.setStatus(OrderStatus.FAILED);
entity.setRejectReason("Poll error: " + checkError(ex));
entity.setAttemptCount(i + 1);
final OrderRequest save = ceaseOrderRepo.save(entity);
log.info("Obtained FAILED status for cease line. Updated row: {} trackingId: {}", save, entity.getTrackingId());
return CeaseLineResponse.builder()
.httpCode(500)
.message("FAILED")
.orderNo(entity.getBillerOrderNo())
.orderActionId(entity.getBillerOrderActionNo())
.messageDescription(entity.getRejectReason())
.build();
}
}
entity.setAttemptCount(maxAttemptForReplaceDevice);
return handleAmaCaseForCeaseLineTimeout(customerId, entity, productOrderId, req, httpHeaders, trackingId);
}
private CeaseLineResponse handleAmaCaseForCeaseLineTimeout(
String customerId,
OrderRequest entity,
String productOfferId,
CreateAndSubmitSuspendResumeCeaseOrderRequest req,
HttpHeaders httpHeaders,
String trackingId
) {
log.info("Creating case in AMA for stuck cease order. Order ID: {}, Action ID: {}, trackingId: {}", entity.getBillerOrderNo(), entity.getBillerOrderActionNo(),
trackingId);
String bpmOrderId = req.getPayload().getBpmOrderInputX9() != null
? req.getPayload().getBpmOrderInputX9().getBpmOrderIdx9()
: null;
String caseNumber = maybeCreateAmaCase(customerId, entity, productOfferId, bpmOrderId, httpHeaders);
entity.setRejectReason("Order created but still processing - case Number: " + caseNumber);
entity.setStatus(OrderStatus.SUBMITTED);
final OrderRequest save = ceaseOrderRepo.save(entity);
log.info("SUBMITTED (polling finished) for cease line. Updated row: {} trackingId: {}", save, entity.getTrackingId());
return buildAcceptedOrderResponse202(entity.getBillerOrderNo(), entity.getBillerOrderActionNo(), "Order created but still processing", caseNumber);
}
Это то, что происходит в запросе и создании нового дела с использованием API
u_correlation_id\":\"null:9001962483:9001962484
Вот что LLM предложила мне добавить после вызова отмены:
// Add a small delay to ensure the polling thread has stopped
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
и прерванная проверка здесь"
for (int i = 0; i < maxAttemptForCeaseLine; i++) {
// Check if thread has been interrupted/cancelled
if (Thread.currentThread().isInterrupted()) {
log.info("Polling cancelled for trackingId: {}", trackingId);
return null;
}
Что здесь не так? Есть мысли?
Изменить: такое поведение наблюдается только при попытке=3, а не для 0,1 и 2.
Свойства:
ceaseline.poll.plan.submitted=4,3,3
ceaseline.poll.max-attempts=3
ceaseline.future.timeout-seconds=15
ceaseline.ama.case.enabled=false
ceaseline.app.case.fetch-state-async.enabled=false
метод создания дела
private String maybeCreateAmaCase(String customerId, OrderRequest entity, String productOfferId, String bpmOrderId, HttpHeaders httpHeaders) {
String trackingId = ServiceContext.getString(CEASE_LINE_TRACKING_ID);
if (!amaCaseEnabledForCeaseLine) return null;
IopCaseRequest request = buildIopCaseRequest(customerId, entity.getBillerOrderNo(), entity.getBillerOrderActionNo(), productOfferId, bpmOrderId);
String caseNumber = createCaseAndGetCaseNumber(request, httpHeaders).getCaseNumber();
IopCaseRequest requestWithState = buildIopCaseRequestWithState(caseNumber, matrixServiceConfig.getCeaseLineAssignToUser(), "15");
log.info("Created case in AMA for stuck cease order. Order ID: {}, Action ID: {}, Case Number: {}, trackingId{}",
entity.getBillerOrderNo(), entity.getBillerOrderActionNo(), caseNumber, trackingId);
// Clone headers and set tracking ID explicitly
HttpHeaders asyncHeaders = new HttpHeaders();
asyncHeaders.putAll(httpHeaders);
asyncHeaders.set(CEASE_LINE_TRACKING_ID, trackingId);
// Guard the async call
if (fetchStateAsyncEnabledForCeaseLine) {
fetchCaseStateAsync(requestWithState, caseNumber, asyncHeaders);
} else {
log.info("Async case state fetching for in progress state is disabled for case: {}", caseNumber);
}
return caseNumber;
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... pring-java
Дело создается дважды путем двойного вызова API в Spring/Java [закрыто] ⇐ JAVA
Программисты JAVA общаются здесь
1767548580
Anonymous
У нас есть такой код, который трижды повторяет вызов API в рамках механизма опроса. Если он не завершится, он создаст дело, вызвав другой API. Происходит следующее: в журналах я вижу два потока — основной и пул потоков, создающие новые дела. Таким образом, идентификатор отслеживания из пула потоков thead принимает значение null и, таким образом, создает дублирующиеся потоки.
Вот соответствующая часть кода. LLM предлагает мне добавить тайм-аут ниже вызова отмены, однако с этим сталкивается другой API, в котором нет тайм-аута.
[b]Основной поток[/b]
if (entity != null && entity.getId() != null) {
Future future = null;
try {
log.info("Waiting for polling result for id : {} trackingId: {}", entity.getId(), trackingId);
OrderRequest finalEntity = entity;
String finalProductOrderId = productOrderId;
Callable task = () -> checkGetStatusAPIForCeaseLine(customerId, finalProductOrderId, routeEnv, sc, trackingId, finalEntity, req);
future = executor.submit(task);
CeaseLineResponse result = future.get(futureTimeoutSecondsForCeaseLine, TimeUnit.SECONDS);
return result;
} catch (TimeoutException te) {
log.warn("Polling did not complete in time for id: {} trackingId: {}", entity.getId(), trackingId);
future.cancel(true);
return handleAmaCaseForCeaseLineTimeout(customerId, entity, productOrderId, req, httpHeaders, trackingId);
} catch (Exception e) {
log.error("Error while waiting for poll result", e);
return CeaseLineResponse.builder()
.httpCode(500)
.message("FAILED")
.orderNo(entity.getBillerOrderNo())
.orderActionId(entity.getBillerOrderActionNo())
.build();
}
}
Вызов исполнителя
@Transactional
public CeaseLineResponse checkGetStatusAPIForCeaseLine(String customerId, String productOrderId, String routeEnv, String sc, String trackingId, OrderRequest entity, CreateAndSubmitSuspendResumeCeaseOrderRequest req) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add(HEADER_TRACKING_ID, trackingId);
httpHeaders.add(HEADER_ROUTE_ENV, routeEnv);
httpHeaders.add(HEADER_SOURCE_SYSTEM_ID, "MATRIX-CEASE-POLL");
httpHeaders.add(HEADER_SOURCE_SERVER_ID, "MATRIX-CEASE-POLL");
httpHeaders.add(HEADER_SERVICE_NAME, "OrderStatus");
httpHeaders.add(HEADER_CACHE_CONTROL, HEADER_CACHE_CONTROL_NO_CACHE);
httpHeaders.add(HEADER_SERVICE_OPERATION_NAME, "MATRIX-CEASE-POLL");
httpHeaders.add(HEADER_TIMESTAMP, String.valueOf(System.currentTimeMillis()));
for (int i = 0; i < maxAttemptForCeaseLine; i++) {
// wait before polling
try {
Thread.sleep(ceaseLineSubmittedPlan[i] * 1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.info("Polling interrupted due to timeout, trackingId: {}", trackingId);
return null;
}
try {
long start = System.nanoTime();
OrderStatusResponse orderStatus = amdocs.getOrderStatus(customerId, productOrderId, sc, trackingId, httpHeaders);
long end = System.nanoTime();
double durationSeconds = (end - start) / 1_000_000_000.0;
log.info("Polling attempt {} for getCeaseLineOrderStatus. Execution time: {} seconds, trackingId: {}", i + 1, durationSeconds, trackingId);
String status = orderStatus != null && orderStatus.getMessage() != null ? orderStatus.getMessage().getStatus() : null;
log.info("Polled status: {} for cease line, trackingId: {}", status, trackingId);
if ("CLOSED".equalsIgnoreCase(status)) {
entity.setStatus(OrderStatus.SUCCESS);
entity.setStatusUpdateDate(Instant.now());
entity.setStatusUpdateSource("API");
entity.setAttemptCount(i + 1);
final OrderRequest save = ceaseOrderRepo.save(entity);
log.info("Obtained CLOSED status for cease line. Updated row: {} trackingId: {}", save, entity.getTrackingId());
return CeaseLineResponse.builder()
.httpCode(200)
.message("SUCCESS")
.orderNo(entity.getBillerOrderNo())
.orderActionId(entity.getBillerOrderActionNo())
.build();
}
} catch (Exception ex) {
entity.setStatus(OrderStatus.FAILED);
entity.setRejectReason("Poll error: " + checkError(ex));
entity.setAttemptCount(i + 1);
final OrderRequest save = ceaseOrderRepo.save(entity);
log.info("Obtained FAILED status for cease line. Updated row: {} trackingId: {}", save, entity.getTrackingId());
return CeaseLineResponse.builder()
.httpCode(500)
.message("FAILED")
.orderNo(entity.getBillerOrderNo())
.orderActionId(entity.getBillerOrderActionNo())
.messageDescription(entity.getRejectReason())
.build();
}
}
entity.setAttemptCount(maxAttemptForReplaceDevice);
return handleAmaCaseForCeaseLineTimeout(customerId, entity, productOrderId, req, httpHeaders, trackingId);
}
private CeaseLineResponse handleAmaCaseForCeaseLineTimeout(
String customerId,
OrderRequest entity,
String productOfferId,
CreateAndSubmitSuspendResumeCeaseOrderRequest req,
HttpHeaders httpHeaders,
String trackingId
) {
log.info("Creating case in AMA for stuck cease order. Order ID: {}, Action ID: {}, trackingId: {}", entity.getBillerOrderNo(), entity.getBillerOrderActionNo(),
trackingId);
String bpmOrderId = req.getPayload().getBpmOrderInputX9() != null
? req.getPayload().getBpmOrderInputX9().getBpmOrderIdx9()
: null;
String caseNumber = maybeCreateAmaCase(customerId, entity, productOfferId, bpmOrderId, httpHeaders);
entity.setRejectReason("Order created but still processing - case Number: " + caseNumber);
entity.setStatus(OrderStatus.SUBMITTED);
final OrderRequest save = ceaseOrderRepo.save(entity);
log.info("SUBMITTED (polling finished) for cease line. Updated row: {} trackingId: {}", save, entity.getTrackingId());
return buildAcceptedOrderResponse202(entity.getBillerOrderNo(), entity.getBillerOrderActionNo(), "Order created but still processing", caseNumber);
}
Это то, что происходит в запросе и создании нового дела с использованием API
u_correlation_id\":\"null:9001962483:9001962484
Вот что LLM предложила мне добавить после вызова отмены:
// Add a small delay to ensure the polling thread has stopped
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
и прерванная проверка здесь"
for (int i = 0; i < maxAttemptForCeaseLine; i++) {
// Check if thread has been interrupted/cancelled
if (Thread.currentThread().isInterrupted()) {
log.info("Polling cancelled for trackingId: {}", trackingId);
return null;
}
Что здесь не так? Есть мысли?
Изменить: такое поведение наблюдается только при попытке=3, а не для 0,1 и 2.
Свойства:
ceaseline.poll.plan.submitted=4,3,3
ceaseline.poll.max-attempts=3
ceaseline.future.timeout-seconds=15
ceaseline.ama.case.enabled=false
ceaseline.app.case.fetch-state-async.enabled=false
метод создания дела
private String maybeCreateAmaCase(String customerId, OrderRequest entity, String productOfferId, String bpmOrderId, HttpHeaders httpHeaders) {
String trackingId = ServiceContext.getString(CEASE_LINE_TRACKING_ID);
if (!amaCaseEnabledForCeaseLine) return null;
IopCaseRequest request = buildIopCaseRequest(customerId, entity.getBillerOrderNo(), entity.getBillerOrderActionNo(), productOfferId, bpmOrderId);
String caseNumber = createCaseAndGetCaseNumber(request, httpHeaders).getCaseNumber();
IopCaseRequest requestWithState = buildIopCaseRequestWithState(caseNumber, matrixServiceConfig.getCeaseLineAssignToUser(), "15");
log.info("Created case in AMA for stuck cease order. Order ID: {}, Action ID: {}, Case Number: {}, trackingId{}",
entity.getBillerOrderNo(), entity.getBillerOrderActionNo(), caseNumber, trackingId);
// Clone headers and set tracking ID explicitly
HttpHeaders asyncHeaders = new HttpHeaders();
asyncHeaders.putAll(httpHeaders);
asyncHeaders.set(CEASE_LINE_TRACKING_ID, trackingId);
// Guard the async call
if (fetchStateAsyncEnabledForCeaseLine) {
fetchCaseStateAsync(requestWithState, caseNumber, asyncHeaders);
} else {
log.info("Async case state fetching for in progress state is disabled for case: {}", caseNumber);
}
return caseNumber;
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79859982/case-is-being-created-twice-by-calling-the-api-twice-in-spring-java[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия