OppoBackgroundTasks.java 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package com.adx.tencent.oppo.service;
  2. import com.adx.tencent.config.AppProperties;
  3. import com.adx.tencent.leader.LeaderElection;
  4. import org.slf4j.Logger;
  5. import org.slf4j.LoggerFactory;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.boot.ApplicationArguments;
  8. import org.springframework.boot.ApplicationRunner;
  9. import org.springframework.lang.Nullable;
  10. import org.springframework.stereotype.Component;
  11. import java.util.concurrent.ExecutorService;
  12. import java.util.concurrent.Executors;
  13. import java.util.concurrent.atomic.AtomicBoolean;
  14. @Component
  15. public class OppoBackgroundTasks implements ApplicationRunner {
  16. private static final Logger log = LoggerFactory.getLogger(OppoBackgroundTasks.class);
  17. @Autowired private AppProperties props;
  18. @Autowired(required = false) private OppoColdWorker worker;
  19. @Autowired(required = false) private OppoRetryService retryService;
  20. @Autowired(required = false) private OppoTagEventSyncService tagSync;
  21. @Autowired(required = false) @Nullable private LeaderElection leaderElection;
  22. private final AtomicBoolean stopped = new AtomicBoolean();
  23. private final ExecutorService executor = Executors.newCachedThreadPool(r -> {
  24. Thread t = new Thread(r);
  25. t.setDaemon(true);
  26. return t;
  27. });
  28. public void run(ApplicationArguments args) {
  29. if (worker != null) {
  30. executor.submit(() -> {
  31. while (!stopped.get()) {
  32. try {
  33. if (worker.runOnce() == 0) {
  34. sleep(200);
  35. }
  36. } catch (Exception e) {
  37. log.error("oppo cold worker: {}", e.getMessage(), e);
  38. sleep(1000);
  39. }
  40. }
  41. });
  42. }
  43. if (retryService != null && props.isOppoCallbackRetryEnabled()) {
  44. if (props.isSkipLeaderElection() || leaderElection == null) {
  45. executor.submit(() -> runRetry(() -> stopped.get()));
  46. } else {
  47. executor.submit(() -> leaderElection.run(
  48. "adx:lock:oppo:callback-retry",
  49. props.getTaskLockTtl(), props.getTaskLockRenewInterval(), props.getTaskLockRetryInterval(),
  50. stopped::get,
  51. this::runRetry,
  52. e -> log.error("oppo callback retry leader: {}", e.getMessage(), e)
  53. ));
  54. }
  55. }
  56. if (tagSync != null && props.isOppoTagEventSyncEnabled()) {
  57. if (props.isSkipLeaderElection() || leaderElection == null) {
  58. executor.submit(() -> runTagEventSync(() -> stopped.get()));
  59. } else {
  60. executor.submit(() -> leaderElection.run(
  61. "adx:lock:oppo:tag-event-sync",
  62. props.getTaskLockTtl(), props.getTaskLockRenewInterval(), props.getTaskLockRetryInterval(),
  63. stopped::get,
  64. this::runTagEventSync,
  65. e -> log.error("oppo tag event sync leader: {}", e.getMessage(), e)
  66. ));
  67. }
  68. }
  69. }
  70. private void runRetry(LeaderElection.StopSignal stopSignal) {
  71. long intervalMs = props.getOppoCallbackRetryInterval().toMillis();
  72. while (!stopSignal.isStopped()) {
  73. try {
  74. retryService.retry(props.getOppoCallbackRetryLimit());
  75. } catch (Exception e) {
  76. log.error("oppo callback retry: {}", e.getMessage(), e);
  77. }
  78. sleepResponsive(intervalMs, stopSignal);
  79. }
  80. }
  81. private void runTagEventSync(LeaderElection.StopSignal stopSignal) {
  82. long intervalMs = props.getOppoTagEventSyncInterval().toMillis();
  83. while (!stopSignal.isStopped()) {
  84. try {
  85. tagSync.syncOnce();
  86. } catch (Exception e) {
  87. log.error("oppo tag event sync: {}", e.getMessage(), e);
  88. }
  89. sleepResponsive(intervalMs, stopSignal);
  90. }
  91. }
  92. private void sleepResponsive(long millis, LeaderElection.StopSignal stopSignal) {
  93. long remaining = millis;
  94. while (remaining > 0 && !stopSignal.isStopped()) {
  95. long chunk = Math.min(remaining, 1000);
  96. sleep(chunk);
  97. remaining -= chunk;
  98. }
  99. }
  100. private void sleep(long millis) {
  101. try {
  102. Thread.sleep(Math.max(1, millis));
  103. } catch (InterruptedException e) {
  104. Thread.currentThread().interrupt();
  105. stopped.set(true);
  106. }
  107. }
  108. }