
com.github.lontime.extcosid.container.SegmentIdContainer Maven / Gradle / Ivy
package com.github.lontime.extcosid.container;
import java.time.Duration;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import javax.sql.DataSource;
import com.github.lontime.base.commonj.components.AbstractLifecycle;
import com.github.lontime.base.commonj.utils.StringHelper;
import com.github.lontime.extcosid.configuration.IdConverterDefinition;
import com.github.lontime.extcosid.configuration.SegmentIdOptions;
import com.github.lontime.extcosid.jdbi.JdbiIdSegmentDistributorFactory;
import com.github.lontime.extcosid.jdbi.JdbiIdSegmentInitializer;
import com.github.lontime.extcosid.redisson.RedissonIdSegmentDistributorFactory;
import com.github.lontime.extdatasource.DatasourceInstance;
import com.github.lontime.extjdbi.JdbiInstance;
import com.github.lontime.extredisson.RedissonInstance;
import com.github.lontime.shaded.com.google.common.base.MoreObjects;
import com.github.lontime.shaded.com.google.common.base.Strings;
import com.github.lontime.shaded.org.redisson.api.RedissonClient;
import me.ahoo.cosid.IdConverter;
import me.ahoo.cosid.converter.PrefixIdConverter;
import me.ahoo.cosid.converter.Radix62IdConverter;
import me.ahoo.cosid.converter.SuffixIdConverter;
import me.ahoo.cosid.converter.ToStringIdConverter;
import me.ahoo.cosid.jdbc.JdbcIdSegmentDistributorFactory;
import me.ahoo.cosid.jdbc.JdbcIdSegmentInitializer;
import me.ahoo.cosid.provider.DefaultIdGeneratorProvider;
import me.ahoo.cosid.provider.IdGeneratorProvider;
import me.ahoo.cosid.segment.DefaultSegmentId;
import me.ahoo.cosid.segment.IdSegmentDistributor;
import me.ahoo.cosid.segment.IdSegmentDistributorDefinition;
import me.ahoo.cosid.segment.IdSegmentDistributorFactory;
import me.ahoo.cosid.segment.SegmentChainId;
import me.ahoo.cosid.segment.SegmentId;
import me.ahoo.cosid.segment.StringSegmentId;
import me.ahoo.cosid.segment.concurrent.PrefetchWorkerExecutorService;
import org.jdbi.v3.core.Jdbi;
/**
* SegmentIdExt.
* @author lontime
* @since 1.0
*/
public class SegmentIdContainer extends AbstractLifecycle {
private final SegmentIdOptions options;
private final String namespace;
private final Map segmentIds = new ConcurrentHashMap<>();
private volatile PrefetchWorkerExecutorService prefetchWorkerExecutorService;
private IdSegmentDistributorFactory distributorFactory;
public SegmentIdContainer(String namespace, SegmentIdOptions options) {
this.options = options;
this.namespace = namespace;
}
private PrefetchWorkerExecutorService buildPrefetchWorkerExecutorService() {
final Duration prefetchPeriod = options.getChain().getPrefetchWorker().getPrefetchPeriod();
final Integer corePoolSize = options.getChain().getPrefetchWorker().getCorePoolSize();
final PrefetchWorkerExecutorService executorService =
new PrefetchWorkerExecutorService(prefetchPeriod, corePoolSize, false);
//默认创建的线程 关闭调用
PrefetchWorkerExecutorService.DEFAULT.shutdown();
return executorService;
}
public SegmentId getSegmentId() {
return segmentIds.computeIfAbsent(IdGeneratorProvider.SHARE, k -> {
final SegmentId segmentId = loadShareSegmentId();
DefaultIdGeneratorProvider.INSTANCE.set(k, segmentId);
return segmentId;
});
}
public SegmentId getSegmentId(String name) {
if (StringHelper.isEmpty(name)) {
return getSegmentId();
}
final SegmentId segmentId = segmentIds.computeIfAbsent(name, k -> {
final SegmentId segmentIdInner = loadSegmentId(k);
if (segmentIdInner == null) {
return null;
}
DefaultIdGeneratorProvider.INSTANCE.set(name, segmentIdInner);
return segmentIdInner;
});
if (Objects.nonNull(segmentId)) {
return segmentId;
}
return getSegmentId();
}
private SegmentId loadShareSegmentId() {
return loadSegmentId(options.getShare());
}
private SegmentId loadSegmentId(String name) {
if (StringHelper.isEmpty(name)) {
return loadSegmentId(options.getShare());
}
final Optional definitionOptional
= options.getProvider().stream().filter(s -> name.equals(s.getName())).findFirst();
if (definitionOptional.isPresent()) {
final SegmentIdOptions.IdDefinition definition = definitionOptional.get();
return loadSegmentId(definition);
}
return null;
}
private SegmentId loadSegmentId(SegmentIdOptions.IdDefinition definition) {
final IdSegmentDistributorDefinition distributorDefinition = asDistributorDefinition(definition.getName(), definition);
final IdSegmentDistributor idSegmentDistributor = distributorFactory.create(distributorDefinition);
return createSegment(definition, idSegmentDistributor);
}
private IdSegmentDistributorFactory buildIdSegmentDistributorFactory() {
final SegmentIdOptions.DistributorType type = options.getDistributor().getType();
if (type == SegmentIdOptions.DistributorType.JDBI) {
final SegmentIdOptions.DistributorJdbi jdbiOptions = options.getDistributor().getJdbi();
final Jdbi jdbi = JdbiInstance.get().getJdbi(jdbiOptions.getDataSourceName());
final JdbiIdSegmentInitializer jdbiIdSegmentInitializer =
new JdbiIdSegmentInitializer(jdbiOptions.getInitCosidTableSql(),
jdbiOptions.getInitIdSegmentSql(), jdbi);
return new JdbiIdSegmentDistributorFactory(jdbi, jdbiOptions.getEnableAutoInitIdSegment(),
jdbiIdSegmentInitializer, jdbiOptions.getIncrementMaxIdSql(), jdbiOptions.getFetchMaxIdSql());
}
if (type == SegmentIdOptions.DistributorType.JDBC) {
final SegmentIdOptions.DistributorJdbc jdbcOptions = options.getDistributor().getJdbc();
final DataSource dataSource = DatasourceInstance.get().getDataSource(jdbcOptions.getDataSourceName());
final JdbcIdSegmentInitializer jdbcIdSegmentInitializer =
new JdbcIdSegmentInitializer(jdbcOptions.getInitCosidTableSql(), jdbcOptions.getInitIdSegmentSql(),
dataSource);
return new JdbcIdSegmentDistributorFactory(dataSource, jdbcOptions.getEnableAutoInitIdSegment(),
jdbcIdSegmentInitializer, jdbcOptions.getInitIdSegmentSql(), jdbcOptions.getFetchMaxIdSql());
}
if (type == SegmentIdOptions.DistributorType.REDISSON) {
final SegmentIdOptions.DistributorRedisson redissonOptions = options.getDistributor().getRedisson();
final RedissonClient redissonClient = RedissonInstance.get().client(redissonOptions.getClientName());
return new RedissonIdSegmentDistributorFactory(redissonClient, redissonOptions.getTimeout());
}
throw new IllegalStateException("Unexpected value: " + type.name());
}
private IdSegmentDistributorDefinition asDistributorDefinition(String name, SegmentIdOptions.IdDefinition idDefinition) {
return new IdSegmentDistributorDefinition(namespace, name, idDefinition.getOffset(), idDefinition.getStep());
}
private SegmentId createSegment(SegmentIdOptions.IdDefinition idDefinition, IdSegmentDistributor idSegmentDistributor) {
final Long ttl = MoreObjects.firstNonNull(idDefinition.getTtl(), options.getTtl());
final SegmentIdOptions.Mode mode = MoreObjects.firstNonNull(idDefinition.getMode(), options.getMode());
final SegmentId segmentId;
if (SegmentIdOptions.Mode.DEFAULT == mode) {
segmentId = new DefaultSegmentId(ttl, idSegmentDistributor);
} else {
this.prefetchWorkerExecutorService = buildPrefetchWorkerExecutorService();
SegmentIdOptions.Chain chain = MoreObjects.firstNonNull(idDefinition.getChain(), options.getChain());
segmentId = new SegmentChainId(ttl, chain.getSafeDistance(), idSegmentDistributor, prefetchWorkerExecutorService);
}
final IdConverterDefinition converterDefinition = idDefinition.getConverter();
if (Objects.isNull(converterDefinition)) {
return segmentId;
}
IdConverter idConverter = ToStringIdConverter.INSTANCE;
switch (converterDefinition.getType()) {
case TO_STRING: {
break;
}
case RADIX: {
IdConverterDefinition.Radix radix = converterDefinition.getRadix();
idConverter = new Radix62IdConverter(radix.getPadStart(), radix.getCharSize());
break;
}
default:
throw new IllegalStateException("Unexpected value: " + converterDefinition.getType());
}
if (!Strings.isNullOrEmpty(converterDefinition.getPrefix())) {
idConverter = new PrefixIdConverter(converterDefinition.getPrefix(), idConverter);
}
if (!Strings.isNullOrEmpty(converterDefinition.getSuffix())) {
idConverter = new SuffixIdConverter(converterDefinition.getSuffix(), idConverter);
}
return new StringSegmentId(segmentId, idConverter);
}
@Override
public void initialize() {
this.distributorFactory = buildIdSegmentDistributorFactory();
}
@Override
public void destroy() {
if (prefetchWorkerExecutorService != null) {
prefetchWorkerExecutorService.shutdown();
}
}
public boolean enabled() {
return options.getEnabled();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy