|
|
@@ -9,6 +9,10 @@ import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Set;
|
|
|
+import java.util.concurrent.CountDownLatch;
|
|
|
+import java.util.concurrent.ExecutorService;
|
|
|
+import java.util.concurrent.Executors;
|
|
|
+import java.util.concurrent.Semaphore;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
@@ -588,66 +592,106 @@ public class AdPlanConfServiceImpl extends ServiceImpl<AdPlanConfMapper, AdPlanC
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // 第二步:创建广告组与创意
|
|
|
- // 遍历处理每个 AdPlan
|
|
|
+ // 第二步:创建广告组与创意(使用虚拟线程并行处理,Semaphore限制最大并发数为10)
|
|
|
+ Semaphore semaphore = new Semaphore(10);
|
|
|
+ CountDownLatch latch = new CountDownLatch(plans.size());
|
|
|
+ ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
|
|
+
|
|
|
for (AdPlan plan : plans) {
|
|
|
- try {
|
|
|
- log.info("开始处理广告计划,planId={}, adgroupName={}", plan.getId(), plan.getAdgroupName());
|
|
|
+ executor.submit(() -> {
|
|
|
+ try {
|
|
|
+ semaphore.acquire();
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
+ latch.countDown();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 每个虚拟线程创建独立的 TencentAds 实例
|
|
|
+ TencentAds threadTencentAds;
|
|
|
+ try {
|
|
|
+ threadTencentAds = clientFactory.getTencentAds(jobNumber, Constant.MAIN_ORG_ACCOUNT_ID);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("虚拟线程创建TencentAds实例失败,planId={}", plan.getId(), e);
|
|
|
+ plan.setStatus(AdPlanStatus.FAILED);
|
|
|
+ plan.setFailReason("创建TencentAds实例失败: " + StrUtil.truncateError(e.getMessage()));
|
|
|
+ adPlanService.updateById(plan);
|
|
|
+ semaphore.release();
|
|
|
+ latch.countDown();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ log.info("开始处理广告计划,planId={}, adgroupName={}", plan.getId(), plan.getAdgroupName());
|
|
|
+
|
|
|
+ if (plan.getAdgroupId() > 0 || plan.getStatus() == AdPlanStatus.SUCCESS) {
|
|
|
+ // 创建动态创意
|
|
|
+ createDynamicCreatives(threadTencentAds, plan);
|
|
|
+ plan.setFailReason("");
|
|
|
+ plan.setStatus(AdPlanStatus.SUCCESS);
|
|
|
+ plan.setSuccessTime(LocalDateTime.now());
|
|
|
+ adPlanService.updateById(plan);
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- if (plan.getAdgroupId() > 0 || plan.getStatus() == AdPlanStatus.SUCCESS) {
|
|
|
- // 创建动态创意
|
|
|
- createDynamicCreatives(tencentAds, plan);
|
|
|
- plan.setFailReason("");
|
|
|
+ // 更新状态为执行中
|
|
|
+ plan.setStatus(AdPlanStatus.IN_PROGRESS);
|
|
|
+ adPlanService.updateById(plan);
|
|
|
+
|
|
|
+ // 根据 adType 构建请求
|
|
|
+ AdgroupsAddRequest request = buildAdgroupRequest(plan);
|
|
|
+ log.info("请求参数: {}", JSON.toJSON(request));
|
|
|
+ // 创建广告组
|
|
|
+ log.info("调用腾讯API创建广告组,accountId={}, orgAccountId={}", plan.getAccountId(),
|
|
|
+ Constant.MAIN_ORG_ACCOUNT_ID);
|
|
|
+ AdgroupsAddResponseData response = tencentAdsAdgroupService.createAdgroup(
|
|
|
+ threadTencentAds, request);
|
|
|
+
|
|
|
+ // 更新 adgroupId
|
|
|
+ plan.setAdgroupId(response.getAdgroupId());
|
|
|
+ log.info("广告组创建成功,adgroupId={}", response.getAdgroupId());
|
|
|
+
|
|
|
+ // 更新状态为成功
|
|
|
plan.setStatus(AdPlanStatus.SUCCESS);
|
|
|
+ plan.setFailReason("");
|
|
|
+ plan.setCreateTime(LocalDateTime.now());
|
|
|
plan.setSuccessTime(LocalDateTime.now());
|
|
|
adPlanService.updateById(plan);
|
|
|
- continue;
|
|
|
- }
|
|
|
|
|
|
- // 更新状态为执行中
|
|
|
- plan.setStatus(AdPlanStatus.IN_PROGRESS);
|
|
|
- adPlanService.updateById(plan);
|
|
|
-
|
|
|
- // 根据 adType 构建请求
|
|
|
- AdgroupsAddRequest request = buildAdgroupRequest(plan);
|
|
|
- log.info("请求参数: {}", JSON.toJSON(request));
|
|
|
- // 创建广告组
|
|
|
- log.info("调用腾讯API创建广告组,accountId={}, orgAccountId={}", plan.getAccountId(),
|
|
|
- Constant.MAIN_ORG_ACCOUNT_ID);
|
|
|
- AdgroupsAddResponseData response = tencentAdsAdgroupService.createAdgroup(
|
|
|
- tencentAds, request);
|
|
|
-
|
|
|
- // 更新 adgroupId
|
|
|
- plan.setAdgroupId(response.getAdgroupId());
|
|
|
- log.info("广告组创建成功,adgroupId={}", response.getAdgroupId());
|
|
|
-
|
|
|
- // 更新状态为成功
|
|
|
- plan.setStatus(AdPlanStatus.SUCCESS);
|
|
|
- plan.setFailReason("");
|
|
|
- plan.setCreateTime(LocalDateTime.now());
|
|
|
- plan.setSuccessTime(LocalDateTime.now());
|
|
|
- adPlanService.updateById(plan);
|
|
|
-
|
|
|
- // 创建动态创意
|
|
|
- if (plan.getAdgroupId() > 0) {
|
|
|
- createDynamicCreatives(tencentAds, plan);
|
|
|
- }
|
|
|
+ // 创建动态创意
|
|
|
+ if (plan.getAdgroupId() > 0) {
|
|
|
+ createDynamicCreatives(threadTencentAds, plan);
|
|
|
+ }
|
|
|
|
|
|
- log.info("广告计划处理成功,planId={}, adgroupId={}", plan.getId(), plan.getAdgroupId());
|
|
|
+ log.info("广告计划处理成功,planId={}, adgroupId={}", plan.getId(), plan.getAdgroupId());
|
|
|
|
|
|
- } catch (TencentAdsResponseException e) {
|
|
|
- // 记录失败
|
|
|
- log.error("创建广告失败, planId={} code={} message={} messageCn={}", plan.getId(), e.getCode(),
|
|
|
- e.getMessage(), e.getMessageCn());
|
|
|
- plan.setStatus(AdPlanStatus.FAILED);
|
|
|
- plan.setFailReason(StrUtil.truncateError(e.getMessageCn()));
|
|
|
- adPlanService.updateById(plan);
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("创建广告失败, planId={}", plan.getId(), e);
|
|
|
- plan.setStatus(AdPlanStatus.FAILED);
|
|
|
- plan.setFailReason(StrUtil.truncateError(e.getMessage()));
|
|
|
- adPlanService.updateById(plan);
|
|
|
- }
|
|
|
+ } catch (TencentAdsResponseException e) {
|
|
|
+ // 记录失败
|
|
|
+ log.error("创建广告失败, planId={} code={} message={} messageCn={}", plan.getId(), e.getCode(),
|
|
|
+ e.getMessage(), e.getMessageCn());
|
|
|
+ plan.setStatus(AdPlanStatus.FAILED);
|
|
|
+ plan.setFailReason(StrUtil.truncateError(e.getMessageCn()));
|
|
|
+ adPlanService.updateById(plan);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("创建广告失败, planId={}", plan.getId(), e);
|
|
|
+ plan.setStatus(AdPlanStatus.FAILED);
|
|
|
+ plan.setFailReason(StrUtil.truncateError(e.getMessage()));
|
|
|
+ adPlanService.updateById(plan);
|
|
|
+ } finally {
|
|
|
+ semaphore.release();
|
|
|
+ latch.countDown();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 等待所有虚拟线程任务完成
|
|
|
+ try {
|
|
|
+ latch.await();
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ log.error("等待虚拟线程任务完成被中断,confId={}", confId, e);
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
+ } finally {
|
|
|
+ executor.shutdown();
|
|
|
}
|
|
|
|
|
|
// 更新 AdPlanConf 状态
|
|
|
@@ -1085,7 +1129,7 @@ public class AdPlanConfServiceImpl extends ServiceImpl<AdPlanConfMapper, AdPlanC
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- TencentAds tencentAds = clientFactory.getTencentAds(null, Constant.MAIN_ORG_ACCOUNT_ID);
|
|
|
+ TencentAds tencentAds = clientFactory.getTencentAds(Constant.JOB_NUMBER, Constant.MAIN_ORG_ACCOUNT_ID);
|
|
|
doDeletePlans(tencentAds, deletePlans);
|
|
|
lambdaUpdate().eq(AdPlanConf::getId, conf.getId())
|
|
|
.set(AdPlanConf::getFailReason, "广告巡检删除" + deletePlans.size() + "个广告")
|