v1.5.3 修改了文档少数内容,但是还没写完,有人要一起写,所以push一下

This commit is contained in:
TcSnZh
2021-05-20 21:26:09 +08:00
parent 0ada03e413
commit fd6dc77ffd
30 changed files with 693 additions and 236 deletions

View File

@@ -1048,33 +1048,34 @@ SetNext<T, V> specialToNextWrapper(DependWrapperActionStrategy strategy, WorkerW
class Case6 {
private static WorkerWrapperBuilder<?, ?> builder(String id) {
return WorkerWrapper.<String, String>builder()
.id(id)
.worker((param, allWrappers) -> {
System.out.println("wrapper(id=" + id + ") is working");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
});
.id(id)
.worker((param, allWrappers) -> {
System.out.println("wrapper(id=" + id + ") is working");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
});
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
WorkerWrapper<?, ?> b = builder("B")
// 这里设置了不论a怎么样b都会快速失败。但是a设置的对wrapper的特殊策略把它覆盖了。
.depends((dependWrappers, thisWrapper, fromWrapper) ->
DependenceAction.FAST_FAIL
.fastFailException(ResultState.EXCEPTION, new RuntimeException("b 必定失败除非有上游wrapper救他"))
)
.build();
// 这里设置了不论a怎么样b都会快速失败。但是a设置的对wrapper的特殊策略把它覆盖了。
.depends((dependWrappers, thisWrapper, fromWrapper) ->
DependenceAction.FAST_FAIL
.fastFailException(ResultState.EXCEPTION, new RuntimeException("b 必定失败除非有上游wrapper救他"))
)
.callback(ICallback.PRINT_EXCEPTION_STACK_TRACE)
.build();
WorkerWrapper<?, ?> a = builder("A")
.setNext()
// a将会使b直接开始工作
// 若是去掉这行代码则b会失败
.specialToNextWrapper(fromWrapper -> DependenceAction.START_WORK.emptyProperty(), b)
.wrapper(b)
.end().build();
.setNext()
// a将会使b直接开始工作
// 若是去掉这行代码则b会失败
.specialToNextWrapper(fromWrapper -> DependenceAction.START_WORK.emptyProperty(), b)
.wrapper(b)
.end().build();
Async.beginWork(1000, a);
System.out.println(a.getWorkResult());
System.out.println(b.getWorkResult());
@@ -1394,9 +1395,9 @@ public interface WorkerWrapperBuilder<T, V> {
>```xml
><!-- 动态任务调度有需要的话可以引入。依赖fastjson请自行解决版本冲突 -->
><dependency>
> <artifactId>asyncTool-scheduling</artifactId>
> <groupId>com.jd.platform</groupId>
> <version>1.5.0-SNAPSHOT</version>
> <artifactId>asyncTool-scheduling</artifactId>
> <groupId>com.jd.platform</groupId>
> <version>1.5.0-SNAPSHOT</version>
></dependency>
>```
@@ -1439,14 +1440,14 @@ wrappers:[
// 而且不能与wrappers数组中其他的对象的id属性相同。即必须保证id唯一。
// 不允许undefined不允许null。
"id": "first",
// param即参数。请看《param属性格式
// param即参数。请看《param》
// useObjectModel代表value的值是否是“对象模型”。
// 允许undefined如果undefined则使用null。显然允许null
// 允许undefined或null视为{"useObjectModel": false,"value": null}
"param": {
"useObjectModel": false,
"value": "JackMa"
},
// 传入对象模型,请看《对象模型》
// 传入对象模型,请看《对象模型ObjectModel
// 不允许undefined或null
"worker": {
"sameObjectId": 1,
@@ -1457,8 +1458,9 @@ wrappers:[
"callback": {
"sameObjectId": 1
},
// wrapper依赖策略
// wrapper策略
// 允许undefined与null。如果为两者则使用com.jd.platform.async.wrapper.strategy.WrapperStrategy.DefaultWrapperStrategy
// 即"ALL_DEPENDENCIES_ALL_SUCCESS"与"CHECK_ONE_LEVEL"
"wrapperStrategy": {
// 传入{}键值对键名为即wrapper的id属性值为对象模型。
// 允许undefined和null两者之意与空键值对{}并无二致
@@ -1522,7 +1524,7 @@ wrappers:[
`useObjectModel`属性用于说明`value`属性的所代表的对象类型:
* 为false使用json所对应的类型。
* 为true使用《实现类对象规范》中的我们自定义的对象模型。
* 为true使用《对象模型`ObjectModel`》中的我们自定义的对象模型。
```json
{
@@ -1604,8 +1606,12 @@ beginWork: {
// 如果设置了该属性其他的属性均会被忽视。优先级低于constObjectName
"sameObjectId": 1,
// 提供类的全限定名字符串,将调用无参构造方法进行初始化
// 如果constObjectName设置了非null且非undefined值则此值允许为null或undefined
// 如果sameObjectId设置了非null且非undefined值则id相同的对象模型中允许且只允许一个值为非null或非undefined其他的都必须为null或undefined
"className": "your.package.name.YourKlassName",
// 初始化后,会根据该值来修改对象属性
// 允许为null或undefined表示不额外设置属性
"properties": {
// 其中的键值对为各字段名。这些字段需要有getter、setter方法。
"myIntegerField": 123123

View File

@@ -29,7 +29,7 @@ public interface ICallback<T, V> {
/**
* 提供常量选项:打印异常信息,跳过时的异常{@link SkippedException}不会打印。
*/
ICallback<?, ?> PRINT_EXCEPTION_STACK_TRACE = new ICallback<Object, Object>() {
ICallback PRINT_EXCEPTION_STACK_TRACE = new ICallback<Object, Object>() {
@Override
public void result(boolean success, Object param, WorkResult<Object> workResult) {
Exception ex = workResult.getEx();

View File

@@ -0,0 +1,75 @@
package beforev14.depend;
import java.util.Map;
import com.jd.platform.async.executor.Async;
import com.jd.platform.async.worker.WorkResult;
import com.jd.platform.async.wrapper.WorkerWrapper;
/**
* @author sjsdfg
* @since 2020/6/14
*/
@SuppressWarnings({"deprecation", "RedundantStringFormatCall"})
class LambdaTest {
public static void main(String[] args) throws Exception {
WorkerWrapper<WorkResult<User>, String> workerWrapper2 = new WorkerWrapper.Builder<WorkResult<User>, String>()
.worker((WorkResult<User> result, Map<String, WorkerWrapper<?, ?>> allWrappers) -> {
System.out.println("par2的入参来自于par1 " + result.getResult());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return result.getResult().getName();
})
.callback((boolean success, WorkResult<User> param, WorkResult<String> workResult) ->
System.out.println(String.format("thread is %s, param is %s, result is %s", Thread.currentThread().getName(), param, workResult)))
.id("third")
.build();
WorkerWrapper<WorkResult<User>, User> workerWrapper1 = new WorkerWrapper.Builder<WorkResult<User>, User>()
.worker((WorkResult<User> result, Map<String, WorkerWrapper<?, ?>> allWrappers) -> {
System.out.println("par1的入参来自于par0 " + result.getResult());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new User("user1");
})
.callback((boolean success, WorkResult<User> param, WorkResult<User> workResult) ->
System.out.println(String.format("thread is %s, param is %s, result is %s", Thread.currentThread().getName(), param, workResult)))
.id("second")
.next(workerWrapper2)
.build();
WorkerWrapper<String, User> workerWrapper = new WorkerWrapper.Builder<String, User>()
.worker((String object, Map<String, WorkerWrapper<?,?>> allWrappers) -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new User("user0");
})
.param("0")
.id("first")
.next(workerWrapper1, true)
.callback((boolean success, String param, WorkResult<User> workResult) ->
System.out.println(String.format("thread is %s, param is %s, result is %s", Thread.currentThread().getName(), param, workResult)))
.build();
//虽然尚未执行但是也可以先取得结果的引用作为下一个任务的入参。V1.2前写法,需要手工给
//V1.3后不用给wrapper setParam了直接在worker的action里自行根据id获取即可.参考dependnew包下代码
WorkResult<User> result = workerWrapper.getWorkResult();
WorkResult<User> result1 = workerWrapper1.getWorkResult();
workerWrapper1.setParam(result);
workerWrapper2.setParam(result1);
Async.beginWork(3500, workerWrapper);
System.out.println(workerWrapper2.getWorkResult());
Async.shutDown();
}
}

View File

@@ -1,5 +1,6 @@
package v15.cases;
import com.jd.platform.async.callback.ICallback;
import com.jd.platform.async.executor.Async;
import com.jd.platform.async.worker.ResultState;
import com.jd.platform.async.wrapper.WorkerWrapper;
@@ -29,12 +30,14 @@ class Case6 {
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
//noinspection unchecked
WorkerWrapper<?, ?> b = builder("B")
// 这里设置了不论a怎么样b都会快速失败。但是a设置的对wrapper的特殊策略把它覆盖了。
.depends((dependWrappers, thisWrapper, fromWrapper) ->
DependenceAction.FAST_FAIL
.fastFailException(ResultState.EXCEPTION, new RuntimeException("b 必定失败除非有上游wrapper救他"))
)
.callback(ICallback.PRINT_EXCEPTION_STACK_TRACE)
.build();
WorkerWrapper<?, ?> a = builder("A")
.setNext()

View File

@@ -0,0 +1,9 @@
package com.jd.platform.async.scheduling;
/**
* 入口方法类
*
* @author tcsnzh[zh.jobs@foxmail.com] create this in 2021/5/20-上午12:05
*/
public class AsyncScheduling {
}

View File

@@ -1,40 +0,0 @@
package com.jd.platform.async.scheduling;
import com.jd.platform.async.scheduling.model.SchedulingDrawingsModel;
/**
* @author create by TcSnZh on 2021/5/17-上午1:22
*/
public class DefaultSchedulingJsonParser implements SchedulingJsonParser {
// ========== singleton instance ==========
/**
* 私有构造方法,需要通过{@link #getInstance()}方法获取单例。
*/
private DefaultSchedulingJsonParser() {
}
/**
* 获取单例
*/
public static DefaultSchedulingJsonParser getInstance() {
return instance;
}
private static final DefaultSchedulingJsonParser instance = new DefaultSchedulingJsonParser();
// ========== public methods ==========
@Override
public SchedulingDrawingsModel parse(String json) {
// todo
return null;
}
// ========== util methods ==========
}

View File

@@ -1,24 +0,0 @@
package com.jd.platform.async.scheduling;
import com.jd.platform.async.scheduling.model.SchedulingDrawingsModel;
/**
* @author create by TcSnZh on 2021/5/17-下午7:22
*/
public interface SchedulingJsonParser {
/**
* 解析json为图纸对象
*
* @param json json
* @return 返回图纸对象接口
*/
SchedulingDrawingsModel parse(String json);
/**
* 默认实现
*/
static SchedulingJsonParser getDefaultInstance() {
return DefaultSchedulingJsonParser.getInstance();
}
}

View File

@@ -0,0 +1,219 @@
package com.jd.platform.async.scheduling.drawings;
import com.jd.platform.async.scheduling.exception.IllegalSchedulingPropertyException;
import com.jd.platform.async.scheduling.model.ObjectModel;
import com.jd.platform.async.scheduling.model.SchedulingDrawingsModel;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
/**
* @author tcsnzh[zh.jobs@foxmail.com] create this in 2021/5/20-下午4:38
*/
class DefaultSchedulingDrawingsParser implements SchedulingDrawingsParser {
static final DefaultSchedulingDrawingsParser instance = new DefaultSchedulingDrawingsParser();
@Override
public SchedulingDrawings parseDrawings(final SchedulingDrawingsModel model) throws IllegalSchedulingPropertyException {
final SchedulingDrawingsImpl drawings = new SchedulingDrawingsImpl();
final String drawingsName = model.getDrawingsName();
drawings.setName(drawingsName == null ? UUID.randomUUID().toString() : drawingsName);
final List<SchedulingDrawingsModel.WrapperModel> wrappers =
propRequireNotNull(model.getWrappers(), "wrappers");
// 缓存WrapperModelMap并检查id是否唯一
final LinkedHashMap<String, SchedulingDrawingsModel.WrapperModel> wrapperId2ModelMap =
new LinkedHashMap<>(wrappers.size());
for (int i = 0; i < wrappers.size(); i++) {
final SchedulingDrawingsModel.WrapperModel wrapper = wrappers.get(i);
// 检查id是否重复并存入map
final String id = propRequireNotNull(wrapper.getId(), "wrappers[" + i + "].id");
if (null != wrapperId2ModelMap.put(id, wrapper)) {
throw new IllegalSchedulingPropertyException("Wrapper id \"" + id + "\" duplicate .");
}
}
// 缓存ObjectModelMap并检查
final Map<Long, ObjectModel> wrappersObjectModelMap = wrappersObjectModelMap(wrappers, wrapperId2ModelMap.keySet());
// 构造wrapperFactory
// todo 还没写完
return null;
}
// ========== private method ==========
// ========== util static methods ==========
/**
* 缓存sameObjectId有有效值的ObjectModel并检查
* 1. ObjectModel参数是否符合格式规范
* 2. wrapperStrategy.dependOnUpWrapperStrategyMapper 的键id是否存在于wrappers的id属性集合中
*
* @param wrappers wrappers属性值的列表
* @param wrappersIdSet 已经包括wrappers列表中所有id属性的Set
* @return 返回Map的键为ObjectModel的sameObjectId值为ObjectModel
* @throws IllegalSchedulingPropertyException 格式错误,抛出异常
*/
protected static Map<Long, ObjectModel> wrappersObjectModelMap(
List<SchedulingDrawingsModel.WrapperModel> wrappers,
Set<String> wrappersIdSet
) throws IllegalSchedulingPropertyException {
final LinkedHashMap<Long, ObjectModel> objectModelMap = new LinkedHashMap<>();
for (final SchedulingDrawingsModel.WrapperModel wrapper : wrappers) {
final String prefixPropName = "wrappers[id=" + wrapper.getId() + "]";
final SchedulingDrawingsModel.WrapperModel.ParamModel param = wrapper.getParam();
// 将param参数中的objectModel检查并存入map
if (param != null && Boolean.TRUE.equals(
propRequireNotNull(param.getUseObjectModel(), prefixPropName + ".param.useObjectModel")
)) {
final Object value = param.getValue();
if (value instanceof ObjectModel) {
checkAndPutObjectModelHasDifferentId(
(ObjectModel) value,
objectModelMap,
prefixPropName + ".param.value");
} else {
throw IllegalSchedulingPropertyException.illegalFieldParameter(
prefixPropName + ".param.value",
value,
"it should instanceof ObjectModel."
);
}
}
// 检查并缓存worker的objectModel
final String _workerPropName = prefixPropName + ".worker";
checkAndPutObjectModelHasDifferentId(propRequireNotNull(wrapper.getWorker(), _workerPropName),
objectModelMap, _workerPropName);
// 检查并缓存callback的objectModel
checkAndPutObjectModelHasDifferentId(wrapper.getCallback(), objectModelMap, prefixPropName + ".callback");
// 检查wrapperStrategy
final SchedulingDrawingsModel.WrapperModel.WrapperStrategyModel wrapperStrategy = wrapper.getWrapperStrategy();
if (wrapperStrategy != null) {
// 检查并缓存dependOnUpWrapperStrategyMapper
final Map<String, ObjectModel> dependOnUpWrapperStrategyMapper =
wrapperStrategy.getDependOnUpWrapperStrategyMapper();
if (dependOnUpWrapperStrategyMapper != null) {
for (Map.Entry<String, ObjectModel> entry :
dependOnUpWrapperStrategyMapper.entrySet()) {
final String wrapperId = entry.getKey();
final String mapperPropName = prefixPropName + ".wrapperStrategy.dependOnUpWrapperStrategyMapper";
if (!wrappersIdSet.contains(wrapperId)) {
throw IllegalSchedulingPropertyException.illegalFieldParameter(
mapperPropName,
dependOnUpWrapperStrategyMapper,
"the key(wrapperId) of \"" + wrapperId + "\n not in wrappers list"
);
}
checkAndPutObjectModelHasDifferentId(
propRequireNotNull(entry.getValue(), mapperPropName),
objectModelMap,
mapperPropName
);
}
}
// 检查并缓存dependenceStrategy
final ObjectModel dependenceStrategy = wrapperStrategy.getDependenceStrategy();
final String dependenceStrategyPropName = prefixPropName + ".wrapperStrategy.dependenceStrategy";
if (dependenceStrategy != null) {
checkAndPutObjectModelHasDifferentId(
dependenceStrategy,
objectModelMap,
dependenceStrategyPropName
);
}
// 检查并缓存skipStrategy
final String skipStrategyPropName = prefixPropName + ".wrapperStrategy.skipStrategy";
final ObjectModel skipStrategy = wrapperStrategy.getSkipStrategy();
if (skipStrategy != null) {
checkAndPutObjectModelHasDifferentId(
skipStrategy,
objectModelMap,
skipStrategyPropName);
}
}
}
return objectModelMap;
}
/**
* 本方法为{@link #wrappersObjectModelMap(List, Set)}的子方法。
* 用于抽取ObjectModel格式的判断逻辑。
*
* @param objectModel 对象模型
* @param objectModelMap 要存入的Map
* @param propNameSup 属性名
* @throws IllegalSchedulingPropertyException 格式错误,抛出异常
*/
private static void checkAndPutObjectModelHasDifferentId(ObjectModel objectModel,
Map<Long, ObjectModel> objectModelMap,
Supplier<String> propNameSup)
throws IllegalSchedulingPropertyException {
final String constObjectName = objectModel.getConstObjectName();
if (constObjectName != null) {
if (!ObjectModel.containConstObject(constObjectName)) {
final String propName;
throw new IllegalSchedulingPropertyException(
(propNameSup == null || (propName = propNameSup.get()) == null ? "" : "Property " + propName + " ") +
"ObjectModel doesn't have a constant object named \""
+ constObjectName + "\" . objectModel is " + objectModel);
}
return;
}
final Long sameObjectId = objectModel.getSameObjectId();
if (sameObjectId != null) {
final Map<String, Object> properties = objectModel.getProperties();
if (objectModelMap.containsKey(sameObjectId) &&
// 同一id的对象其他属性不允许重复设置
(objectModel.getClassName() != null || properties != null && !properties.isEmpty())) {
throw new IllegalSchedulingPropertyException(
"The objectModel which sameObjectId=" + sameObjectId +
" cannot be set \"className\" or \"properties\" again . the two in conflict is " +
objectModel + " and " + objectModelMap.get(sameObjectId) + " ."
);
}
objectModelMap.put(sameObjectId, objectModel);
return;
}
propRequireNotNull(objectModel.getClassName(), propNameSup.get());
}
private static void checkAndPutObjectModelHasDifferentId(ObjectModel objectModel,
Map<Long, ObjectModel> objectModelMap,
String propName)
throws IllegalSchedulingPropertyException {
checkAndPutObjectModelHasDifferentId(objectModel, objectModelMap, () -> propName);
}
/**
* 检查属性是否为null
*
* @param prop 属性值
* @param propName 属性名
* @param reason 原因说明。
* 默认值为{@code "it's not allow null"},用于{@link #propRequireNotNull(Object, String)}与
* {@link #propRequireNotNull(Object, Supplier)}方法中。
* @param <T> 属性值泛型
* @return 返回传入的属性值,供继续调用
* @throws IllegalSchedulingPropertyException 如果属性为null抛出异常
*/
private static <T> T propRequireNotNull(T prop, Supplier<String> propName, Supplier<String> reason)
throws IllegalSchedulingPropertyException {
if (prop == null) {
throw IllegalSchedulingPropertyException.illegalFieldParameter(
propName.get(),
null,
reason.get()
);
}
return prop;
}
private static <T> T propRequireNotNull(T prop, String propName) throws IllegalSchedulingPropertyException {
return propRequireNotNull(prop, () -> propName);
}
private static <T> T propRequireNotNull(T prop, Supplier<String> propName) throws IllegalSchedulingPropertyException {
return propRequireNotNull(prop, propName, () -> "it's not allow null");
}
}

View File

@@ -0,0 +1,10 @@
package com.jd.platform.async.scheduling.drawings;
/**
* 工厂图纸,可从模型转化而来
*
* @author tcsnzh[zh.jobs@foxmail.com] create this in 2021/5/20-上午12:00
*/
public interface SchedulingDrawings {
}

View File

@@ -0,0 +1,16 @@
package com.jd.platform.async.scheduling.drawings;
/**
* @author tcsnzh[zh.jobs@foxmail.com] create this in 2021/5/20-下午4:39
*/
class SchedulingDrawingsImpl implements SchedulingDrawings{
protected String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@@ -0,0 +1,18 @@
package com.jd.platform.async.scheduling.drawings;
import com.jd.platform.async.scheduling.exception.IllegalSchedulingPropertyException;
import com.jd.platform.async.scheduling.model.SchedulingDrawingsModel;
/**
* @author tcsnzh[zh.jobs@foxmail.com] create this in 2021/5/20-上午12:03
*/
public interface SchedulingDrawingsParser {
/**
* 从模型转化为图纸
*/
SchedulingDrawings parseDrawings(SchedulingDrawingsModel model) throws IllegalSchedulingPropertyException;
default SchedulingDrawingsParser getDefaultInstance() {
return DefaultSchedulingDrawingsParser.instance;
}
}

View File

@@ -1,25 +0,0 @@
package com.jd.platform.async.scheduling.exception;
/**
* @author tcsnzh[zh.jobs@foxmail.com] create this in 2021/5/19-下午7:20
*/
public class IllegalConfigException extends Exception{
public IllegalConfigException() {
}
public IllegalConfigException(String message) {
super(message);
}
public IllegalConfigException(String message, Throwable cause) {
super(message, cause);
}
public IllegalConfigException(Throwable cause) {
super(cause);
}
public IllegalConfigException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@@ -0,0 +1,25 @@
package com.jd.platform.async.scheduling.exception;
/**
* @author tcsnzh[zh.jobs@foxmail.com] create this in 2021/5/19-下午7:20
*/
public class IllegalSchedulingException extends Exception{
public IllegalSchedulingException() {
}
public IllegalSchedulingException(String message) {
super(message);
}
public IllegalSchedulingException(String message, Throwable cause) {
super(message, cause);
}
public IllegalSchedulingException(Throwable cause) {
super(cause);
}
public IllegalSchedulingException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@@ -0,0 +1,55 @@
package com.jd.platform.async.scheduling.exception;
/**
* @author tcsnzh[zh.jobs@foxmail.com] create this in 2021/5/20-下午4:59
*/
public class IllegalSchedulingPropertyException extends IllegalSchedulingException {
public IllegalSchedulingPropertyException(String message) {
super(message);
}
public IllegalSchedulingPropertyException(String message, Throwable cause) {
super(message, cause);
}
/**
* json反序列化失败
*
* @param json json
* @param cause 原因
* @return 返回异常
*/
public static IllegalSchedulingPropertyException deserializeJsonFailed(String json,
Throwable cause) {
return new IllegalSchedulingPropertyException(
"Json deserialize to model failed , please check properties and see QuickStart.md . the json is : " + json,
cause
);
}
/**
* 如果json反序列化有效但是不符合规范。
*
* @param illegalFieldName 无效的属性名
* @param fieldValue 属性的值
* @param reason 原因
* @param cause 引发异常可以为null
* @return 返回异常
*/
public static IllegalSchedulingPropertyException illegalFieldParameter(String illegalFieldName,
Object fieldValue,
String reason,
Throwable cause) {
return new IllegalSchedulingPropertyException(
"Property" + illegalFieldName + " does not conform to specification. value is : " + fieldValue
+ " . because " + reason, cause
);
}
public static IllegalSchedulingPropertyException illegalFieldParameter(String illegalFieldName,
Object fieldValue,
String reason) {
return illegalFieldParameter(illegalFieldName, fieldValue, reason, null);
}
}

View File

@@ -1,22 +1,19 @@
package com.jd.platform.async.scheduling;
import sun.misc.Unsafe;
package com.jd.platform.async.scheduling.factory;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;
/**
* 调度工厂传入图纸生成一组wrapper
*
* @author create by TcSnZh on 2021/5/17-上午1:11
*/
public class SchedulingFactory {
private final String factoryName;
public abstract class AbstractSchedulingFactory {
protected final String factoryName;
/**
* 无参构造默认使用 {@code 栈信息<自增long值> } 作为工厂名
*/
public SchedulingFactory() {
public AbstractSchedulingFactory() {
this(Thread.currentThread().getStackTrace()[2] + "<" + defaultFactoryNameCount.getAndIncrement() + ">");
}
@@ -25,7 +22,7 @@ public class SchedulingFactory {
*
* @param factoryName 工厂名
*/
public SchedulingFactory(String factoryName) {
public AbstractSchedulingFactory(String factoryName) {
this.factoryName = factoryName;
}

View File

@@ -0,0 +1,33 @@
package com.jd.platform.async.scheduling.model;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.jd.platform.async.scheduling.exception.IllegalSchedulingPropertyException;
import static com.alibaba.fastjson.parser.Feature.*;
/**
* @author create by TcSnZh on 2021/5/17-上午1:22
*/
class DefaultSchedulingJsonModelParser implements SchedulingJsonModelParser {
// ========== singleton instance ==========
static final DefaultSchedulingJsonModelParser instance = new DefaultSchedulingJsonModelParser();
// ========== public methods ==========
@Override
public SchedulingDrawingsModel parseToModel(String json) throws IllegalSchedulingPropertyException {
try {
return JSONObject.parseObject(json, SchedulingDrawingsModel.class, DEFAULT_FEATURES);
} catch (Exception e) {
throw IllegalSchedulingPropertyException.deserializeJsonFailed(json, e);
}
}
static Feature[] DEFAULT_FEATURES = {
AllowComment, AllowUnQuotedFieldNames, AllowSingleQuotes, SafeMode, ErrorOnEnumNotMatch
};
// ========== util methods ==========
}

View File

@@ -11,7 +11,6 @@ import java.util.Map;
/**
* @author tcsnzh[zh.jobs@foxmail.com] create this in 2021/5/19-下午7:51
*/
@SuppressWarnings("unused")
public class ObjectModel {
protected String constObjectName;
protected String className;
@@ -57,6 +56,16 @@ public class ObjectModel {
return constObjects;
}
@Override
public String toString() {
return "ObjectModel{" +
"constObjectName='" + constObjectName + '\'' +
", className='" + className + '\'' +
", sameObjectId=" + sameObjectId +
", properties=" + properties +
'}';
}
// static constants
private static final Map<String, Object> constObjects;
@@ -73,6 +82,10 @@ public class ObjectModel {
constObjects.put("PRINT_EXCEPTION_STACK_TRACE", ICallback.PRINT_EXCEPTION_STACK_TRACE);
}
public static boolean containConstObject(String name) {
return constObjects.containsKey(name);
}
public static <T> T getConstObject(String name) {
//noinspection unchecked
return (T) constObjects.get(name);

View File

@@ -2,6 +2,7 @@ package com.jd.platform.async.scheduling.model;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.concurrent.TimeUnit;
/**
@@ -159,6 +160,22 @@ public class SchedulingDrawingsModel {
public void setExtendConfig(String extendConfig) {
this.extendConfig = extendConfig;
}
@Override
public String toString() {
return "WrapperModel{" +
"id='" + id + '\'' +
", param=" + param +
", worker=" + worker +
", callback=" + callback +
", wrapperStrategy=" + wrapperStrategy +
", allowInterrupt=" + allowInterrupt +
", enableTimeout=" + enableTimeout +
", timeoutLength=" + timeoutLength +
", timeUnit=" + timeUnit +
", extendConfig='" + extendConfig + '\'' +
'}';
}
}
public static class RelationModel {
@@ -180,6 +197,14 @@ public class SchedulingDrawingsModel {
public void setTo(Object to) {
this.to = to;
}
@Override
public String toString() {
return "RelationModel{" +
"from=" + from +
", to=" + to +
'}';
}
}
public static class BeginWorkModel {
@@ -219,6 +244,16 @@ public class SchedulingDrawingsModel {
public void setExecutor(String executor) {
this.executor = executor;
}
@Override
public String toString() {
return "BeginWorkModel{" +
"timeoutLength=" + timeoutLength +
", timeoutUnit=" + timeoutUnit +
", wrappers=" + wrappers +
", executor='" + executor + '\'' +
'}';
}
}
public String getDrawingsName() {
@@ -252,4 +287,14 @@ public class SchedulingDrawingsModel {
public void setBeginWork(BeginWorkModel beginWork) {
this.beginWork = beginWork;
}
@Override
public String toString() {
return "SchedulingDrawingsModel{" +
"drawingsName='" + drawingsName + '\'' +
", wrappers=" + wrappers +
", relations=" + relations +
", beginWork=" + beginWork +
'}';
}
}

View File

@@ -0,0 +1,23 @@
package com.jd.platform.async.scheduling.model;
import com.jd.platform.async.scheduling.exception.IllegalSchedulingPropertyException;
/**
* @author create by TcSnZh on 2021/5/17-下午7:22
*/
public interface SchedulingJsonModelParser {
/**
* 解析json为配置模型对象
*
* @param json json
* @return 返回图纸对象接口
*/
SchedulingDrawingsModel parseToModel(String json) throws IllegalSchedulingPropertyException;
/**
* 默认实现
*/
static SchedulingJsonModelParser getDefaultInstance() {
return DefaultSchedulingJsonModelParser.instance;
}
}

View File

@@ -10,7 +10,4 @@ public abstract class ReflectUtil {
private ReflectUtil() {
}
public static void foreachField(Class<?> clazz) {
}
}

View File

@@ -1,14 +0,0 @@
package schedulingtest.cases;
import com.jd.platform.async.scheduling.SchedulingJsonParser;
import schedulingtest.FileStringReader;
/**
* @author create by TcSnZh on 2021/5/17-上午11:49
*/
class Case1 {
public static void main(String[] args) {
String json = FileStringReader.readFile("test.json");
System.out.println(SchedulingJsonParser.getDefaultInstance().parse(json));
}
}

View File

@@ -1,4 +1,4 @@
package schedulingtest;
package v15.schedulingtest;
import java.io.*;
import java.util.Objects;
@@ -34,8 +34,4 @@ public class FileStringReader {
}
}
}
public static void main(String[] args) {
System.out.println("test readFile : \n\n" + readFile("case1_1.json"));
}
}

View File

@@ -0,0 +1,15 @@
package v15.schedulingtest.cases.case1;
import com.jd.platform.async.scheduling.exception.IllegalSchedulingException;
import com.jd.platform.async.scheduling.model.SchedulingJsonModelParser;
import v15.schedulingtest.FileStringReader;
/**
* @author create by TcSnZh on 2021/5/17-上午11:49
*/
class Case1 {
public static void main(String[] args) throws IllegalSchedulingException {
String json = FileStringReader.readFile("v15/case1_1.json");
System.out.println(SchedulingJsonModelParser.getDefaultInstance().parseToModel(json));
}
}

View File

@@ -1,19 +1,16 @@
package schedulingtest.impl;
package v15.schedulingtest.cases.case1;
import com.jd.platform.async.callback.ICallback;
import com.jd.platform.async.callback.IWorker;
import com.jd.platform.async.worker.WorkResult;
import com.jd.platform.async.wrapper.WorkerWrapper;
import schedulingtest.entity.User;
import java.util.Map;
import static schedulingtest.impl.SelectUserByName.HundredMillion;
/**
* @author create by TcSnZh on 2021/5/17-上午2:04
*/
public class PayTaxes implements IWorker<String, User>, ICallback<String, User> {
class PayTaxes implements IWorker<String, User>, ICallback<String, User> {
/**
* 富人资产>1亿收30%的税穷人发1000块
*/
@@ -21,7 +18,7 @@ public class PayTaxes implements IWorker<String, User>, ICallback<String, User>
public User action(String selectUserWrapperId, Map<String, WorkerWrapper<?, ?>> allWrappers) {
User u = (User) allWrappers.get(selectUserWrapperId).getWorkResult().getResult();
double money;
if ((money = u.getMoney()) > 1.00 * HundredMillion) {
if ((money = u.getMoney()) > 1.00 * SelectUserByName.HundredMillion) {
u.setMoney(money * 0.7);
} else {
u.setMoney(money + 1000);

View File

@@ -1,4 +1,4 @@
package schedulingtest;
package v15.schedulingtest.cases.case1;
import com.jd.platform.async.callback.IWorker;
import com.jd.platform.async.wrapper.WorkerWrapper;
@@ -8,7 +8,7 @@ import java.util.Map;
/**
* @author create by TcSnZh on 2021/5/17-上午2:31
*/
public class PrintParam implements IWorker<Object, Object> {
class PrintParam implements IWorker<Object, Object> {
@Override
public Object action(Object object, Map<String, WorkerWrapper<?, ?>> allWrappers) {
System.out.println("print param : " + object);

View File

@@ -1,13 +1,11 @@
package schedulingtest.impl;
package v15.schedulingtest.cases.case1;
import com.jd.platform.async.callback.ICallback;
import com.jd.platform.async.callback.IWorker;
import com.jd.platform.async.worker.WorkResult;
import com.jd.platform.async.wrapper.WorkerWrapper;
import schedulingtest.entity.User;
import v15.schedulingtest.cases.case1.User;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
@@ -15,7 +13,7 @@ import java.util.concurrent.atomic.AtomicInteger;
/**
* @author create by TcSnZh on 2021/5/17-上午1:33
*/
public class SelectUserByName implements IWorker<String, User>, ICallback<String, User> {
class SelectUserByName implements IWorker<String, User>, ICallback<String, User> {
public static final long HundredMillion = 100000000;
private static final Map<String, User> datasource;

View File

@@ -1,9 +1,9 @@
package schedulingtest.entity;
package v15.schedulingtest.cases.case1;
/**
* @author create by TcSnZh on 2021/5/17-上午1:33
*/
public class User {
class User {
private String name;
private int age;
private double money;

View File

@@ -1,61 +0,0 @@
{
"drawingsName": "case1_1",
"wrappers": [
{
"id": "first",
"param": "JackMa",
"worker": "schedulingtest.impl.SelectUserByName",
"callback": {
"className:": "schedulingtest.impl.SelectUserByName"
},
"wrapperStrategy": {
"dependWrapperStrategyMapper": null,
"dependMustStrategyMapper": null,
"dependenceStrategy": "ALL_DEPENDENCIES_ALL_SUCCESS",
"skipStrategy": "CHECK_ONE_LEVEL"
},
"allowInterrupt": true,
"enableTimeout": true,
"timeoutLength": 50,
"timeoutUnit": "TimeUnit.MILLISECONDS"
},
{
"id": "second",
"workerAndCallback": "schedulingtest.impl.PayTaxes"
},
{
"id": "third",
"__extend": "second"
},
{
"id": "fourth",
"worker": "schedulingtest.impl.PrintParam",
"wrapperStrategy": {
"dependenceStrategy": "ALL_DEPENDENCIES_ALL_SUCCESS"
}
}
],
"relations": [
{
"from": "first",
"to": "second"
},
{
"from": "second",
"to": "fourth"
},
{
"from": "third",
"to": "fourth"
}
],
"beginWork": {
"timeoutLength": 100,
"timeoutUnit": "TimeUnit.MILLISECONDS",
"wrappers": [
"first"
],
"executor": "COMMON_POOL"
},
"objects": []
}

View File

@@ -1,9 +0,0 @@
{
"drawingsName": "case1_1",
"wrappers": [
{
"id": "first",
"worker": "schedulingtest.impl.SelectUserByName"
}
]
}

View File

@@ -0,0 +1,80 @@
{
"drawingsName": "case1_1",
"wrappers": [
{
"id": "first",
"param": {
"useObjectModel": false,
"value": "JackMa"
},
"worker": {
"sameObjectId": 1,
"className:": "schedulingtest.impl.SelectUserByName"
},
"callback": {
"sameObjectId": 1
},
"wrapperStrategy": {
"dependOnUpWrapperStrategyMapper": null,
"dependenceStrategy": {
"constObjectName": "ALL_DEPENDENCIES_ALL_SUCCESS"
},
"skipStrategy": {
"constObjectName": "CHECK_ONE_LEVEL"
}
},
"allowInterrupt": true,
"enableTimeout": true,
"timeoutLength": 50,
"timeoutUnit": "TimeUnit.MILLISECONDS"
},
{
"id": "second",
"worker": {
"sameObjectId": 2,
"className:": "schedulingtest.impl.SelectUserByName"
},
"callback": {
"sameObjectId": 2
}
},
{
"id": "third",
"__extend": "second"
},
{
"id": "fourth",
"worker": {
"sameObjectId": 2,
"className:": "schedulingtest.impl.PrintParam"
},
"wrapperStrategy": {
"dependenceStrategy": {
"constObjectName": "ALL_DEPENDENCIES_ALL_SUCCESS"
}
}
}
],
"relations": [
{
"from": "first",
"to": "second"
},
{
"from": "second",
"to": "fourth"
},
{
"from": "third",
"to": "fourth"
}
],
"beginWork": {
"timeoutLength": 100,
"timeoutUnit": "MILLISECONDS",
"wrappers": [
"first"
],
"executor": "COMMON_POOL"
}
}