package tech.powerjob.server.initializer; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; import tech.powerjob.common.utils.CommonUtils; import tech.powerjob.server.extension.LockService; import tech.powerjob.server.persistence.remote.model.SundryDO; import tech.powerjob.server.persistence.remote.repository.SundryRepository; import javax.annotation.Resource; import java.util.Date; import java.util.Optional; import java.util.function.Consumer; /** * 新系统初始化器 * * @author tjq * @since 2023/9/5 */ @Slf4j @Component public class NewSystemInitializer implements CommandLineRunner { private static final String LOCK_PREFIX = "sys_init_lock_"; private static final int MAX_LOCK_TIME = 5000; @Resource private LockService lockService; @Resource private SundryRepository sundryRepository; @Resource private SystemInitializeService systemInitializeService; private static final String SUNDRY_PKEY = "sys_initialize"; @Override public void run(String... args) throws Exception { initSystemAdmin(); initDefaultNamespace(); } private void initSystemAdmin() { clusterInit(SystemInitializeService.GOAL_INIT_ADMIN, Void -> systemInitializeService.initAdmin()); } private void initDefaultNamespace() { clusterInit(SystemInitializeService.GOAL_INIT_NAMESPACE, Void -> systemInitializeService.initNamespace()); } private void clusterInit(String name, Consumer initFunc) { Optional sundryOpt = sundryRepository.findByPkeyAndSkey(SUNDRY_PKEY, name); if (sundryOpt.isPresent()) { log.info("[NewSystemInitializer] already initialized, skip: {}", name); return; } String lockName = LOCK_PREFIX.concat(name); while (true) { try { boolean lockStatus = lockService.tryLock(lockName, MAX_LOCK_TIME); // 无论是否拿到锁,都重现检测一次,如果已完成初始化,则直接 return Optional sundryOpt2 = sundryRepository.findByPkeyAndSkey(SUNDRY_PKEY, name); if (sundryOpt2.isPresent()) { log.info("[NewSystemInitializer] other server finished initialize, skip process: {}", name); break; } if (!lockStatus) { CommonUtils.easySleep(277); continue; } log.info("[NewSystemInitializer] try to initialize: {}", name); initFunc.accept(null); log.info("[NewSystemInitializer] initialize [{}] successfully!", name); // 写入初始化成功标记 SundryDO sundryDO = new SundryDO(); sundryDO.setPkey(SUNDRY_PKEY); sundryDO.setSkey(name); sundryDO.setContent("A"); sundryDO.setGmtCreate(new Date()); sundryRepository.saveAndFlush(sundryDO); log.info("[NewSystemInitializer] write initialized tag successfully: {}", sundryDO); break; } finally { lockService.unlock(lockName); } } } }