|
@@ -28,6 +28,8 @@ import com.adx.tencent.kuaishou.store.KuaishouColdStore;
|
|
|
import com.adx.tencent.kuaishou.store.KuaishouHotStore;
|
|
import com.adx.tencent.kuaishou.store.KuaishouHotStore;
|
|
|
import com.adx.tencent.leader.LeaderElection;
|
|
import com.adx.tencent.leader.LeaderElection;
|
|
|
import com.adx.tencent.report.AdBidReportStore;
|
|
import com.adx.tencent.report.AdBidReportStore;
|
|
|
|
|
+import com.adx.tencent.tagsync.AccountTagEventResolver;
|
|
|
|
|
+import com.adx.tencent.tagsync.AccountTagEventSyncService;
|
|
|
import com.adx.tencent.tagsync.TagEventResolver;
|
|
import com.adx.tencent.tagsync.TagEventResolver;
|
|
|
import com.adx.tencent.tagsync.TagEventSyncService;
|
|
import com.adx.tencent.tagsync.TagEventSyncService;
|
|
|
import com.adx.tencent.tencent.TencentClient;
|
|
import com.adx.tencent.tencent.TencentClient;
|
|
@@ -510,6 +512,13 @@ public class AppConfiguration {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Bean
|
|
@Bean
|
|
|
|
|
+ public AccountTagEventResolver accountTagEventResolver(@Nullable TiDBColdStore coldStore,
|
|
|
|
|
+ StringRedisTemplate redisTemplate) {
|
|
|
|
|
+ if (coldStore == null) return null;
|
|
|
|
|
+ return new AccountTagEventResolver(redisTemplate, coldStore, props.getAccountTagEventSyncRedisPrefix());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Bean
|
|
|
public HonorTagEventResolver honorTagEventResolver(@Nullable HonorColdStore honorColdStore,
|
|
public HonorTagEventResolver honorTagEventResolver(@Nullable HonorColdStore honorColdStore,
|
|
|
StringRedisTemplate redisTemplate) {
|
|
StringRedisTemplate redisTemplate) {
|
|
|
if (honorColdStore == null) return null;
|
|
if (honorColdStore == null) return null;
|
|
@@ -536,6 +545,7 @@ public class AppConfiguration {
|
|
|
TencentClient tencentClient,
|
|
TencentClient tencentClient,
|
|
|
@Nullable TiDBColdStore coldStore,
|
|
@Nullable TiDBColdStore coldStore,
|
|
|
@Nullable TagEventResolver tagEventResolver,
|
|
@Nullable TagEventResolver tagEventResolver,
|
|
|
|
|
+ @Nullable AccountTagEventResolver accountTagEventResolver,
|
|
|
@Nullable HonorTagEventResolver honorTagEventResolver,
|
|
@Nullable HonorTagEventResolver honorTagEventResolver,
|
|
|
@Nullable KuaishouTagEventResolver kuaishouTagEventResolver,
|
|
@Nullable KuaishouTagEventResolver kuaishouTagEventResolver,
|
|
|
@Nullable VivoTagEventResolver vivoTagEventResolver,
|
|
@Nullable VivoTagEventResolver vivoTagEventResolver,
|
|
@@ -550,7 +560,7 @@ public class AppConfiguration {
|
|
|
@Nullable VivoClient vivoClient) {
|
|
@Nullable VivoClient vivoClient) {
|
|
|
if (coldStore == null) return null;
|
|
if (coldStore == null) return null;
|
|
|
return new ConversionSyncService(baiduClient, hotStore, tencentClient, coldStore, tagEventResolver,
|
|
return new ConversionSyncService(baiduClient, hotStore, tencentClient, coldStore, tagEventResolver,
|
|
|
- honorTagEventResolver, kuaishouTagEventResolver, vivoTagEventResolver,
|
|
|
|
|
|
|
+ accountTagEventResolver, honorTagEventResolver, kuaishouTagEventResolver, vivoTagEventResolver,
|
|
|
honorHotStore, honorColdStore, kuaishouHotStore, kuaishouColdStore, vivoHotStore, vivoColdStore,
|
|
honorHotStore, honorColdStore, kuaishouHotStore, kuaishouColdStore, vivoHotStore, vivoColdStore,
|
|
|
honorClient, kuaishouClient, vivoClient, props);
|
|
honorClient, kuaishouClient, vivoClient, props);
|
|
|
}
|
|
}
|
|
@@ -595,6 +605,15 @@ public class AppConfiguration {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Bean
|
|
@Bean
|
|
|
|
|
+ public AccountTagEventSyncService accountTagEventSyncService(@Nullable TiDBColdStore coldStore,
|
|
|
|
|
+ StringRedisTemplate redisTemplate) {
|
|
|
|
|
+ if (coldStore == null) return null;
|
|
|
|
|
+ Duration ttl = props.getAccountTagEventSyncInterval().multipliedBy(3);
|
|
|
|
|
+ return new AccountTagEventSyncService(coldStore, redisTemplate,
|
|
|
|
|
+ props.getAccountTagEventSyncRedisPrefix(), ttl);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Bean
|
|
|
public HonorTagEventSyncService honorTagEventSyncService(@Nullable HonorColdStore honorColdStore,
|
|
public HonorTagEventSyncService honorTagEventSyncService(@Nullable HonorColdStore honorColdStore,
|
|
|
StringRedisTemplate redisTemplate) {
|
|
StringRedisTemplate redisTemplate) {
|
|
|
if (honorColdStore == null) return null;
|
|
if (honorColdStore == null) return null;
|
|
@@ -734,6 +753,7 @@ public class AppConfiguration {
|
|
|
@Autowired(required = false) private ConversionSyncRunner conversionSyncRunner;
|
|
@Autowired(required = false) private ConversionSyncRunner conversionSyncRunner;
|
|
|
@Autowired(required = false) private RetryService retryService;
|
|
@Autowired(required = false) private RetryService retryService;
|
|
|
@Autowired(required = false) private TagEventSyncService tagEventSyncService;
|
|
@Autowired(required = false) private TagEventSyncService tagEventSyncService;
|
|
|
|
|
+ @Autowired(required = false) private AccountTagEventSyncService accountTagEventSyncService;
|
|
|
@Autowired(required = false) private LeaderElection leaderElection;
|
|
@Autowired(required = false) private LeaderElection leaderElection;
|
|
|
|
|
|
|
|
private final AtomicBoolean stopped = new AtomicBoolean(false);
|
|
private final AtomicBoolean stopped = new AtomicBoolean(false);
|
|
@@ -825,6 +845,28 @@ public class AppConfiguration {
|
|
|
taskLog.warn("Tag event sync NOT started: service={}, enabled={}",
|
|
taskLog.warn("Tag event sync NOT started: service={}, enabled={}",
|
|
|
tagEventSyncService != null, props.isTagEventSyncEnabled());
|
|
tagEventSyncService != null, props.isTagEventSyncEnabled());
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ // 腾讯账户级广告位回传方式同步
|
|
|
|
|
+ if (accountTagEventSyncService != null && props.isAccountTagEventSyncEnabled()) {
|
|
|
|
|
+ if (props.isSkipLeaderElection()) {
|
|
|
|
|
+ executor.submit(() -> runAccountTagEventSync(() -> stopped.get()));
|
|
|
|
|
+ taskLog.info("Account tag event sync started (skip leader election)");
|
|
|
|
|
+ } else if (leaderElection != null) {
|
|
|
|
|
+ executor.submit(() ->
|
|
|
|
|
+ leaderElection.run(
|
|
|
|
|
+ "adx:lock:tencent:account-tag-event-sync",
|
|
|
|
|
+ props.getTaskLockTtl(), props.getTaskLockRenewInterval(), props.getTaskLockRetryInterval(),
|
|
|
|
|
+ stopped::get,
|
|
|
|
|
+ (jobStop) -> runAccountTagEventSync(jobStop),
|
|
|
|
|
+ e -> taskLog.error("tencent account tag event sync leader: {}", e.getMessage(), e)
|
|
|
|
|
+ )
|
|
|
|
|
+ );
|
|
|
|
|
+ taskLog.info("Account tag event sync leader election started");
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ taskLog.warn("Account tag event sync NOT started: service={}, enabled={}",
|
|
|
|
|
+ accountTagEventSyncService != null, props.isAccountTagEventSyncEnabled());
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private void runConversionSync(LeaderElection.StopSignal jobStop) {
|
|
private void runConversionSync(LeaderElection.StopSignal jobStop) {
|
|
@@ -918,6 +960,21 @@ public class AppConfiguration {
|
|
|
taskLog.info("[TagEventSync] task stopped");
|
|
taskLog.info("[TagEventSync] task stopped");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ private void runAccountTagEventSync(LeaderElection.StopSignal jobStop) {
|
|
|
|
|
+ long intervalMs = props.getAccountTagEventSyncInterval().toMillis();
|
|
|
|
|
+ taskLog.info("[AccountTagEventSync] task started, interval={}ms", intervalMs);
|
|
|
|
|
+ while (!jobStop.isStopped()) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ int n = accountTagEventSyncService.syncOnce();
|
|
|
|
|
+ taskLog.info("[AccountTagEventSync] done: synced={}", n);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ taskLog.error("[AccountTagEventSync] error: {}", e.getMessage(), e);
|
|
|
|
|
+ }
|
|
|
|
|
+ sleepResponsive(intervalMs, jobStop);
|
|
|
|
|
+ }
|
|
|
|
|
+ taskLog.info("[AccountTagEventSync] task stopped");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private static void sleepResponsive(long ms, LeaderElection.StopSignal jobStop) {
|
|
private static void sleepResponsive(long ms, LeaderElection.StopSignal jobStop) {
|
|
|
long deadline = System.currentTimeMillis() + ms;
|
|
long deadline = System.currentTimeMillis() + ms;
|
|
|
while (!jobStop.isStopped()) {
|
|
while (!jobStop.isStopped()) {
|