fix: refresh dashboard active retention metrics
This commit is contained in:
parent
1520362d9f
commit
d53728e874
@ -0,0 +1,38 @@
|
||||
package com.red.circle.console.app.scheduler;
|
||||
|
||||
import com.red.circle.component.redis.annotation.TaskCacheLock;
|
||||
import com.red.circle.console.app.service.app.datav.CountryDashboardDailyMetricService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 国家数据大屏活跃和留存增量聚合任务.
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@ConditionalOnProperty(
|
||||
name = "red-circle.country-dashboard.active-retention-refresh-enabled",
|
||||
havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
@RequiredArgsConstructor
|
||||
public class CountryDashboardActiveRetentionMetricTask {
|
||||
|
||||
private final CountryDashboardDailyMetricService countryDashboardDailyMetricService;
|
||||
|
||||
@Value("${red-circle.country-dashboard.active-retention-refresh-days:32}")
|
||||
private int refreshDays;
|
||||
|
||||
@Scheduled(cron = "${red-circle.country-dashboard.active-retention-refresh-cron:0 */10 * * * ?}",
|
||||
zone = "Asia/Shanghai")
|
||||
@TaskCacheLock(key = "COUNTRY_DASHBOARD_ACTIVE_RETENTION_REFRESH", expireSecond = 60 * 8)
|
||||
public void refreshActiveRetention() {
|
||||
long start = System.currentTimeMillis();
|
||||
countryDashboardDailyMetricService.refreshActiveRetentionRecentDays(refreshDays);
|
||||
log.info("country dashboard active retention refresh task finished, days={}, costMs={}",
|
||||
refreshDays, System.currentTimeMillis() - start);
|
||||
}
|
||||
}
|
||||
@ -114,6 +114,39 @@ public class CountryDashboardDailyMetricService {
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshActiveRetentionRecentDays(int days) {
|
||||
ensureMetricSchema();
|
||||
int safeDays = Math.max(days, 1);
|
||||
List<String> sysOrigins = resolveSysOrigins();
|
||||
List<StatTimezone> statTimezones = resolveStatTimezones(null);
|
||||
for (String sysOrigin : sysOrigins) {
|
||||
for (StatTimezone statTimezone : statTimezones) {
|
||||
List<LocalDate> statDates = recentDates(safeDays, statTimezone.zoneId());
|
||||
for (LocalDate statDate : statDates) {
|
||||
try {
|
||||
refreshActiveRetentionPeriod(toDayWindow(statDate), sysOrigin, statTimezone);
|
||||
} catch (Exception ex) {
|
||||
log.error("refresh country dashboard active retention day failed, statDate={}, sysOrigin={}, statTimezone={}",
|
||||
statDate, sysOrigin, statTimezone.id(), ex);
|
||||
}
|
||||
}
|
||||
Set<PeriodWindow> windows = new LinkedHashSet<>();
|
||||
for (LocalDate statDate : statDates) {
|
||||
windows.add(toWeekWindow(statDate, statTimezone.zoneId()));
|
||||
windows.add(toMonthWindow(statDate, statTimezone.zoneId()));
|
||||
}
|
||||
for (PeriodWindow window : windows) {
|
||||
try {
|
||||
refreshActiveRetentionPeriod(window, sysOrigin, statTimezone);
|
||||
} catch (Exception ex) {
|
||||
log.error("refresh country dashboard active retention period failed, periodType={}, periodKey={}, sysOrigin={}, statTimezone={}",
|
||||
window.periodType(), window.periodKey(), sysOrigin, statTimezone.id(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshRange(LocalDate startDate, LocalDate endDate, String sysOrigin) {
|
||||
refreshRange(startDate, endDate, sysOrigin, null);
|
||||
}
|
||||
@ -352,6 +385,24 @@ public class CountryDashboardDailyMetricService {
|
||||
System.currentTimeMillis() - start);
|
||||
}
|
||||
|
||||
private void refreshActiveRetentionPeriod(PeriodWindow window, String sysOrigin,
|
||||
StatTimezone statTimezone) {
|
||||
long start = System.currentTimeMillis();
|
||||
TimeWindow timeWindow = toStorageTimeWindow(window, statTimezone);
|
||||
Map<String, CountryDashboardPeriodMetricDTO> rows = new LinkedHashMap<>();
|
||||
mergePeriodDailyActive(rows, listDailyActive(window, sysOrigin), window, sysOrigin,
|
||||
statTimezone);
|
||||
mergePeriodRetention(rows, window, sysOrigin, statTimezone, timeWindow.startTime(),
|
||||
timeWindow.endTime());
|
||||
List<CountryDashboardPeriodMetricDTO> metrics = new ArrayList<>(rows.values());
|
||||
int upserted = metrics.isEmpty() ? 0
|
||||
: transactionTemplate.execute(status ->
|
||||
countryDashboardDAO.upsertPeriodActiveRetentionMetrics(metrics));
|
||||
log.info("refresh country dashboard active retention success, periodType={}, periodKey={}, sysOrigin={}, statTimezone={}, countries={}, upserted={}, costMs={}",
|
||||
window.periodType(), window.periodKey(), sysOrigin, statTimezone.id(), metrics.size(),
|
||||
upserted, System.currentTimeMillis() - start);
|
||||
}
|
||||
|
||||
private void refreshAll(String sysOrigin, StatTimezone statTimezone) {
|
||||
long start = System.currentTimeMillis();
|
||||
PeriodWindow window = new PeriodWindow(PERIOD_ALL, PERIOD_ALL, "全部", null, null);
|
||||
|
||||
@ -191,6 +191,9 @@ public interface CountryDashboardDAO extends BaseDAO<IUserBaseInfo> {
|
||||
|
||||
int upsertPeriodMetrics(@Param("metrics") List<CountryDashboardPeriodMetricDTO> metrics);
|
||||
|
||||
int upsertPeriodActiveRetentionMetrics(
|
||||
@Param("metrics") List<CountryDashboardPeriodMetricDTO> metrics);
|
||||
|
||||
int deletePeriodUserMetrics(
|
||||
@Param("periodType") String periodType,
|
||||
@Param("periodKey") String periodKey,
|
||||
|
||||
@ -1378,6 +1378,63 @@
|
||||
</if>
|
||||
</delete>
|
||||
|
||||
<insert id="upsertPeriodActiveRetentionMetrics">
|
||||
INSERT INTO country_dashboard_period_metric (
|
||||
period_type,
|
||||
period_key,
|
||||
stat_timezone,
|
||||
period_name,
|
||||
period_start_date,
|
||||
period_end_date,
|
||||
sys_origin,
|
||||
country_code,
|
||||
country_name,
|
||||
daily_active_user,
|
||||
d1_retention_user,
|
||||
d1_retention_base_user,
|
||||
d7_retention_user,
|
||||
d7_retention_base_user,
|
||||
d30_retention_user,
|
||||
d30_retention_base_user,
|
||||
refreshed_at
|
||||
)
|
||||
VALUES
|
||||
<foreach collection="metrics" item="item" separator=",">
|
||||
(
|
||||
#{item.periodType},
|
||||
#{item.periodKey},
|
||||
#{item.statTimezone},
|
||||
#{item.periodName},
|
||||
#{item.periodStartDate},
|
||||
#{item.periodEndDate},
|
||||
#{item.sysOrigin},
|
||||
#{item.countryCode},
|
||||
#{item.countryName},
|
||||
IFNULL(#{item.dailyActiveUser}, 0),
|
||||
IFNULL(#{item.d1RetentionUser}, 0),
|
||||
IFNULL(#{item.d1RetentionBaseUser}, 0),
|
||||
IFNULL(#{item.d7RetentionUser}, 0),
|
||||
IFNULL(#{item.d7RetentionBaseUser}, 0),
|
||||
IFNULL(#{item.d30RetentionUser}, 0),
|
||||
IFNULL(#{item.d30RetentionBaseUser}, 0),
|
||||
NOW()
|
||||
)
|
||||
</foreach>
|
||||
ON DUPLICATE KEY UPDATE
|
||||
period_name = VALUES(period_name),
|
||||
period_start_date = VALUES(period_start_date),
|
||||
period_end_date = VALUES(period_end_date),
|
||||
country_name = VALUES(country_name),
|
||||
daily_active_user = VALUES(daily_active_user),
|
||||
d1_retention_user = VALUES(d1_retention_user),
|
||||
d1_retention_base_user = VALUES(d1_retention_base_user),
|
||||
d7_retention_user = VALUES(d7_retention_user),
|
||||
d7_retention_base_user = VALUES(d7_retention_base_user),
|
||||
d30_retention_user = VALUES(d30_retention_user),
|
||||
d30_retention_base_user = VALUES(d30_retention_base_user),
|
||||
refreshed_at = NOW()
|
||||
</insert>
|
||||
|
||||
<insert id="insertPeriodNewUserMetrics">
|
||||
INSERT IGNORE INTO country_dashboard_period_user_metric (
|
||||
period_type,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user