Skip to content

Commit 0fb2e24

Browse files
committed
feat: first commit code
1 parent 73e970f commit 0fb2e24

27 files changed

+859
-0
lines changed

dataloader-plus-core/pom.xml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<groupId>me.lokic</groupId>
7+
<artifactId>dataloader-plus</artifactId>
8+
<version>1.0-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>dataloader-plus-core</artifactId>
13+
14+
<properties>
15+
<maven.compiler.source>8</maven.compiler.source>
16+
<maven.compiler.target>8</maven.compiler.target>
17+
<dataloader.version>2.2.3</dataloader.version>
18+
<logback.version>1.1.11</logback.version>
19+
<lombok.version>1.18.18</lombok.version>
20+
</properties>
21+
22+
<dependencies>
23+
<dependency>
24+
<groupId>com.graphql-java</groupId>
25+
<artifactId>java-dataloader</artifactId>
26+
<version>${dataloader.version}</version>
27+
</dependency>
28+
<dependency>
29+
<groupId>org.projectlombok</groupId>
30+
<artifactId>lombok</artifactId>
31+
<version>${lombok.version}</version>
32+
</dependency>
33+
<dependency>
34+
<groupId>ch.qos.logback</groupId>
35+
<artifactId>logback-classic</artifactId>
36+
<version>${logback.version}</version>
37+
</dependency>
38+
<dependency>
39+
<groupId>ch.qos.logback</groupId>
40+
<artifactId>logback-core</artifactId>
41+
<version>${logback.version}</version>
42+
</dependency>
43+
</dependencies>
44+
45+
</project>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package me.lokic.dataloaderplus.core;
2+
3+
4+
@FunctionalInterface
5+
public interface DataLoaderExecutor<R> {
6+
7+
R execute(ExDataLoaderRegistry registry);
8+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package me.lokic.dataloaderplus.core;
2+
3+
import org.dataloader.DataLoader;
4+
import org.dataloader.DataLoaderOptions;
5+
6+
import java.util.Map;
7+
import java.util.Optional;
8+
import java.util.concurrent.ConcurrentHashMap;
9+
10+
/**
11+
* DataLoader的工厂,基于 {@link MultiKeyMappedBatchLoader} 创建 {@link DataLoader}
12+
*/
13+
public class DataLoaderFactory {
14+
15+
private final Map<String, MultiKeyMappedBatchLoader<?, ?>> DATA_LOADER_CREATORS = new ConcurrentHashMap<>();
16+
17+
public void addMultiKeyMappedBatchLoader(MultiKeyMappedBatchLoader<?, ?> dataLoaderProvider) {
18+
DATA_LOADER_CREATORS.put(dataLoaderProvider.getClass().getName(), dataLoaderProvider);
19+
}
20+
21+
public DataLoader<?, ?> create(String name, DataLoaderOptions options) {
22+
MultiKeyMappedBatchLoader<?, ?> loader = Optional.ofNullable(DATA_LOADER_CREATORS.get(name))
23+
.orElseThrow(() -> new IllegalArgumentException("not found data loader supplier"));
24+
25+
return DataLoader.newMappedDataLoader(loader, options);
26+
}
27+
28+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package me.lokic.dataloaderplus.core;
2+
3+
import me.lokic.dataloaderplus.core.kits.CompletableFutures;
4+
import org.dataloader.DataLoaderOptions;
5+
6+
import java.util.concurrent.CompletableFuture;
7+
8+
public class DataLoaderTemplate {
9+
10+
private final DataLoaderOptions options;
11+
private final DataLoaderFactory factory;
12+
13+
14+
public DataLoaderTemplate(TemplateOptions options) {
15+
this.options = options.getOptions();
16+
this.factory = options.getFactory();
17+
}
18+
19+
20+
public <R> R using(DataLoaderExecutor<CompletableFuture<R>> executor) {
21+
ExDataLoaderRegistry registry = new ExDataLoaderRegistry(options, factory);
22+
return execute(registry, reg -> CompletableFutures.join(using(reg, executor)));
23+
}
24+
25+
26+
public <R> CompletableFuture<R> using(ExDataLoaderRegistry registry, DataLoaderExecutor<CompletableFuture<R>> executor) {
27+
return execute(registry, executor);
28+
}
29+
30+
private static <R> R execute(ExDataLoaderRegistry registry, DataLoaderExecutor<R> executor) {
31+
boolean isOutermost = false;
32+
try {
33+
if (RegistryHolder.getRegistry() == null) {
34+
isOutermost = true;
35+
RegistryHolder.setRegistry(registry);
36+
} else {
37+
if (RegistryHolder.getRegistry() != registry) {
38+
throw new IllegalArgumentException("register must be same");
39+
}
40+
}
41+
return executor.execute(registry);
42+
} finally {
43+
// 如果是最外层设置registry的方法,则最后需要清除registry
44+
if (isOutermost) {
45+
RegistryHolder.clear();
46+
}
47+
}
48+
}
49+
50+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package me.lokic.dataloaderplus.core;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import me.lokic.dataloaderplus.core.proxy.InterfaceProxy;
5+
import org.dataloader.DataLoader;
6+
import org.dataloader.DataLoaderOptions;
7+
import org.dataloader.DataLoaderRegistry;
8+
import org.dataloader.MappedBatchLoaderWithContext;
9+
10+
import java.util.List;
11+
import java.util.Map;
12+
import java.util.concurrent.ConcurrentHashMap;
13+
14+
/**
15+
* DataLoaderRegistry的扩展
16+
*/
17+
@Slf4j
18+
public class ExDataLoaderRegistry extends DataLoaderRegistry {
19+
20+
private final DataLoaderOptions options;
21+
private final DataLoaderFactory factory;
22+
23+
/**
24+
* 使用 @{@link me.lokic.dataloaderplus.core.annotation.DataLoaderService} 注释接口的实现类的缓存,避免重复创建
25+
*/
26+
private static final Map<Class<?>, Object> SERVICE_CACHE = new ConcurrentHashMap<>();
27+
28+
protected ExDataLoaderRegistry(DataLoaderOptions options, DataLoaderFactory factory) {
29+
this.options = options;
30+
this.factory = factory;
31+
}
32+
33+
/**
34+
* 获取或者创建对应的 {@link DataLoader}
35+
*
36+
* @param clazz
37+
* @param <K>
38+
* @param <V>
39+
* @return
40+
*/
41+
public <K, V> DataLoader<K, V> getDataLoader(Class<? extends MappedBatchLoaderWithContext<?, ?>> clazz) {
42+
return computeIfAbsent(clazz.getName(), key -> factory.create(key, options));
43+
}
44+
45+
/**
46+
* 获取 {@link me.lokic.dataloaderplus.core.annotation.DataLoaderService} 对应的 {@code serviceClazz} 的实现
47+
*
48+
* @param serviceClazz
49+
* @param <S>
50+
* @return
51+
*/
52+
@SuppressWarnings("unchecked")
53+
public static <S> S getService(Class<S> serviceClazz) {
54+
return (S) SERVICE_CACHE.computeIfAbsent(
55+
serviceClazz,
56+
InterfaceProxy::newInstance
57+
);
58+
}
59+
60+
61+
@Override
62+
public void dispatchAll() {
63+
List<DataLoader<?, ?>> dataLoaders = getDataLoaders();
64+
dataLoaders.forEach(DataLoader::dispatch);
65+
}
66+
67+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package me.lokic.dataloaderplus.core;
2+
3+
4+
import me.lokic.dataloaderplus.core.tuples.Tuple2;
5+
6+
public interface MultiKey2MappedBatchLoader<K1, K2, V> extends MultiKeyMappedBatchLoader<Tuple2<K1, K2>, V> {
7+
8+
9+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package me.lokic.dataloaderplus.core;
2+
3+
4+
import me.lokic.dataloaderplus.core.tuples.Tuple3;
5+
6+
public interface MultiKey3MappedBatchLoader<K1, K2, K3, V> extends MultiKeyMappedBatchLoader<Tuple3<K1, K2, K3>, V> {
7+
8+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package me.lokic.dataloaderplus.core;
2+
3+
import org.dataloader.MappedBatchLoaderWithContext;
4+
5+
/**
6+
* 用于对应一些多参数的方法,不需要去重新定义一个包含所有参数的参数对象
7+
* <p>
8+
* 如, <pre>{@code CompletableFuture<String> method(String p1, String p2)}</pre>
9+
* <p>
10+
* <a href="https://www.graphql-java.com/documentation/v16/batching/">graphql-java batching</a>
11+
*
12+
* @param <K>
13+
* @param <V>
14+
*/
15+
public interface MultiKeyMappedBatchLoader<K, V> extends MappedBatchLoaderWithContext<K, V> {
16+
17+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package me.lokic.dataloaderplus.core;
2+
3+
4+
/**
5+
* 以线程绑定的形式获取 {@link ExDataLoaderRegistry}
6+
*/
7+
public class RegistryHolder {
8+
9+
public static final ThreadLocal<ExDataLoaderRegistry> HOLDER = new ThreadLocal<>();
10+
11+
/**
12+
* 获取当前线程的CustomizeDataLoaderRegistry
13+
*
14+
* @return
15+
*/
16+
public static ExDataLoaderRegistry getRegistry() {
17+
return HOLDER.get();
18+
}
19+
20+
/**
21+
* 当前线程设置CustomizeDataLoaderRegistry
22+
*
23+
* @param registry
24+
*/
25+
public static void setRegistry(ExDataLoaderRegistry registry) {
26+
HOLDER.set(registry);
27+
}
28+
29+
/**
30+
* 针对当前线程的CustomizeDataLoaderRegistry,
31+
* 如果存在则调用 {@link ExDataLoaderRegistry#dispatchAll()}, 不存在则忽略该请求
32+
*/
33+
public static void tryDispatchAll() {
34+
ExDataLoaderRegistry registry = getRegistry();
35+
if (registry != null) {
36+
registry.dispatchAll();
37+
}
38+
}
39+
40+
/**
41+
* 清除当前线程的CustomizeDataLoaderRegistry
42+
*/
43+
public static void clear() {
44+
HOLDER.remove();
45+
}
46+
47+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package me.lokic.dataloaderplus.core;
2+
3+
import lombok.Builder;
4+
import lombok.Getter;
5+
import org.dataloader.DataLoaderOptions;
6+
7+
/**
8+
* {@link DataLoaderTemplate} 需要的配置
9+
*/
10+
@Getter
11+
@Builder
12+
public class TemplateOptions {
13+
14+
private static final DataLoaderOptions DEFAULT_OPTIONS = DataLoaderOptions.newOptions();
15+
public static final DataLoaderFactory DEFAULT_FACTORY = new DataLoaderFactory();
16+
17+
private final DataLoaderOptions options;
18+
private final DataLoaderFactory factory;
19+
20+
21+
public TemplateOptions(DataLoaderOptions options, DataLoaderFactory factory) {
22+
this.options = options == null ? DEFAULT_OPTIONS : options;
23+
this.factory = factory == null ? DEFAULT_FACTORY : factory;
24+
}
25+
26+
public DataLoaderOptions getOptions() {
27+
return options;
28+
}
29+
30+
public DataLoaderFactory getFactory() {
31+
return factory;
32+
}
33+
}

0 commit comments

Comments
 (0)