Full Code of alibaba/easy-retry for AI

main 86b831c436bc cached
140 files
152.9 KB
46.2k tokens
390 symbols
1 requests
Download .txt
Showing preview only (202K chars total). Download the full file or copy to clipboard to get everything.
Repository: alibaba/easy-retry
Branch: main
Commit: 86b831c436bc
Files: 140
Total size: 152.9 KB

Directory structure:
gitextract_y0h1aiip/

├── .editorconfig
├── .github/
│   └── workflows/
│       └── maven.yml
├── .gitignore
├── LICENSE
├── README.md
├── config/
│   └── intellij-java-google-style.xml
├── easy-retry-common/
│   ├── pom.xml
│   └── src/
│       └── main/
│           └── java/
│               └── com/
│                   └── alibaba/
│                       └── easyretry/
│                           └── common/
│                               ├── AbstractResultPredicate.java
│                               ├── AbstractRetrySyncExecutor.java
│                               ├── EasyRetryPredicate.java
│                               ├── Invocation.java
│                               ├── RetryConfiguration.java
│                               ├── RetryContainer.java
│                               ├── RetryContext.java
│                               ├── RetryExecutor.java
│                               ├── RetryIdentify.java
│                               ├── RetryLifecycle.java
│                               ├── RetrySyncExecutor.java
│                               ├── SCallable.java
│                               ├── SimpleMethodInvocation.java
│                               ├── access/
│                               │   ├── RetrySerializerAccess.java
│                               │   ├── RetryStrategyAccess.java
│                               │   └── RetryTaskAccess.java
│                               ├── constant/
│                               │   ├── enums/
│                               │   │   ├── HandleResultEnum.java
│                               │   │   ├── RetryTaskStatusEnum.java
│                               │   │   └── RetryTypeEnum.java
│                               │   └── package-info.java
│                               ├── entity/
│                               │   └── RetryTask.java
│                               ├── event/
│                               │   ├── RetryEvent.java
│                               │   ├── RetryEventMulticaster.java
│                               │   ├── RetryListener.java
│                               │   ├── before/
│                               │   │   ├── AfterSaveBeforeRetryEvent.java
│                               │   │   ├── BeforeRetryEvent.java
│                               │   │   └── PrepSaveBeforeRetryEvent.java
│                               │   └── on/
│                               │       ├── FailureOnRetryEvent.java
│                               │       ├── OnRetryEvent.java
│                               │       ├── StopOnRetryEvent.java
│                               │       └── SuccessOnRetryEvent.java
│                               ├── filter/
│                               │   ├── AbstractRetryFilter.java
│                               │   ├── RetryFilter.java
│                               │   ├── RetryFilterDiscover.java
│                               │   ├── RetryFilterInvocation.java
│                               │   ├── RetryFilterInvocationHandler.java
│                               │   ├── RetryFilterRegister.java
│                               │   ├── RetryFilterRegisterHandler.java
│                               │   └── RetryFilterResponse.java
│                               ├── processor/
│                               │   ├── AsyncPersistenceProcessor.java
│                               │   ├── RetryProcessor.java
│                               │   └── SyncProcessor.java
│                               ├── resolve/
│                               │   └── ExecutorSolver.java
│                               ├── retryer/
│                               │   ├── Retryer.java
│                               │   └── RetryerInfo.java
│                               ├── serializer/
│                               │   ├── ArgDeSerializerInfo.java
│                               │   ├── ArgSerializerInfo.java
│                               │   ├── EasyRetrySerializer.java
│                               │   ├── ResultPredicateSerializer.java
│                               │   └── RetryArgSerializer.java
│                               └── strategy/
│                                   ├── RetryStrategy.java
│                                   ├── StopStrategy.java
│                                   └── WaitStrategy.java
├── easy-retry-core/
│   ├── pom.xml
│   └── src/
│       ├── main/
│       │   └── java/
│       │       └── com/
│       │           └── alibaba/
│       │               └── easyretry/
│       │                   └── core/
│       │                       ├── DegradeAbleRetryExecutor.java
│       │                       ├── PersistenceRetryExecutor.java
│       │                       ├── PersistenceRetryer.java
│       │                       ├── PersistenceRetryerBuilder.java
│       │                       ├── RetryerBuilder.java
│       │                       ├── SyncRetryer.java
│       │                       ├── SyncRetryerBuilder.java
│       │                       ├── access/
│       │                       │   ├── DefaultRetrySerializerAccess.java
│       │                       │   └── MemoryRetryTaskAccess.java
│       │                       ├── container/
│       │                       │   └── SimpleRetryContainer.java
│       │                       ├── context/
│       │                       │   └── MaxAttemptsPersistenceRetryContext.java
│       │                       ├── degrade/
│       │                       │   └── EasyRetryDegradeHelper.java
│       │                       ├── event/
│       │                       │   └── SimpleRetryEventMulticaster.java
│       │                       ├── filter/
│       │                       │   ├── DefaultRetryFilterInvocationHandler.java
│       │                       │   ├── DefaultRetryFilterRegisterHandler.java
│       │                       │   ├── IdentifyRetryFilter.java
│       │                       │   ├── MethodExcuteRetryFilter.java
│       │                       │   ├── NOOPRetryFilter.java
│       │                       │   ├── SPIRetryFilterDiscover.java
│       │                       │   └── SimpleRetryFilterRegister.java
│       │                       ├── process/
│       │                       │   ├── async/
│       │                       │   │   ├── AbstractAsyncPersistenceProcessor.java
│       │                       │   │   ├── before/
│       │                       │   │   │   ├── AbstractAsyncPersistenceBeforeRetryProcessor.java
│       │                       │   │   │   ├── ExceptionPersistenceAsyncBeforeRetryProcessor.java
│       │                       │   │   │   └── ResultAsynPersistenceBeforeRetryProcessor.java
│       │                       │   │   └── on/
│       │                       │   │       ├── AbstractAsyncPersistenceOnRetryProcessor.java
│       │                       │   │       ├── ExceptionPersistenceAsynOnRetryProcessor.java
│       │                       │   │       └── ResultAsynPersistenceOnRetryProcessor.java
│       │                       │   └── package-info.java
│       │                       ├── serializer/
│       │                       │   ├── FastJsonRetryArgSerializer.java
│       │                       │   ├── HessianResultPredicateSerializer.java
│       │                       │   └── HessianRetryArgSerializer.java
│       │                       ├── strategy/
│       │                       │   └── DefaultRetryStrategy.java
│       │                       └── utils/
│       │                           ├── HessianSerializerUtils.java
│       │                           ├── LogUtils.java
│       │                           └── PrintUtils.java
│       └── test/
│           └── java/
│               └── com/
│                   └── alibaba/
│                       └── easyretry/
│                           └── core/
│                               └── utils/
│                                   └── TestClass.java
├── easy-retry-extensions/
│   ├── easy-retry-guava-extension/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── alibaba/
│   │                       └── easyretry/
│   │                           └── extension/
│   │                               └── guava/
│   │                                   ├── GuavaRetrySyncExecutor.java
│   │                                   └── package-info.java
│   ├── easy-retry-mybatis-extension/
│   │   ├── pom.xml
│   │   └── src/
│   │       ├── main/
│   │       │   ├── java/
│   │       │   │   └── com/
│   │       │   │       └── alibaba/
│   │       │   │           └── easyretry/
│   │       │   │               └── extension/
│   │       │   │                   └── mybatis/
│   │       │   │                       ├── access/
│   │       │   │                       │   └── MybatisRetryTaskAccess.java
│   │       │   │                       ├── common/
│   │       │   │                       │   └── utils/
│   │       │   │                       │       └── HostUtils.java
│   │       │   │                       ├── dao/
│   │       │   │                       │   ├── BaseDAOSupport.java
│   │       │   │                       │   ├── RetryTaskDAO.java
│   │       │   │                       │   └── RetryTaskDAOImpl.java
│   │       │   │                       ├── po/
│   │       │   │                       │   └── RetryTaskPO.java
│   │       │   │                       └── query/
│   │       │   │                           └── RetryTaskQuery.java
│   │       │   └── resources/
│   │       │       └── dal/
│   │       │           └── easyretry/
│   │       │               ├── easy-mybatis-config.xml
│   │       │               └── mapper/
│   │       │                   └── easy-retry-task-mapper.xml
│   │       └── test/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── alibaba/
│   │           │           └── easyretry/
│   │           │               └── extension/
│   │           │                   └── mybatis/
│   │           │                       ├── DbConfig.java
│   │           │                       ├── MyBatisConfig.java
│   │           │                       ├── access/
│   │           │                       │   └── MybatisRetryTaskAccessTest.java
│   │           │                       ├── common/
│   │           │                       │   └── utils/
│   │           │                       │       └── HostUtilsTest.java
│   │           │                       └── dao/
│   │           │                           └── RetryTaskDAOImplTest.java
│   │           └── resources/
│   │               ├── logback.xml
│   │               └── task.sql
│   ├── easy-retry-spring-extension/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── alibaba/
│   │                       └── easyretry/
│   │                           └── extension/
│   │                               └── spring/
│   │                                   ├── RetryListenerInitialize.java
│   │                                   ├── SPELParamPredicate.java
│   │                                   ├── SPELResultPredicate.java
│   │                                   ├── SpringEventApplicationListener.java
│   │                                   ├── SpringRetryFilterDiscover.java
│   │                                   └── aop/
│   │                                       ├── EasyRetryable.java
│   │                                       └── RetryInterceptor.java
│   └── pom.xml
├── easy-retry-starters/
│   ├── easy-retry-memory-starter/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── alibaba/
│   │           │           └── easyretry/
│   │           │               └── memory/
│   │           │                   ├── MemoryAutoConfiguration.java
│   │           │                   └── config/
│   │           │                       └── EasyRetryMemoryCompatibleProperties.java
│   │           └── resources/
│   │               └── META-INF/
│   │                   ├── additional-spring-configuration-metadata.json
│   │                   └── spring.factories
│   ├── easy-retry-mybatis-starter/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── alibaba/
│   │           │           └── easyretry/
│   │           │               └── mybatis/
│   │           │                   ├── MybatisAutoConfiguration.java
│   │           │                   └── conifg/
│   │           │                       └── EasyRetryMybatisProperties.java
│   │           └── resources/
│   │               └── META-INF/
│   │                   ├── additional-spring-configuration-metadata.json
│   │                   └── spring.factories
│   ├── easy-retry-starter-common/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── alibaba/
│   │                       └── easyretry/
│   │                           └── starter/
│   │                               └── common/
│   │                                   └── CommonAutoConfiguration.java
│   └── pom.xml
└── pom.xml

================================================
FILE CONTENTS
================================================

================================================
FILE: .editorconfig
================================================
root = true

[*]
charset = utf-8

[*.java]
indent_style = tab
indent_size = 4
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true

[*.{json, yml, xml}]
indent_style = tab
indent_size = 4

[*.md]
insert_final_newline = false
trim_trailing_whitespace = false

[*.properties]
ij_properties_align_group_field_declarations = false
ij_properties_keep_blank_lines = false
ij_properties_key_value_delimiter = equals
ij_properties_spaces_around_key_value_delimiter = false

================================================
FILE: .github/workflows/maven.yml
================================================
# This workflow will build a Java project with Maven
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven

name: Java CI with Maven

on:
    push:
        branches: [ main ]
    pull_request:
        branches: [ main ]


jobs:
    build:
        runs-on: ubuntu-latest
        steps:
            -   uses: actions/checkout@v2
            -   name: Set up JDK 1.8
                uses: actions/setup-java@v1
                with:
                    java-version: 1.8
            -   name: Build with Maven
                run: mvn -B package --file pom.xml


================================================
FILE: .gitignore
================================================
# Compiled class file
*.class
*.classpath
*.factorypath

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

# IDE Files #
*.iml
.idea
.idea/
.project
.settings
target
.DS_Store

# temp ignore
*.cache
*.diff
*.patch
*.tmp

# Maven ignore
.flattened-pom.xml


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2021 Alibaba

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# Easy-Retry

一种存储介质可扩展的持久化重试方案
![img](img/readme/arch.jpg)

### Getting started

#### Memory Retry

1. 增加pom依赖

```xml
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easy-retry-memory-starter</artifactId>
    <version>${last-version}</version>
</dependency>
```

2. 在application.properties增加配置

`spring.easyretry.memory.enabled = true`

3. 在需要重试的方法上增加`@EasyRetryable`注解

```java
public class MemoryUserService {
    @EasyRetryable
    public User getUserById(Long userId){
        return new User();
    }
}
```

#### Mybatis Retry

1. 增加pom依赖
```xml
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easy-retry-mybatis-starter</artifactId>
    <version>${last-version}</version>
</dependency>
```

2. 在application.properties增加配置

`spring.easyretry.mybatis.enabled = true`

3. 声明`javax.sql.DataSource`的`Bean`实例,参考下面例子(以`druid`连接池为例)
```
@Bean(name = "easyRetryMybatisDataSource", initMethod = "init", destroyMethod = "close")
public DataSource easyRetryMybatisDataSource() {
    DruidDataSource tds = new DruidDataSource();
    tds.setUrl("");
    tds.setUsername("");
    tds.setPassword("");
    ...
    return tds;
}
```

4. 新增持久化表

```
CREATE TABLE `easy_retry_task` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `gmt_create` datetime NOT NULL COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL COMMENT '修改时间',
  `sharding` varchar(64) DEFAULT NULL COMMENT '数据库分片字段',
  `biz_id` varchar(64) DEFAULT NULL COMMENT '业务id',
  `executor_name` varchar(512) NOT NULL COMMENT '执行名称',
  `executor_method_name` varchar(512) NOT NULL COMMENT '执行方法名称',
  `retry_status` tinyint(4) NOT NULL COMMENT '重试状态',
  `args_str` varchar(7168) DEFAULT NULL COMMENT '执行方法参数',
  `ext_attrs` varchar(3000) DEFAULT NULL COMMENT '扩展字段',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COMMENT='easy_retry_task'
;
```

5. 在需要重试的方法上增加@EasyRetryable注解

```java
public class MybatisUserService {
    @EasyRetryable
    public User getUserById(Long userId){
        return new User();
    }
}
```

### Built With

• JDK1.8

• Spring Framework5+

• Spring Boot2.4+

• Maven3.0


================================================
FILE: config/intellij-java-google-style.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<code_scheme name="GoogleStyle">
	<option name="OTHER_INDENT_OPTIONS">
		<value>
			<option name="INDENT_SIZE" value="2"/>
			<option name="CONTINUATION_INDENT_SIZE" value="4"/>
			<option name="TAB_SIZE" value="2"/>
			<option name="USE_TAB_CHARACTER" value="false"/>
			<option name="SMART_TABS" value="false"/>
			<option name="LABEL_INDENT_SIZE" value="0"/>
			<option name="LABEL_INDENT_ABSOLUTE" value="false"/>
			<option name="USE_RELATIVE_INDENTS" value="false"/>
		</value>
	</option>
	<option name="INSERT_INNER_CLASS_IMPORTS" value="true"/>
	<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999"/>
	<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999"/>
	<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
		<value/>
	</option>
	<option name="IMPORT_LAYOUT_TABLE">
		<value>
			<package name="" static="true" withSubpackages="true"/>
			<emptyLine/>
			<package name="" static="false" withSubpackages="true"/>
		</value>
	</option>
	<option name="RIGHT_MARGIN" value="100"/>
	<option name="JD_ALIGN_PARAM_COMMENTS" value="false"/>
	<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false"/>
	<option name="JD_P_AT_EMPTY_LINES" value="false"/>
	<option name="JD_KEEP_EMPTY_PARAMETER" value="false"/>
	<option name="JD_KEEP_EMPTY_EXCEPTION" value="false"/>
	<option name="JD_KEEP_EMPTY_RETURN" value="false"/>
	<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
	<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0"/>
	<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
	<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="0"/>
	<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
	<option name="ALIGN_MULTILINE_FOR" value="false"/>
	<option name="CALL_PARAMETERS_WRAP" value="1"/>
	<option name="METHOD_PARAMETERS_WRAP" value="1"/>
	<option name="EXTENDS_LIST_WRAP" value="1"/>
	<option name="THROWS_KEYWORD_WRAP" value="1"/>
	<option name="METHOD_CALL_CHAIN_WRAP" value="1"/>
	<option name="BINARY_OPERATION_WRAP" value="1"/>
	<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true"/>
	<option name="TERNARY_OPERATION_WRAP" value="1"/>
	<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true"/>
	<option name="FOR_STATEMENT_WRAP" value="1"/>
	<option name="ARRAY_INITIALIZER_WRAP" value="1"/>
	<option name="WRAP_COMMENTS" value="true"/>
	<option name="IF_BRACE_FORCE" value="3"/>
	<option name="DOWHILE_BRACE_FORCE" value="3"/>
	<option name="WHILE_BRACE_FORCE" value="3"/>
	<option name="FOR_BRACE_FORCE" value="3"/>
	<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true"/>
	<AndroidXmlCodeStyleSettings>
		<option name="USE_CUSTOM_SETTINGS" value="true"/>
		<option name="LAYOUT_SETTINGS">
			<value>
				<option name="INSERT_BLANK_LINE_BEFORE_TAG" value="false"/>
			</value>
		</option>
	</AndroidXmlCodeStyleSettings>
	<JSCodeStyleSettings>
		<option name="INDENT_CHAINED_CALLS" value="false"/>
	</JSCodeStyleSettings>
	<Python>
		<option name="USE_CONTINUATION_INDENT_FOR_ARGUMENTS" value="true"/>
	</Python>
	<TypeScriptCodeStyleSettings>
		<option name="INDENT_CHAINED_CALLS" value="false"/>
	</TypeScriptCodeStyleSettings>
	<XML>
		<option name="XML_ALIGN_ATTRIBUTES" value="false"/>
		<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true"/>
	</XML>
	<codeStyleSettings language="CSS">
		<indentOptions>
			<option name="INDENT_SIZE" value="2"/>
			<option name="CONTINUATION_INDENT_SIZE" value="4"/>
			<option name="TAB_SIZE" value="2"/>
		</indentOptions>
	</codeStyleSettings>
	<codeStyleSettings language="ECMA Script Level 4">
		<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
		<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
		<option name="ALIGN_MULTILINE_FOR" value="false"/>
		<option name="CALL_PARAMETERS_WRAP" value="1"/>
		<option name="METHOD_PARAMETERS_WRAP" value="1"/>
		<option name="EXTENDS_LIST_WRAP" value="1"/>
		<option name="BINARY_OPERATION_WRAP" value="1"/>
		<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true"/>
		<option name="TERNARY_OPERATION_WRAP" value="1"/>
		<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true"/>
		<option name="FOR_STATEMENT_WRAP" value="1"/>
		<option name="ARRAY_INITIALIZER_WRAP" value="1"/>
		<option name="IF_BRACE_FORCE" value="3"/>
		<option name="DOWHILE_BRACE_FORCE" value="3"/>
		<option name="WHILE_BRACE_FORCE" value="3"/>
		<option name="FOR_BRACE_FORCE" value="3"/>
		<option name="PARENT_SETTINGS_INSTALLED" value="true"/>
	</codeStyleSettings>
	<codeStyleSettings language="HTML">
		<indentOptions>
			<option name="INDENT_SIZE" value="2"/>
			<option name="CONTINUATION_INDENT_SIZE" value="4"/>
			<option name="TAB_SIZE" value="2"/>
		</indentOptions>
	</codeStyleSettings>
	<codeStyleSettings language="JAVA">
		<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
		<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
		<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1"/>
		<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
		<option name="ALIGN_MULTILINE_RESOURCES" value="false"/>
		<option name="ALIGN_MULTILINE_FOR" value="false"/>
		<option name="CALL_PARAMETERS_WRAP" value="1"/>
		<option name="METHOD_PARAMETERS_WRAP" value="1"/>
		<option name="EXTENDS_LIST_WRAP" value="1"/>
		<option name="THROWS_KEYWORD_WRAP" value="1"/>
		<option name="METHOD_CALL_CHAIN_WRAP" value="1"/>
		<option name="BINARY_OPERATION_WRAP" value="1"/>
		<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true"/>
		<option name="TERNARY_OPERATION_WRAP" value="1"/>
		<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true"/>
		<option name="FOR_STATEMENT_WRAP" value="1"/>
		<option name="ARRAY_INITIALIZER_WRAP" value="1"/>
		<option name="WRAP_COMMENTS" value="true"/>
		<option name="IF_BRACE_FORCE" value="3"/>
		<option name="DOWHILE_BRACE_FORCE" value="3"/>
		<option name="WHILE_BRACE_FORCE" value="3"/>
		<option name="FOR_BRACE_FORCE" value="3"/>
		<option name="PARENT_SETTINGS_INSTALLED" value="true"/>
		<indentOptions>
			<option name="INDENT_SIZE" value="2"/>
			<option name="CONTINUATION_INDENT_SIZE" value="4"/>
			<option name="TAB_SIZE" value="2"/>
		</indentOptions>
	</codeStyleSettings>
	<codeStyleSettings language="JSON">
		<indentOptions>
			<option name="CONTINUATION_INDENT_SIZE" value="4"/>
			<option name="TAB_SIZE" value="2"/>
		</indentOptions>
	</codeStyleSettings>
	<codeStyleSettings language="JavaScript">
		<option name="RIGHT_MARGIN" value="80"/>
		<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
		<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
		<option name="ALIGN_MULTILINE_FOR" value="false"/>
		<option name="CALL_PARAMETERS_WRAP" value="1"/>
		<option name="METHOD_PARAMETERS_WRAP" value="1"/>
		<option name="BINARY_OPERATION_WRAP" value="1"/>
		<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true"/>
		<option name="TERNARY_OPERATION_WRAP" value="1"/>
		<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true"/>
		<option name="FOR_STATEMENT_WRAP" value="1"/>
		<option name="ARRAY_INITIALIZER_WRAP" value="1"/>
		<option name="IF_BRACE_FORCE" value="3"/>
		<option name="DOWHILE_BRACE_FORCE" value="3"/>
		<option name="WHILE_BRACE_FORCE" value="3"/>
		<option name="FOR_BRACE_FORCE" value="3"/>
		<option name="PARENT_SETTINGS_INSTALLED" value="true"/>
		<indentOptions>
			<option name="INDENT_SIZE" value="2"/>
			<option name="TAB_SIZE" value="2"/>
		</indentOptions>
	</codeStyleSettings>
	<codeStyleSettings language="PROTO">
		<option name="RIGHT_MARGIN" value="80"/>
		<indentOptions>
			<option name="INDENT_SIZE" value="2"/>
			<option name="CONTINUATION_INDENT_SIZE" value="2"/>
			<option name="TAB_SIZE" value="2"/>
		</indentOptions>
	</codeStyleSettings>
	<codeStyleSettings language="protobuf">
		<option name="RIGHT_MARGIN" value="80"/>
		<indentOptions>
			<option name="INDENT_SIZE" value="2"/>
			<option name="CONTINUATION_INDENT_SIZE" value="2"/>
			<option name="TAB_SIZE" value="2"/>
		</indentOptions>
	</codeStyleSettings>
	<codeStyleSettings language="Python">
		<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
		<option name="RIGHT_MARGIN" value="80"/>
		<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
		<option name="PARENT_SETTINGS_INSTALLED" value="true"/>
		<indentOptions>
			<option name="INDENT_SIZE" value="2"/>
			<option name="CONTINUATION_INDENT_SIZE" value="4"/>
			<option name="TAB_SIZE" value="2"/>
		</indentOptions>
	</codeStyleSettings>
	<codeStyleSettings language="SASS">
		<indentOptions>
			<option name="CONTINUATION_INDENT_SIZE" value="4"/>
			<option name="TAB_SIZE" value="2"/>
		</indentOptions>
	</codeStyleSettings>
	<codeStyleSettings language="SCSS">
		<indentOptions>
			<option name="CONTINUATION_INDENT_SIZE" value="4"/>
			<option name="TAB_SIZE" value="2"/>
		</indentOptions>
	</codeStyleSettings>
	<codeStyleSettings language="TypeScript">
		<indentOptions>
			<option name="INDENT_SIZE" value="2"/>
			<option name="TAB_SIZE" value="2"/>
		</indentOptions>
	</codeStyleSettings>
	<codeStyleSettings language="XML">
		<indentOptions>
			<option name="INDENT_SIZE" value="2"/>
			<option name="CONTINUATION_INDENT_SIZE" value="2"/>
			<option name="TAB_SIZE" value="2"/>
		</indentOptions>
		<arrangement>
			<rules>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>xmlns:android</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>^$</XML_NAMESPACE>
							</AND>
						</match>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>xmlns:.*</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>^$</XML_NAMESPACE>
							</AND>
						</match>
						<order>BY_NAME</order>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*:id</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>style</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>^$</XML_NAMESPACE>
							</AND>
						</match>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>^$</XML_NAMESPACE>
							</AND>
						</match>
						<order>BY_NAME</order>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*:.*Style</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
						<order>BY_NAME</order>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*:layout_width</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*:layout_height</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*:layout_weight</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*:layout_margin</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*:layout_marginTop</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*:layout_marginBottom</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*:layout_marginStart</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*:layout_marginEnd</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*:layout_marginLeft</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*:layout_marginRight</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*:layout_.*</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
						<order>BY_NAME</order>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*:padding</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*:paddingTop</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*:paddingBottom</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*:paddingStart</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*:paddingEnd</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*:paddingLeft</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*:paddingRight</NAME>
								<XML_ATTRIBUTE/>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*</NAME>
								<XML_NAMESPACE>http://schemas.android.com/apk/res/android
								</XML_NAMESPACE>
							</AND>
						</match>
						<order>BY_NAME</order>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*</NAME>
								<XML_NAMESPACE>http://schemas.android.com/apk/res-auto
								</XML_NAMESPACE>
							</AND>
						</match>
						<order>BY_NAME</order>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*</NAME>
								<XML_NAMESPACE>http://schemas.android.com/tools</XML_NAMESPACE>
							</AND>
						</match>
						<order>BY_NAME</order>
					</rule>
				</section>
				<section>
					<rule>
						<match>
							<AND>
								<NAME>.*</NAME>
								<XML_NAMESPACE>.*</XML_NAMESPACE>
							</AND>
						</match>
						<order>BY_NAME</order>
					</rule>
				</section>
			</rules>
		</arrangement>
	</codeStyleSettings>
	<Objective-C>
		<option name="INDENT_NAMESPACE_MEMBERS" value="0"/>
		<option name="INDENT_C_STRUCT_MEMBERS" value="2"/>
		<option name="INDENT_CLASS_MEMBERS" value="2"/>
		<option name="INDENT_VISIBILITY_KEYWORDS" value="1"/>
		<option name="INDENT_INSIDE_CODE_BLOCK" value="2"/>
		<option name="KEEP_STRUCTURES_IN_ONE_LINE" value="true"/>
		<option name="FUNCTION_PARAMETERS_WRAP" value="5"/>
		<option name="FUNCTION_CALL_ARGUMENTS_WRAP" value="5"/>
		<option name="TEMPLATE_CALL_ARGUMENTS_WRAP" value="5"/>
		<option name="TEMPLATE_CALL_ARGUMENTS_ALIGN_MULTILINE" value="true"/>
		<option name="ALIGN_INIT_LIST_IN_COLUMNS" value="false"/>
		<option name="SPACE_BEFORE_SUPERCLASS_COLON" value="false"/>
	</Objective-C>
	<Objective-C-extensions>
		<option name="GENERATE_INSTANCE_VARIABLES_FOR_PROPERTIES" value="ASK"/>
		<option name="RELEASE_STYLE" value="IVAR"/>
		<option name="TYPE_QUALIFIERS_PLACEMENT" value="BEFORE"/>
		<file>
			<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import"/>
			<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro"/>
			<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef"/>
			<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum"/>
			<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant"/>
			<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global"/>
			<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct"/>
			<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl"/>
			<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function"/>
		</file>
		<class>
			<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property"/>
			<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize"/>
			<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod"/>
			<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod"/>
			<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod"/>
			<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod"/>
		</class>
		<extensions>
			<pair header="h" source="cc"/>
			<pair header="h" source="c"/>
		</extensions>
	</Objective-C-extensions>
	<codeStyleSettings language="ObjectiveC">
		<option name="RIGHT_MARGIN" value="80"/>
		<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
		<option name="BLANK_LINES_BEFORE_IMPORTS" value="0"/>
		<option name="BLANK_LINES_AFTER_IMPORTS" value="0"/>
		<option name="BLANK_LINES_AROUND_CLASS" value="0"/>
		<option name="BLANK_LINES_AROUND_METHOD" value="0"/>
		<option name="BLANK_LINES_AROUND_METHOD_IN_INTERFACE" value="0"/>
		<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="false"/>
		<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true"/>
		<option name="FOR_STATEMENT_WRAP" value="1"/>
		<option name="ASSIGNMENT_WRAP" value="1"/>
		<indentOptions>
			<option name="INDENT_SIZE" value="2"/>
			<option name="CONTINUATION_INDENT_SIZE" value="4"/>
		</indentOptions>
	</codeStyleSettings>
</code_scheme>

================================================
FILE: easy-retry-common/pom.xml
================================================
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xmlns="http://maven.apache.org/POM/4.0.0"
		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.alibaba</groupId>
		<artifactId>easy-retry</artifactId>
		<version>${revision}</version>
		<relativePath>../pom.xml</relativePath>
	</parent>
	<artifactId>easy-retry-common</artifactId>
	<name>easy-retry-common</name>
	<description>easy-retry-common</description>

	<dependencies>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
		</dependency>
		<dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
		</dependency>
	</dependencies>

</project>

================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/AbstractResultPredicate.java
================================================
package com.alibaba.easyretry.common;

/**
 * @author Created by wuhao on 2021/3/26.
 */
public abstract class AbstractResultPredicate<T> implements EasyRetryPredicate<T, Boolean> {

	@Override
	public abstract Boolean apply(T result);

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/AbstractRetrySyncExecutor.java
================================================
package com.alibaba.easyretry.common;

import com.alibaba.easyretry.common.retryer.RetryerInfo;

/**
 * @author zhangchi20
 * Created on 2023-07-17
 */
public abstract class AbstractRetrySyncExecutor<V> implements RetrySyncExecutor<V> {

	private RetryerInfo<V> retryerInfo;

	@Override
	public void setRetryerInfo(RetryerInfo<V> retryerInfo) {
		this.retryerInfo = retryerInfo;
	}

	public RetryerInfo<V> getRetryerInfo() {
		return retryerInfo;
	}


	@Override
	public abstract V call(SCallable<V> callable) throws Throwable;

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/EasyRetryPredicate.java
================================================
package com.alibaba.easyretry.common;

import java.io.Serializable;

/**
 * @author Created by wuhao on 2021/3/18.
 */
public interface EasyRetryPredicate<T, R> extends Serializable {

	R apply(T result);

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/Invocation.java
================================================
package com.alibaba.easyretry.common;

/**
 * @author Created by wuhao on 2021/3/29.
 */
public interface Invocation {

	Object invoke() throws Throwable;

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryConfiguration.java
================================================
package com.alibaba.easyretry.common;

import com.alibaba.easyretry.common.access.RetrySerializerAccess;
import com.alibaba.easyretry.common.access.RetryStrategyAccess;
import com.alibaba.easyretry.common.access.RetryTaskAccess;
import com.alibaba.easyretry.common.event.RetryEventMulticaster;
import com.alibaba.easyretry.common.resolve.ExecutorSolver;
import com.alibaba.easyretry.common.serializer.ResultPredicateSerializer;

/**
 * @author Created by wuhao on 2020/11/5.
 */
public interface RetryConfiguration {

	RetryTaskAccess getRetryTaskAccess();

	RetrySerializerAccess getRetrySerializerAccess();

	RetryStrategyAccess getRetryStrategyAccess();

	ExecutorSolver getExecutorSolver();

	ResultPredicateSerializer getResultPredicateSerializer();

	Integer getMaxRetryTimes();

	RetryEventMulticaster getRetryEventMulticaster();

	default AbstractRetrySyncExecutor getRetrySyncExecutor() {
		return null;
	}

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryContainer.java
================================================
package com.alibaba.easyretry.common;

/**
 * @author Created by wuhao on 2020/11/5.
 */
public interface RetryContainer extends RetryLifecycle {

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryContext.java
================================================
package com.alibaba.easyretry.common;

public interface RetryContext extends RetryLifecycle {

	void setAttribute(String key, String value);

	String getAttribute(String key);

	/**
	 * 获取唯一标识
	 */
	String getId();

	Invocation getInvocation();

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryExecutor.java
================================================
package com.alibaba.easyretry.common;

import com.alibaba.easyretry.common.constant.enums.HandleResultEnum;

/**
 * @author Created by wuhao on 2021/3/2.
 */
public interface RetryExecutor {

	HandleResultEnum doExecute(RetryContext context);
}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryIdentify.java
================================================
package com.alibaba.easyretry.common;

import java.util.Objects;

/**
 * @author Created by wuhao on 2021/2/20.
 */
public class RetryIdentify {

	private static final ThreadLocal<String> RETRY_CONTEXT_THREAD_LOCAL = new ThreadLocal<>();

	private static final String RETRY_FLAG = "RETRY_FLAG";

	public static void start() {
		RETRY_CONTEXT_THREAD_LOCAL.set(RETRY_FLAG);
	}

	public static void stop() {
		RETRY_CONTEXT_THREAD_LOCAL.set(null);
	}

	public static boolean isOnRetry() {
		return Objects.nonNull(RETRY_CONTEXT_THREAD_LOCAL.get());
	}
}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryLifecycle.java
================================================
package com.alibaba.easyretry.common;

/**
 * @author Created by wuhao on 2020/11/2.
 */
public interface RetryLifecycle {

	void start();

	void stop();
}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetrySyncExecutor.java
================================================
package com.alibaba.easyretry.common;

import com.alibaba.easyretry.common.retryer.RetryerInfo;

/**
 * @author zhangchi20
 * Created on 2023-07-17
 */
public interface RetrySyncExecutor<V> {

	V call(SCallable<V> callable) throws Throwable;

	void setRetryerInfo(RetryerInfo<V> retryerInfo);

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/SCallable.java
================================================
package com.alibaba.easyretry.common;

import java.io.Serializable;

/**
 * @author Created by wuhao on 2020/11/5.
 */
@FunctionalInterface
public interface SCallable<V> extends Serializable {

	V call() throws Throwable;
}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/SimpleMethodInvocation.java
================================================
package com.alibaba.easyretry.common;

import java.lang.reflect.Method;
import java.util.Arrays;

import lombok.AllArgsConstructor;
import lombok.Setter;

/**
 * @author Created by wuhao on 2021/3/29.
 */
@AllArgsConstructor
public class SimpleMethodInvocation implements Invocation {

	@Setter
	private Object executor;

	@Setter
	private Method method;

	@Setter
	private Object[] args;

	@Override
	public Object invoke() throws Throwable {
		return method.invoke(executor, args);
	}

	@Override
	public String toString() {
		return "[Invocation] executor is " + executor.getClass().getName() + " method is " + method
			.getName() + " args is " + Arrays.toString(args);

	}
}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/access/RetrySerializerAccess.java
================================================
package com.alibaba.easyretry.common.access;

import com.alibaba.easyretry.common.serializer.RetryArgSerializer;

/**
 * 重试信息序列化器获取 如果方法上有指定序列化器,则使用getRetrySerializer 否则使用全局序列化器getCurrentGlobalRetrySerializer
 *
 * @author Created by wuhao on 2020/11/6.
 */
public interface RetrySerializerAccess {

	/**
	 * 获取全局序列化器
	 */
	RetryArgSerializer getCurrentGlobalRetrySerializer();

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/access/RetryStrategyAccess.java
================================================
package com.alibaba.easyretry.common.access;

import com.alibaba.easyretry.common.strategy.StopStrategy;
import com.alibaba.easyretry.common.strategy.WaitStrategy;

/**
 * 重试策略获取 如果方法上有指定则用指定Strategy 否则使用Global
 *
 * @author Created by wuhao on 2020/11/6.
 */
public interface RetryStrategyAccess {

	/**
	 * 获取全局重试任务停止策略
	 */
	StopStrategy getCurrentGlobalStopStrategy();

	/**
	 * 获取全局等待策略
	 */
	WaitStrategy getCurrentGlobalWaitStrategy();

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/access/RetryTaskAccess.java
================================================
package com.alibaba.easyretry.common.access;

import java.util.List;

import com.alibaba.easyretry.common.entity.RetryTask;

/**
 * 重试任务获取器
 */
public interface RetryTaskAccess {

	/**
	 * 保存重试任务
	 */
	boolean saveRetryTask(RetryTask retryTask);

	/**
	 * 更改重试任务为处理中
	 */
	boolean handlingRetryTask(RetryTask retryTask);

	/**
	 * 完结重试任务
	 */
	boolean finishRetryTask(RetryTask retryTask);

	/**
	 * 停止重试任务
	 */
	boolean stopRetryTask(RetryTask retryTask);

	/**
	 * 批量查询重试任务
	 */
	List<RetryTask> listAvailableTasks(Long lastId);
}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/constant/enums/HandleResultEnum.java
================================================
package com.alibaba.easyretry.common.constant.enums;

/**
 * 重试任务重试结果
 *
 * @author Created by wuhao on 2020/11/1.
 */
public enum HandleResultEnum {

	/**
	 * 处理成功
	 */
	SUCCESS,

	/**
	 * 处理失败
	 */
	FAILURE,

	/**
	 * 等待策略返回该case还在等待队列中
	 */
	WAITING,

	/**
	 * 根据停止策略该笔case停止重试
	 */
	STOP,

	ERROR;
}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/constant/enums/RetryTaskStatusEnum.java
================================================
package com.alibaba.easyretry.common.constant.enums;

import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import lombok.Getter;

/**
 * 重试任务状态
 *
 * @author Created by wuhao on 2020/10/31.
 */
public enum RetryTaskStatusEnum {

	/**
	 * 初始化状态
	 */
	INIT(0, "初始化"),

	/**
	 * 任务处理中
	 */
	HANDLING(1, "处理中"),

	/**
	 * 任务处理异常
	 */
	ERROR(2, "异常"),

	/**
	 * 任务完结
	 */
	FINISH(3, "完结");

	private static final Map<Integer, RetryTaskStatusEnum> MAP =
		Stream.of(values())
			.collect(Collectors.toMap(RetryTaskStatusEnum::getCode, (value) -> value));
	@Getter
	private int code;
	@Getter
	private String desc;

	RetryTaskStatusEnum(int code, String desc) {
		this.code = code;
		this.desc = desc;
	}

	public static RetryTaskStatusEnum fromCode(int code) {
		return MAP.get(code);
	}
}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/constant/enums/RetryTypeEnum.java
================================================
package com.alibaba.easyretry.common.constant.enums;

/**
 * 重试种类
 *
 * @author Created by zhangchi on 2023-07-12
 */
public enum RetryTypeEnum {

	/**
	 * 同步
	 */
	SYNC,

	/**
	 * 异步
	 */
	ASYNC,
	;

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/constant/package-info.java
================================================
/**
 * @author Created by wuhao on 2020/11/6.
 */
package com.alibaba.easyretry.common.constant;


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/entity/RetryTask.java
================================================
package com.alibaba.easyretry.common.entity;

import java.util.Date;
import java.util.Map;

import com.alibaba.easyretry.common.constant.enums.RetryTaskStatusEnum;

import lombok.Data;

/**
 * 重试任务实体
 *
 * @author wuhao
 */
@Data
public class RetryTask {

	/**
	 * 主键id
	 */
	private Long id;

	/**
	 * 业务信息
	 */
	private String bizId;

	/**
	 * 执行者名称
	 */
	private String executorName;

	/**
	 * 执行者方法
	 */
	private String executorMethodName;

	/**
	 * 当重试失败时候执行的方法
	 */
	private String onFailureMethod;

	/**
	 * 重试任务状态
	 */
	private RetryTaskStatusEnum status;

	/**
	 * 任务上的扩展字段
	 */
	private Map<String, String> extAttrs;

	/**
	 * 重试执行者方法参数
	 */
	private String argsStr;

	private Date gmtCreate;

	private Date gmtModified;
}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/RetryEvent.java
================================================
package com.alibaba.easyretry.common.event;

/**
 * @author Created by wuhao on 2021/3/25.
 */
public interface RetryEvent {

	String getName();

	boolean isOnRetry();

	void setAttribute(String key, String vule);
}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/RetryEventMulticaster.java
================================================
package com.alibaba.easyretry.common.event;

/**
 * @author Created by wuhao on 2021/3/26.
 */
public interface RetryEventMulticaster {

	void register(RetryListener listener);

	void multicast(RetryEvent retryEvent);

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/RetryListener.java
================================================
package com.alibaba.easyretry.common.event;

/**
 * @author Created by wuhao on 2021/3/25.
 */
public interface RetryListener<T extends RetryEvent> {

	void onRetryEvent(T event);

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/before/AfterSaveBeforeRetryEvent.java
================================================
package com.alibaba.easyretry.common.event.before;

import com.alibaba.easyretry.common.entity.RetryTask;

/**
 * @author Created by wuhao on 2021/3/25.
 */
public class AfterSaveBeforeRetryEvent extends BeforeRetryEvent {

	public AfterSaveBeforeRetryEvent(RetryTask retryTask) {
		super(retryTask);
	}
}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/before/BeforeRetryEvent.java
================================================
package com.alibaba.easyretry.common.event.before;

import java.util.Map;
import java.util.Objects;

import com.alibaba.easyretry.common.entity.RetryTask;
import com.alibaba.easyretry.common.event.RetryEvent;

import com.google.common.collect.Maps;

/**
 * @author Created by wuhao on 2021/3/25.
 */
public abstract class BeforeRetryEvent implements RetryEvent {

	private RetryTask retryTask;

	public BeforeRetryEvent(RetryTask retryTask) {
		this.retryTask = retryTask;
	}

	@Override
	public boolean isOnRetry() {
		return false;
	}

	@Override
	public void setAttribute(String key, String value) {
		Map<String, String> extAttrs = retryTask.getExtAttrs();
		if (Objects.isNull(extAttrs)) {
			extAttrs = Maps.newHashMap();
		}
		extAttrs.put(key, value);
	}

	@Override
	public String getName() {
		return this.getClass().getSimpleName();
	}

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/before/PrepSaveBeforeRetryEvent.java
================================================
package com.alibaba.easyretry.common.event.before;

import com.alibaba.easyretry.common.entity.RetryTask;

/**
 * @author Created by wuhao on 2021/3/25.
 */
public class PrepSaveBeforeRetryEvent extends BeforeRetryEvent {

	public PrepSaveBeforeRetryEvent(RetryTask retryTask) {
		super(retryTask);
	}
}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/on/FailureOnRetryEvent.java
================================================
package com.alibaba.easyretry.common.event.on;

import com.alibaba.easyretry.common.RetryContext;

/**
 * @author Created by wuhao on 2021/3/25.
 */
public class FailureOnRetryEvent extends OnRetryEvent {

	public FailureOnRetryEvent(RetryContext retryContext) {
		super(retryContext);
	}

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/on/OnRetryEvent.java
================================================
package com.alibaba.easyretry.common.event.on;

import com.alibaba.easyretry.common.RetryContext;
import com.alibaba.easyretry.common.event.RetryEvent;

/**
 * @author Created by wuhao on 2021/3/25.
 */
public abstract class OnRetryEvent implements RetryEvent {

	final private RetryContext retryContext;

	public OnRetryEvent(RetryContext retryContext) {
		this.retryContext = retryContext;
	}

	@Override
	public void setAttribute(String key, String value) {
		retryContext.setAttribute(key, value);
	}

	public String getAttribute(String key) {
		return retryContext.getAttribute(key);
	}

	@Override
	public boolean isOnRetry() {
		return true;
	}

	@Override
	public String getName() {
		return this.getClass().getSimpleName();
	}

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/on/StopOnRetryEvent.java
================================================
package com.alibaba.easyretry.common.event.on;

import com.alibaba.easyretry.common.RetryContext;

/**
 * @author Created by wuhao on 2021/3/25.
 */
public class StopOnRetryEvent extends OnRetryEvent {

	public StopOnRetryEvent(RetryContext retryContext) {
		super(retryContext);
	}

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/on/SuccessOnRetryEvent.java
================================================
package com.alibaba.easyretry.common.event.on;

import com.alibaba.easyretry.common.RetryContext;

/**
 * @author Created by wuhao on 2021/3/25.
 */
public class SuccessOnRetryEvent extends OnRetryEvent {

	public SuccessOnRetryEvent(RetryContext retryContext) {
		super(retryContext);
	}

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/AbstractRetryFilter.java
================================================
package com.alibaba.easyretry.common.filter;

/**
 * @author Created by wuhao on 2021/3/22.
 */
public abstract class AbstractRetryFilter implements RetryFilter {

	protected RetryFilter next;

	@Override
	public void setNext(RetryFilter next) {
		this.next = next;
	}
}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilter.java
================================================
package com.alibaba.easyretry.common.filter;

import com.alibaba.easyretry.common.RetryContext;

/**
 * @author Created by wuhao on 2021/3/22.
 */
public interface RetryFilter {

	RetryFilterResponse doFilter(RetryContext retryContext) throws Throwable;

	void setNext(RetryFilter next);

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterDiscover.java
================================================
package com.alibaba.easyretry.common.filter;

import java.util.List;

/**
 * @author Created by wuhao on 2021/4/9.
 */
public interface RetryFilterDiscover {

	List<RetryFilter> discoverAll();
}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterInvocation.java
================================================
package com.alibaba.easyretry.common.filter;

import com.alibaba.easyretry.common.RetryContext;

/**
 * @author Created by wuhao on 2021/4/10.
 */
public interface RetryFilterInvocation {

	RetryFilterResponse invoke(RetryContext retryContext) throws Throwable;

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterInvocationHandler.java
================================================
package com.alibaba.easyretry.common.filter;

/**
 * @author Created by wuhao on 2021/3/19.
 */
public interface RetryFilterInvocationHandler {
	void handle();

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterRegister.java
================================================
package com.alibaba.easyretry.common.filter;

import java.util.List;

/**
 * @author Created by wuhao on 2021/3/22.
 */
public interface RetryFilterRegister {

	void register(RetryFilter retryFilter);

	List<RetryFilter> export();

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterRegisterHandler.java
================================================
package com.alibaba.easyretry.common.filter;

/**
 * @author Created by wuhao on 2021/4/9.
 */
public interface RetryFilterRegisterHandler {

	void handle();

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterResponse.java
================================================
package com.alibaba.easyretry.common.filter;

import lombok.Data;

/**
 * @author Created by wuhao on 2021/3/22.
 */
@Data
public class RetryFilterResponse {

	private Object response;

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/processor/AsyncPersistenceProcessor.java
================================================
package com.alibaba.easyretry.common.processor;

/**
 * @author Created by wuhao on 2021/3/19.
 */
public interface AsyncPersistenceProcessor<R> extends RetryProcessor {

	@Override
	void process();

	boolean needRetry();

	R getResult() throws Throwable;

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/processor/RetryProcessor.java
================================================
package com.alibaba.easyretry.common.processor;

/**
 * @author Created by wuhao on 2021/3/19.
 */
public interface RetryProcessor {

	void process();

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/processor/SyncProcessor.java
================================================
package com.alibaba.easyretry.common.processor;

/**
 * @author Created by zhangchi on 2023-07-12
 */
public interface SyncProcessor<R> extends RetryProcessor {

	R getResult() throws Throwable;

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/resolve/ExecutorSolver.java
================================================
package com.alibaba.easyretry.common.resolve;

/**
 * @author Created by wuhao on 2020/11/8.
 */
public interface ExecutorSolver {

	Object resolver(String executorName);
}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/retryer/Retryer.java
================================================
package com.alibaba.easyretry.common.retryer;

import com.alibaba.easyretry.common.SCallable;

/**
 * @author Created by wuhao on 2020/11/5.
 */
public interface Retryer<V> {

	V call(SCallable<V> callable) throws Throwable;

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/retryer/RetryerInfo.java
================================================
package com.alibaba.easyretry.common.retryer;

import com.alibaba.easyretry.common.AbstractResultPredicate;
import com.alibaba.easyretry.common.RetryConfiguration;

import lombok.Data;
import lombok.experimental.Accessors;

/**
 * @author Created by wuhao on 2021/3/19.
 */
@Data
@Accessors(chain = true)
public class RetryerInfo<T> {

	/**
	 * 执行者名称
	 */
	private String executorName;

	/**
	 * 执行者方法
	 */
	private String executorMethodName;

	private String onFailureMethod;

	/**
	 * 业务id,外部可以自定义存储一些信息
	 */
	private String bizId;

	private Object[] args;

	private Class<? extends Throwable> onException;

	private RetryConfiguration retryConfiguration;

	private String namespace;

	private boolean reThrowException;

	private AbstractResultPredicate<T> resultPredicate;

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/ArgDeSerializerInfo.java
================================================
package com.alibaba.easyretry.common.serializer;

import lombok.Data;

/**
 * @author Created by wuhao on 2020/11/1.
 */
@Data
public class ArgDeSerializerInfo {

	private String argsStr;
}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/ArgSerializerInfo.java
================================================
package com.alibaba.easyretry.common.serializer;

import lombok.Data;

/**
 * @author Created by wuhao on 2020/11/1.
 */
@Data
public class ArgSerializerInfo {

	/**
	 * 执行者名称
	 */
	private String executorName;

	private String executorClassName;

	/**
	 * 执行者方法
	 */
	private String executorMethodName;

	private Object[] args;
}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/EasyRetrySerializer.java
================================================
package com.alibaba.easyretry.common.serializer;

/**
 * @author Created by wuhao on 2021/3/18.
 */
public interface EasyRetrySerializer<T> {

	String serialize(T serializeInfo);

	T deSerialize(String infoStr);

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/ResultPredicateSerializer.java
================================================
package com.alibaba.easyretry.common.serializer;

import com.alibaba.easyretry.common.AbstractResultPredicate;

/**
 * @author Created by wuhao on 2021/3/18.
 */
public interface ResultPredicateSerializer extends EasyRetrySerializer<AbstractResultPredicate> {

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/RetryArgSerializer.java
================================================
package com.alibaba.easyretry.common.serializer;

/**
 * Retry 序列化器
 */
public interface RetryArgSerializer extends EasyRetrySerializer<ArgSerializerInfo> {

}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/strategy/RetryStrategy.java
================================================
package com.alibaba.easyretry.common.strategy;

import com.alibaba.easyretry.common.RetryContext;

/**
 * @author Created by wuhao on 2020/11/2.
 */
public interface RetryStrategy {

	void clear(RetryContext context);
}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/strategy/StopStrategy.java
================================================
package com.alibaba.easyretry.common.strategy;

import com.alibaba.easyretry.common.RetryContext;

/**
 * @author Created by wuhao on 2020/11/1.
 */
public interface StopStrategy extends RetryStrategy {

	boolean shouldStop(RetryContext context);
}


================================================
FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/strategy/WaitStrategy.java
================================================
package com.alibaba.easyretry.common.strategy;

import com.alibaba.easyretry.common.RetryContext;

/**
 * @author Created by wuhao on 2020/11/1.
 */
public interface WaitStrategy extends RetryStrategy {

	boolean shouldWait(RetryContext context);

	void backOff(RetryContext context);
}


================================================
FILE: easy-retry-core/pom.xml
================================================
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xmlns="http://maven.apache.org/POM/4.0.0"
		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.alibaba</groupId>
		<artifactId>easy-retry</artifactId>
		<version>${revision}</version>
		<relativePath>../pom.xml</relativePath>
	</parent>
	<artifactId>easy-retry-core</artifactId>

	<name>easy-retry-core</name>
	<description>easy-retry-core</description>
	<dependencies>
		<dependency>
			<groupId>${project.groupId}</groupId>
			<artifactId>easy-retry-common</artifactId>
		</dependency>

		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
		</dependency>

		<dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
		</dependency>

		<dependency>
			<groupId>com.caucho</groupId>
			<artifactId>hessian</artifactId>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
		</dependency>

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
		</dependency>

		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-collections4</artifactId>
		</dependency>
	</dependencies>
</project>


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/DegradeAbleRetryExecutor.java
================================================
package com.alibaba.easyretry.core;

import com.alibaba.easyretry.common.RetryContext;
import com.alibaba.easyretry.common.RetryExecutor;
import com.alibaba.easyretry.common.constant.enums.HandleResultEnum;
import com.alibaba.easyretry.core.degrade.EasyRetryDegradeHelper;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

/**
 * @author Created by gejinfeng on 2021/4/29.
 */
@Slf4j
public class DegradeAbleRetryExecutor implements RetryExecutor {

	@Setter
	private RetryExecutor retryExecutor;

	@Setter
	private EasyRetryDegradeHelper easyRetryDegradeHelper;

	@Override
	public HandleResultEnum doExecute(RetryContext context) {
		if (easyRetryDegradeHelper.degrade(context)) {
			return HandleResultEnum.STOP;
		}
		return retryExecutor.doExecute(context);
	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/PersistenceRetryExecutor.java
================================================
package com.alibaba.easyretry.core;

import java.lang.reflect.InvocationTargetException;

import com.alibaba.easyretry.common.RetryConfiguration;
import com.alibaba.easyretry.common.RetryContext;
import com.alibaba.easyretry.common.RetryExecutor;
import com.alibaba.easyretry.common.access.RetryTaskAccess;
import com.alibaba.easyretry.common.constant.enums.HandleResultEnum;
import com.alibaba.easyretry.common.entity.RetryTask;
import com.alibaba.easyretry.common.event.RetryEvent;
import com.alibaba.easyretry.common.event.on.FailureOnRetryEvent;
import com.alibaba.easyretry.common.event.on.StopOnRetryEvent;
import com.alibaba.easyretry.common.event.on.SuccessOnRetryEvent;
import com.alibaba.easyretry.common.filter.RetryFilterInvocation;
import com.alibaba.easyretry.common.filter.RetryFilterResponse;
import com.alibaba.easyretry.core.context.MaxAttemptsPersistenceRetryContext;
import com.alibaba.easyretry.core.process.async.on.AbstractAsyncPersistenceOnRetryProcessor;
import com.alibaba.easyretry.core.process.async.on.ExceptionPersistenceAsynOnRetryProcessor;
import com.alibaba.easyretry.core.process.async.on.ResultAsynPersistenceOnRetryProcessor;
import com.alibaba.easyretry.core.utils.LogUtils;
import com.alibaba.easyretry.core.utils.PrintUtils;

import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

/**
 * @author Created by wuhao on 2021/3/2.
 */
@Slf4j
public class PersistenceRetryExecutor implements RetryExecutor {

	@Setter
	private RetryConfiguration retryConfiguration;

	@Setter
	private RetryFilterInvocation retryFilterInvocation;

	@Override
	public HandleResultEnum doExecute(RetryContext context) {
		try {
			PrintUtils.monitorInfo("begin deal", context);
			return handle(context);
		} catch (Throwable e) {
			log.error("Retry invoke failed", e);
			return HandleResultEnum.ERROR;
		}
	}

	private HandleResultEnum handle(RetryContext context) {
		MaxAttemptsPersistenceRetryContext maxAttemptsPersistenceRetryContext
			= (MaxAttemptsPersistenceRetryContext)context;
		if (maxAttemptsPersistenceRetryContext.getWaitStrategy().shouldWait(context)) {
			PrintUtils.monitorInfo("shouldWait", context);
			return HandleResultEnum.WAITING;
		}
		PrintUtils.monitorInfo("handlingRetryTask", context);
		retryConfiguration.getRetryTaskAccess()
			.handlingRetryTask(maxAttemptsPersistenceRetryContext.getRetryTask());
		AbstractAsyncPersistenceOnRetryProcessor<Object> abstractAsynPersistenceOnRetryProcessor;
		try {
			PrintUtils.monitorInfo("beigin excuteMethod", context);
			RetryFilterResponse retryFilterResponse = retryFilterInvocation.invoke(context);
			abstractAsynPersistenceOnRetryProcessor = new ResultAsynPersistenceOnRetryProcessor<>(
				retryFilterResponse.getResponse(),
				maxAttemptsPersistenceRetryContext);
			PrintUtils.monitorInfo("excuteMethod success ", context);
		} catch (Throwable t) {
			if (t instanceof InvocationTargetException) {
				t = t.getCause();
			}
			log.error("excuteMethod failed task arg is {} task id is {}", context.getInvocation(),
				context.getId(), t);
			abstractAsynPersistenceOnRetryProcessor = new ExceptionPersistenceAsynOnRetryProcessor<>(
				t,
				maxAttemptsPersistenceRetryContext);
		}
		abstractAsynPersistenceOnRetryProcessor.process();
		HandleResultEnum handleResult = abstractAsynPersistenceOnRetryProcessor.getRetryResult();
		PrintUtils.monitorInfo("handleResult ", context, "handleResult is " + handleResult);
		RetryEvent onRetryEvent = null;
		switch (handleResult) {
			case SUCCESS:
				finish(context);
				onRetryEvent = new SuccessOnRetryEvent(context);
				break;
			case STOP:
				stop(context);
				onRetryEvent = new StopOnRetryEvent(context);
				break;
			case FAILURE:
				onRetryEvent = new FailureOnRetryEvent(context);
		}
		retryConfiguration.getRetryEventMulticaster().multicast(onRetryEvent);
		return handleResult;
	}

	private void finish(RetryContext context) {
		MaxAttemptsPersistenceRetryContext maxAttemptsPersistenceRetryContext
			= (MaxAttemptsPersistenceRetryContext)context;
		RetryTask retryTask = maxAttemptsPersistenceRetryContext.getRetryTask();
		try {
			RetryTaskAccess retryTaskAccess = retryConfiguration.getRetryTaskAccess();
			retryTaskAccess.finishRetryTask(retryTask);
			context.stop();
		} catch (Throwable t) {
			LogUtils.CONSISTENCY_LOGGER
				.error("finishRetryTask error " + context.getInvocation() + " please check", t);
		}
	}

	private void stop(RetryContext context) {
		try {
			MaxAttemptsPersistenceRetryContext maxAttemptsPersistenceRetryContext
				= (MaxAttemptsPersistenceRetryContext)context;
			RetryTaskAccess retryTaskAccess = retryConfiguration.getRetryTaskAccess();
			retryTaskAccess.stopRetryTask(maxAttemptsPersistenceRetryContext.getRetryTask());
			//executeOnFailureMethod(context);
			context.stop();
		} catch (Throwable t) {
			LogUtils.CONSISTENCY_LOGGER
				.error("stopRetryTask error " + context.getInvocation() + " please check", t);
		}
	}

	//private void executeOnFailureMethod(RetryContext context) {
	//
	//	MaxRetryTimesRetryContext maxRetryTimesRetryContext = (MaxRetryTimesRetryContext)context;
	//	String methodName = maxRetryTimesRetryContext.getOnFailureMethod();
	//	if (StringUtils.isEmpty(methodName)) {
	//		return;
	//	}
	//	Object executor = context.getExecutor();
	//	Method onFailure = BeanUtils.getMethod(methodName, executor.getClass());
	//	if (Objects.isNull(onFailure)) {
	//		return;
	//	}
	//	try {
	//		onFailure.invoke(executor, context);
	//	} catch (Throwable t) {
	//		LogUtils.CONSISTENCY_LOGGER.error(
	//			"executeOnFailureMethod failed onFailureMethod = {}"
	//				+ PrintUtils.printCommonMethodInfo(context)
	//				+ " please check",
	//			methodName,
	//			t);
	//	}
	//}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/PersistenceRetryer.java
================================================
package com.alibaba.easyretry.core;

import com.alibaba.easyretry.common.SCallable;
import com.alibaba.easyretry.common.processor.AsyncPersistenceProcessor;
import com.alibaba.easyretry.common.retryer.Retryer;
import com.alibaba.easyretry.common.retryer.RetryerInfo;
import com.alibaba.easyretry.core.process.async.before.ExceptionPersistenceAsyncBeforeRetryProcessor;
import com.alibaba.easyretry.core.process.async.before.ResultAsynPersistenceBeforeRetryProcessor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

/**
 * @author Created by wuhao on 2020/11/1.
 */
@Slf4j
@Data
public class PersistenceRetryer<V> implements Retryer<V> {

	private RetryerInfo<V> retryerInfo;

	public PersistenceRetryer(RetryerInfo<V> retryerInfo) {
		this.retryerInfo = retryerInfo;
	}

	@Override
	public V call(SCallable<V> callable) throws Throwable {
		AsyncPersistenceProcessor<V> asynPersistenceProcessor;
		try {
			V result = callable.call();
			asynPersistenceProcessor = new ResultAsynPersistenceBeforeRetryProcessor<>(result,
				retryerInfo);
		} catch (Throwable e) {
			log.error(
				"call method error executorMethodName is {} executorName name is {} args is {}",
				retryerInfo.getExecutorMethodName(),
				retryerInfo.getExecutorName(),
				retryerInfo.getArgs(),
				e);
			asynPersistenceProcessor = new ExceptionPersistenceAsyncBeforeRetryProcessor<>(e,
				retryerInfo);
		}
		asynPersistenceProcessor.process();
		return asynPersistenceProcessor.getResult();
	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/PersistenceRetryerBuilder.java
================================================
package com.alibaba.easyretry.core;

import com.alibaba.easyretry.common.AbstractResultPredicate;
import com.alibaba.easyretry.common.RetryConfiguration;
import com.alibaba.easyretry.common.retryer.RetryerInfo;

/**
 * @author Created by wuhao on 2020/11/1.
 */
public class PersistenceRetryerBuilder<T> {

	private PersistenceRetryer<T> persistenceRetryer;

	public PersistenceRetryerBuilder(RetryConfiguration retryConfiguration) {
		RetryerInfo<T> retryerInfo = new RetryerInfo<>();
		persistenceRetryer = new PersistenceRetryer<T>(retryerInfo);
	}

	public static <T> PersistenceRetryerBuilder<T> of(RetryConfiguration retryConfiguration) {
		return new PersistenceRetryerBuilder<>(retryConfiguration);
	}

	public PersistenceRetryerBuilder<T> withExecutorName(String executorName) {
		persistenceRetryer.getRetryerInfo().setExecutorName(executorName);
		return this;
	}

	public PersistenceRetryerBuilder<T> withExecutorMethodName(String executorMethodName) {
		persistenceRetryer.getRetryerInfo().setExecutorMethodName(executorMethodName);
		return this;
	}

	public PersistenceRetryerBuilder<T> withBizId(String bizId) {
		persistenceRetryer.getRetryerInfo().setBizId(bizId);
		return this;
	}

	public PersistenceRetryerBuilder<T> withArgs(Object[] args) {
		persistenceRetryer.getRetryerInfo().setArgs(args);
		return this;
	}

	public PersistenceRetryerBuilder<T> withOnException(Class<? extends Throwable> onException) {
		persistenceRetryer.getRetryerInfo().setOnException(onException);
		return this;
	}

	public PersistenceRetryerBuilder<T> withOnFailureMethod(String onFailureMethod) {
		persistenceRetryer.getRetryerInfo().setOnFailureMethod(onFailureMethod);
		return this;
	}

	public PersistenceRetryerBuilder<T> withReThrowException(boolean reThrowException) {
		persistenceRetryer.getRetryerInfo().setReThrowException(reThrowException);
		return this;
	}

	public PersistenceRetryerBuilder<T> withNamespace(String namespace) {
		persistenceRetryer.getRetryerInfo().setNamespace(namespace);
		return this;
	}

	public PersistenceRetryerBuilder<T> withConfiguration(RetryConfiguration retryConfiguration) {
		persistenceRetryer.getRetryerInfo().setRetryConfiguration(retryConfiguration);
		return this;
	}

	public PersistenceRetryerBuilder<T> withResultPredicate(AbstractResultPredicate<T> abstractResultPredicate) {
		persistenceRetryer.getRetryerInfo().setResultPredicate(abstractResultPredicate);
		return this;
	}

	public PersistenceRetryer<T> build() {
		return persistenceRetryer;
	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/RetryerBuilder.java
================================================
package com.alibaba.easyretry.core;

import com.alibaba.easyretry.common.AbstractResultPredicate;
import com.alibaba.easyretry.common.RetryConfiguration;
import com.alibaba.easyretry.common.constant.enums.RetryTypeEnum;
import com.alibaba.easyretry.common.retryer.Retryer;

/**
 * @author Created by zhangchi on 2023-07-13
 */
public class RetryerBuilder<T> {

	/**
	 * 执行者名称
	 */
	private String executorNameContext;

	/**
	 * 执行者方法
	 */
	private String executorMethodNameContext;

	private String onFailureMethodContext;

	/**
	 * 业务id,外部可以自定义存储一些信息
	 */
	private String bizIdContext;

	private Object[] argsContext;

	private Class<? extends Throwable> onExceptionContext;

	private RetryConfiguration retryConfigurationContext;

	private String namespaceContext;

	private boolean reThrowExceptionContext;

	private AbstractResultPredicate<T> resultPredicateContext;


	public RetryerBuilder<T> withExecutorName(String executorName) {
		executorNameContext = executorName;
		return this;
	}

	public RetryerBuilder<T> withExecutorMethodName(String executorMethodName) {
		executorMethodNameContext = executorMethodName;
		return this;
	}

	public RetryerBuilder<T> withBizId(String bizId) {
		bizIdContext = bizId;
		return this;
	}

	public RetryerBuilder<T> withArgs(Object[] args) {
		argsContext = args;
		return this;
	}

	public RetryerBuilder<T> withOnException(Class<? extends Throwable> onException) {
		onExceptionContext = onException;
		return this;
	}

	public RetryerBuilder<T> withOnFailureMethod(String onFailureMethod) {
		onFailureMethodContext = onFailureMethod;
		return this;
	}

	public RetryerBuilder<T> withReThrowException(boolean reThrowException) {
		reThrowExceptionContext = reThrowException;
		return this;
	}

	public RetryerBuilder<T> withNamespace(String namespace) {
		namespaceContext = namespace;
		return this;
	}

	public RetryerBuilder<T> withConfiguration(RetryConfiguration retryConfiguration) {
		retryConfigurationContext = retryConfiguration;
		return this;
	}

	public RetryerBuilder<T> withResultPredicate(AbstractResultPredicate<T> abstractResultPredicate) {
		resultPredicateContext = abstractResultPredicate;
		return this;
	}

	public Retryer<T> build(RetryTypeEnum retryTypeEnum) {
		if (RetryTypeEnum.SYNC == retryTypeEnum) {
			return buildSyncRetryer();
		} else {
			return buildAsyncRetryer();
		}
	}

	private SyncRetryer<T> buildSyncRetryer() {
		SyncRetryerBuilder<T> builder = SyncRetryerBuilder.<T>of(retryConfigurationContext)
				.withConfiguration(retryConfigurationContext);
		return builder.build();
	}

	private PersistenceRetryer<T> buildAsyncRetryer() {
		PersistenceRetryerBuilder<T> builder = PersistenceRetryerBuilder.<T>of(retryConfigurationContext)
			.withExecutorName(executorNameContext)
			.withExecutorMethodName(executorMethodNameContext)
			.withArgs(argsContext)
			.withConfiguration(retryConfigurationContext)
			//			.withOnFailureMethod(retryable.onFailureMethod())
			//			.withNamespace(namespace)
			.withReThrowException(reThrowExceptionContext)
			.withResultPredicate(resultPredicateContext);
		return builder.build();
	}

}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/SyncRetryer.java
================================================
package com.alibaba.easyretry.core;


import com.alibaba.easyretry.common.AbstractRetrySyncExecutor;
import com.alibaba.easyretry.common.SCallable;
import com.alibaba.easyretry.common.retryer.Retryer;
import com.alibaba.easyretry.common.retryer.RetryerInfo;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

/**
 * @author Created by zhangchi Created on 2023-07-12
 */
@Slf4j
@Data
public class SyncRetryer<V> implements Retryer<V> {

	private RetryerInfo<V> retryerInfo;

	public SyncRetryer(RetryerInfo<V> retryerInfo) {
		this.retryerInfo = retryerInfo;
	}

	@Override
	public V call(SCallable<V> callable) throws Throwable {
		AbstractRetrySyncExecutor retrySyncExecutor = retryerInfo.getRetryConfiguration().getRetrySyncExecutor();
		retrySyncExecutor.setRetryerInfo(retryerInfo);
		return (V) retrySyncExecutor.call(callable);
	}

}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/SyncRetryerBuilder.java
================================================
package com.alibaba.easyretry.core;

import java.util.Objects;

import com.alibaba.easyretry.common.RetryConfiguration;
import com.alibaba.easyretry.common.retryer.RetryerInfo;

/**
 * @author Created by zhangchi on 2023-07-12
 */
public class SyncRetryerBuilder<T> {

	private SyncRetryer<T> syncRetryer;

	public SyncRetryerBuilder(RetryConfiguration retryConfiguration) {
		RetryerInfo<T> retryerInfo = new RetryerInfo<>();
		syncRetryer = new SyncRetryer<>(retryerInfo);
	}

	public static <T> SyncRetryerBuilder<T> of(RetryConfiguration retryConfiguration) {
		return new SyncRetryerBuilder<>(retryConfiguration);
	}

	public SyncRetryerBuilder<T> withConfiguration(RetryConfiguration retryConfiguration) {
		syncRetryer.getRetryerInfo().setRetryConfiguration(retryConfiguration);
		return this;
	}


	public SyncRetryer<T> build() {
		return syncRetryer;
	}

}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/access/DefaultRetrySerializerAccess.java
================================================
package com.alibaba.easyretry.core.access;

import com.alibaba.easyretry.common.access.RetrySerializerAccess;
import com.alibaba.easyretry.common.serializer.RetryArgSerializer;
import com.alibaba.easyretry.core.serializer.HessianRetryArgSerializer;

/**
 * @author Created by wuhao on 2020/11/6.
 */
public class DefaultRetrySerializerAccess implements RetrySerializerAccess {

	@Override
	public RetryArgSerializer getCurrentGlobalRetrySerializer() {
		return new HessianRetryArgSerializer();
	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/access/MemoryRetryTaskAccess.java
================================================
package com.alibaba.easyretry.core.access;

import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

import com.alibaba.easyretry.common.access.RetryTaskAccess;
import com.alibaba.easyretry.common.constant.enums.RetryTaskStatusEnum;
import com.alibaba.easyretry.common.entity.RetryTask;

import com.google.common.collect.Maps;

/**
 * @author Created by wuhao on 2020/11/5.
 */
public class MemoryRetryTaskAccess implements RetryTaskAccess {

	private static final Map<Long, RetryTask> retryTaskMap = Maps.newConcurrentMap();

	private static final AtomicLong atomicLong = new AtomicLong();

	@Override
	public boolean saveRetryTask(RetryTask retryTask) {
		long id = atomicLong.getAndIncrement();
		retryTask.setId(id);
		retryTaskMap.putIfAbsent(id, retryTask);
		return true;
	}

	@Override
	public boolean handlingRetryTask(RetryTask retryTask) {
		retryTask.setStatus(RetryTaskStatusEnum.HANDLING);
		retryTaskMap.putIfAbsent(retryTask.getId(), retryTask);
		return true;
	}

	@Override
	public boolean finishRetryTask(RetryTask retryTask) {
		retryTaskMap.remove(retryTask.getId());
		return true;
	}

	@Override
	public boolean stopRetryTask(RetryTask retryTask) {
		retryTask.setStatus(RetryTaskStatusEnum.ERROR);
		retryTaskMap.putIfAbsent(retryTask.getId(), retryTask);
		return false;
	}

	@Override
	public List<RetryTask> listAvailableTasks(Long lastId) {
		return retryTaskMap.values().stream()
			.filter((retryTask) -> retryTask.getStatus() == RetryTaskStatusEnum.INIT)
			.filter((retryTask) -> retryTask.getId() > lastId)
			.sorted((o1, o2) -> o1.getId() > o2.getId() ? 1 : -1)
			.collect(Collectors.toList());
	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/container/SimpleRetryContainer.java
================================================
package com.alibaba.easyretry.core.container;

import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import com.alibaba.easyretry.common.RetryConfiguration;
import com.alibaba.easyretry.common.RetryContainer;
import com.alibaba.easyretry.common.RetryContext;
import com.alibaba.easyretry.common.RetryExecutor;
import com.alibaba.easyretry.common.constant.enums.HandleResultEnum;
import com.alibaba.easyretry.common.entity.RetryTask;
import com.alibaba.easyretry.core.context.MaxAttemptsPersistenceRetryContext.RetryContextBuilder;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;

/**
 * @author Created by wuhao on 2020/11/5.
 */
@Slf4j
public class SimpleRetryContainer implements RetryContainer {

	private static final Integer MAX_QUEUE_SIZE = 2000;

	private RetryConfiguration retryConfiguration;

	private RetryExecutor retryExecutor;

	public SimpleRetryContainer() {
	}

	public SimpleRetryContainer(
		RetryConfiguration retryConfiguration, RetryExecutor retryExecutor) {
		this.retryConfiguration = retryConfiguration;
		this.retryExecutor = retryExecutor;
	}

	@Override
	public void start() {
		BlockingQueue<RetryContext> queue = new PriorityBlockingQueue<>(MAX_QUEUE_SIZE);
		ThreadPoolExecutor retryExecutor =
			new ThreadPoolExecutor(
				1,
				1,
				0L,
				TimeUnit.MILLISECONDS,
				new LinkedBlockingQueue<>(),
				r -> new Thread(r, "retryExecutor-Thread"));
		retryExecutor.execute(new TaskConsumer(queue));
		ThreadPoolExecutor retrySelector =
			new ThreadPoolExecutor(
				1,
				1,
				0L,
				TimeUnit.MILLISECONDS,
				new LinkedBlockingQueue<>(),
				r -> new Thread(r, "retrySelector-Thread"));
		retrySelector.execute(new TaskProducer(queue));
	}

	@Override
	public void stop() {
	}

	public class TaskConsumer implements Runnable {

		private static final long MAX_SLEEP_TIME_MILLISECONDS = 10 * 1000L;
		private static final long SLEEP_BASE_TIME_MILLISECONDS = 1000L;
		private final BlockingQueue<RetryContext> queue;
		private long sleepTimes = 0L;

		private TaskConsumer(BlockingQueue<RetryContext> queue) {
			this.queue = queue;
		}

		@Override
		public void run() {
			while (!Thread.currentThread().isInterrupted()) {
				doExecute();
				long totalTime = sleepTimes * SLEEP_BASE_TIME_MILLISECONDS;
				try {
					TimeUnit.MILLISECONDS.sleep(Math.min(totalTime, MAX_SLEEP_TIME_MILLISECONDS));
				} catch (InterruptedException e) {
					log.error("taskConsumer interruptedException error", e);
				}
			}
		}

		private void doExecute() {
			try {
				RetryContext context = queue.take();
				HandleResultEnum result = retryExecutor.doExecute(context);
				if (HandleResultEnum.SUCCESS == result) {
					sleepTimes = 0L;
				} else if (HandleResultEnum.FAILURE == result) {
					sleepTimes = 0L;
					queue.add(context);
				} else if (HandleResultEnum.STOP == result) {
					sleepTimes = 0L;
				} else if (HandleResultEnum.ERROR == result) {
					sleepTimes = 0L;
					// do nothing
				} else {
					sleepTimes++;
					queue.add(context);
				}
			} catch (InterruptedException e) {
				log.error("Retry execute failed when getting retry task", e);
			} catch (Throwable e) {
				log.error("Retry invoke failed", e);
			}
		}
	}

	public class TaskProducer implements Runnable {

		private static final long MAX_SLEEP_TIME_MILLISECONDS = 10 * 1000L;
		private static final long SLEEP_BASE_TIME_MILLISECONDS = 1000L;

		private final BlockingQueue<RetryContext> queue;

		private long sleepTimes = 0L;

		private volatile Long lastId = -1L;

		public TaskProducer(BlockingQueue<RetryContext> queue) {
			this.queue = queue;
		}

		@Override
		public void run() {
			while (!Thread.currentThread().isInterrupted()) {
				doSelect();
				long totalTime =
					sleepTimes * SLEEP_BASE_TIME_MILLISECONDS + SLEEP_BASE_TIME_MILLISECONDS;
				try {
					TimeUnit.MILLISECONDS.sleep(Math.min(totalTime, MAX_SLEEP_TIME_MILLISECONDS));
				} catch (InterruptedException e) {
					log.error("taskConsumer interruptedException error", e);
				}
			}
		}

		private void doSelect() {
			if (queue.size() >= MAX_QUEUE_SIZE) {
				sleepTimes++;
				return;
			}

			List<RetryTask> tasks =
				retryConfiguration.getRetryTaskAccess().listAvailableTasks(lastId);
			if (CollectionUtils.isEmpty(tasks)) {
				sleepTimes++;
				return;
			}
			if (queue.size() >= MAX_QUEUE_SIZE) {
				sleepTimes++;
				return;
			}
			if (queue.size() + tasks.size() >= MAX_QUEUE_SIZE) {
				sleepTimes++;
			} else {
				sleepTimes = 0L;
			}
			for (RetryTask task : tasks) {
				try {
					lastId = task.getId();
					RetryContext retryContext =
						new RetryContextBuilder(retryConfiguration, task)
							.buildInvocation()
							.buildRetryArgSerializer()
							.buildStopStrategy()
							.buildWaitStrategy()
							.buildRetryTask()
							.buildMaxRetryTimes()
							.buildOnFailureMethod()
							.buildPriority(0L)
							.buildResultPredicateSerializer()
							.build();
					retryContext.start();

					queue.put(retryContext);
					log.warn("add retry task to queue, task:{}",
						task.getId());
				} catch (Throwable e) {
					log.error("add retry task to queue , task:{}",
						task.getId(), e);
					// 出现异常task将放不进queue中,就不会再重试了
					// 是否需要更新task的状态,并且加上失败的原因?
				}
			}
		}
	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/context/MaxAttemptsPersistenceRetryContext.java
================================================
package com.alibaba.easyretry.core.context;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

import com.alibaba.easyretry.common.Invocation;
import com.alibaba.easyretry.common.RetryConfiguration;
import com.alibaba.easyretry.common.RetryContext;
import com.alibaba.easyretry.common.RetryLifecycle;
import com.alibaba.easyretry.common.SimpleMethodInvocation;
import com.alibaba.easyretry.common.entity.RetryTask;
import com.alibaba.easyretry.common.serializer.ResultPredicateSerializer;
import com.alibaba.easyretry.common.serializer.RetryArgSerializer;
import com.alibaba.easyretry.common.strategy.StopStrategy;
import com.alibaba.easyretry.common.strategy.WaitStrategy;

import com.google.common.collect.Maps;
import lombok.Data;
import lombok.ToString;
import org.apache.commons.lang3.reflect.MethodUtils;

@Data
@ToString(callSuper = true)
public class MaxAttemptsPersistenceRetryContext implements RetryContext, RetryLifecycle,
	Comparable<MaxAttemptsPersistenceRetryContext> {

	private RetryTask retryTask;

	private RetryArgSerializer retryArgSerializer;

	private ResultPredicateSerializer resultPredicateSerializer;

	private Long priority;

	private StopStrategy stopStrategy;

	private WaitStrategy waitStrategy;

	private int maxRetryTimes;

	private String onFailureMethod;

	private Invocation invocation;

	@Override
	public int compareTo(MaxAttemptsPersistenceRetryContext o) {
		return this.priority > o.getPriority() ? 1 : -1;
	}

	@Override
	public void start() {
	}

	@Override
	public void stop() {
		stopStrategy.clear(this);
		waitStrategy.clear(this);
	}

	@Override
	public void setAttribute(String key, String value) {
		Map<String, String> extAttrs = retryTask.getExtAttrs();
		if (Objects.isNull(extAttrs)) {
			extAttrs = Maps.newHashMap();
		}
		extAttrs.put(key, value);
	}

	@Override
	public String getAttribute(String key) {
		Map<String, String> extAttrs = retryTask.getExtAttrs();
		if (Objects.isNull(extAttrs)) {
			return null;
		} else {
			return extAttrs.get(key);
		}
	}

	public Long getNextRetryTime(TimeUnit unit) {
		return unit.convert(priority, TimeUnit.MILLISECONDS);
	}

	public void setNextRetryTime(Long nexRetryTime, TimeUnit unit) {
		priority = unit.toMillis(nexRetryTime);
	}

	@Override
	public String getId() {
		return retryTask.getId() + "";
	}

	public static class RetryContextBuilder {

		private MaxAttemptsPersistenceRetryContext retryContext;

		private RetryConfiguration retryConfiguration;

		private RetryTask retryTask;

		public RetryContextBuilder(RetryConfiguration retryConfiguration, RetryTask retryTask) {
			retryContext = new MaxAttemptsPersistenceRetryContext();
			this.retryConfiguration = retryConfiguration;
			this.retryTask = retryTask;
		}

		public RetryContextBuilder buildInvocation() {
			RetryArgSerializer retryArgSerializer = retryConfiguration.getRetrySerializerAccess()
				.getCurrentGlobalRetrySerializer();
			Object[] args = retryArgSerializer.deSerialize(retryTask.getArgsStr()).getArgs();
			Object executor = retryConfiguration.getExecutorSolver()
				.resolver(retryTask.getExecutorName());
			Class<?>[] classes = Stream.of(args).map(Object::getClass).toArray(Class[]::new);
			Method method = MethodUtils
				.getMatchingMethod(executor.getClass(), retryTask.getExecutorMethodName(), classes);
			SimpleMethodInvocation simpleMethodInvocation = new SimpleMethodInvocation(executor,
				method, args);
			retryContext.setInvocation(simpleMethodInvocation);
			return this;
		}

		public RetryContextBuilder buildRetryArgSerializer() {
			retryContext.setRetryArgSerializer(
				retryConfiguration.getRetrySerializerAccess().getCurrentGlobalRetrySerializer());
			return this;
		}

		public RetryContextBuilder buildStopStrategy() {
			retryContext.setStopStrategy(
				retryConfiguration.getRetryStrategyAccess().getCurrentGlobalStopStrategy());
			return this;
		}

		public RetryContextBuilder buildWaitStrategy() {
			retryContext.setWaitStrategy(
				retryConfiguration.getRetryStrategyAccess().getCurrentGlobalWaitStrategy());
			return this;
		}

		public RetryContextBuilder buildRetryTask() {
			retryContext.setRetryTask(retryTask);
			return this;
		}

		public RetryContextBuilder buildMaxRetryTimes() {
			retryContext.setMaxRetryTimes(retryConfiguration.getMaxRetryTimes());
			return this;
		}

		public RetryContextBuilder buildOnFailureMethod() {
			retryContext.setOnFailureMethod(retryTask.getOnFailureMethod());
			return this;
		}

		public RetryContextBuilder buildResultPredicateSerializer() {
			retryContext
				.setResultPredicateSerializer(retryConfiguration.getResultPredicateSerializer());
			return this;
		}

		public RetryContextBuilder buildPriority(Long priority) {
			retryContext.setPriority(priority);
			return this;
		}

		public MaxAttemptsPersistenceRetryContext build() {
			return retryContext;
		}
	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/degrade/EasyRetryDegradeHelper.java
================================================
package com.alibaba.easyretry.core.degrade;

import com.alibaba.easyretry.common.RetryContext;

/**
 * @author Created by gejinfeng on 2021/4/29.
 */
public interface EasyRetryDegradeHelper {

	/**
	 * 是否降级
	 *
	 * @param retryContext retryContext
	 * @return degrade
	 */
	boolean degrade(RetryContext retryContext);

}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/event/SimpleRetryEventMulticaster.java
================================================
package com.alibaba.easyretry.core.event;

import java.util.List;
import java.util.Objects;

import com.alibaba.easyretry.common.event.RetryEvent;
import com.alibaba.easyretry.common.event.RetryEventMulticaster;
import com.alibaba.easyretry.common.event.RetryListener;

import com.google.common.collect.Lists;
import lombok.Setter;

/**
 * @author Created by wuhao on 2021/3/26.
 */
public class SimpleRetryEventMulticaster implements RetryEventMulticaster {

	@Setter
	private List<RetryListener> listenerCaches = Lists.newArrayList();

	@Override
	public void register(RetryListener listener) {
		listenerCaches.add(listener);
	}

	@Override
	public void multicast(RetryEvent retryEvent) {
		if (Objects.isNull(retryEvent)) {
			return;
		}
		listenerCaches.forEach((retryListener) -> retryListener.onRetryEvent(retryEvent));
	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/DefaultRetryFilterInvocationHandler.java
================================================
package com.alibaba.easyretry.core.filter;

import java.util.List;

import com.alibaba.easyretry.common.RetryContext;
import com.alibaba.easyretry.common.filter.RetryFilter;
import com.alibaba.easyretry.common.filter.RetryFilterInvocation;
import com.alibaba.easyretry.common.filter.RetryFilterInvocationHandler;
import com.alibaba.easyretry.common.filter.RetryFilterRegister;
import com.alibaba.easyretry.common.filter.RetryFilterResponse;

import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils;

/**
 * @author Created by wuhao on 2021/3/22.
 */
public class DefaultRetryFilterInvocationHandler implements RetryFilterInvocationHandler, RetryFilterInvocation {

	private RetryFilter firstFilter;

	@Setter
	private RetryFilterRegister retryFilterRegister;

	@Override
	public RetryFilterResponse invoke(RetryContext retryContext) throws Throwable {
		return firstFilter.doFilter(retryContext);
	}

	@Override
	public void handle() {
		List<RetryFilter> retryFilters = retryFilterRegister.export();
		firstFilter = new NOOPRetryFilter();
		RetryFilter lastRetryFilter = firstFilter;

		for (RetryFilter retryFilter : CollectionUtils.emptyIfNull(retryFilters)) {
			lastRetryFilter.setNext(retryFilter);
			lastRetryFilter = retryFilter;
		}

		IdentifyRetryFilter identifyRetryFilter = new IdentifyRetryFilter();
		lastRetryFilter.setNext(identifyRetryFilter);
		lastRetryFilter = identifyRetryFilter;

		MethodExcuteRetryFilter methodExcuteRetryFilter = new MethodExcuteRetryFilter();
		lastRetryFilter.setNext(methodExcuteRetryFilter);

	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/DefaultRetryFilterRegisterHandler.java
================================================
package com.alibaba.easyretry.core.filter;

import java.util.List;

import com.alibaba.easyretry.common.filter.RetryFilter;
import com.alibaba.easyretry.common.filter.RetryFilterDiscover;
import com.alibaba.easyretry.common.filter.RetryFilterRegister;
import com.alibaba.easyretry.common.filter.RetryFilterRegisterHandler;

import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils;

/**
 * @author Created by wuhao on 2021/4/9.
 */
public class DefaultRetryFilterRegisterHandler implements RetryFilterRegisterHandler {

	@Setter
	private RetryFilterDiscover retryFilterDiscover;

	@Setter
	private RetryFilterRegister retryFilterRegister;

	@Override
	public void handle() {
		List<RetryFilter> retryFilters = retryFilterDiscover.discoverAll();
		for (RetryFilter retryFilter : CollectionUtils.emptyIfNull(retryFilters)) {
			retryFilterRegister.register(retryFilter);
		}
	}

}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/IdentifyRetryFilter.java
================================================
package com.alibaba.easyretry.core.filter;

import com.alibaba.easyretry.common.RetryContext;
import com.alibaba.easyretry.common.RetryIdentify;
import com.alibaba.easyretry.common.filter.AbstractRetryFilter;
import com.alibaba.easyretry.common.filter.RetryFilterResponse;

/**
 * @author Created by wuhao on 2021/3/22.
 */
public class IdentifyRetryFilter extends AbstractRetryFilter {

	@Override
	public RetryFilterResponse doFilter(RetryContext retryContext) throws Throwable {
		try {
			RetryIdentify.start();
			return next.doFilter(retryContext);
		} finally {
			RetryIdentify.stop();
		}
	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/MethodExcuteRetryFilter.java
================================================
package com.alibaba.easyretry.core.filter;

import com.alibaba.easyretry.common.RetryContext;
import com.alibaba.easyretry.common.filter.RetryFilter;
import com.alibaba.easyretry.common.filter.RetryFilterResponse;

/**
 * @author Created by wuhao on 2021/3/22.
 */
public class MethodExcuteRetryFilter implements RetryFilter {

	@Override
	public RetryFilterResponse doFilter(RetryContext retryContext) throws Throwable {
		RetryFilterResponse retryFilterResponse = new RetryFilterResponse();
		retryFilterResponse.setResponse(retryContext.getInvocation().invoke());
		return retryFilterResponse;
	}

	@Override
	public void setNext(RetryFilter next) {

	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/NOOPRetryFilter.java
================================================
package com.alibaba.easyretry.core.filter;

import com.alibaba.easyretry.common.RetryContext;
import com.alibaba.easyretry.common.filter.AbstractRetryFilter;
import com.alibaba.easyretry.common.filter.RetryFilterResponse;

/**
 * @author Created by wuhao on 2021/3/22.
 */
public class NOOPRetryFilter extends AbstractRetryFilter {

	@Override
	public RetryFilterResponse doFilter(RetryContext retryContext) throws Throwable {
		return next.doFilter(retryContext);
	}

}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/SPIRetryFilterDiscover.java
================================================
package com.alibaba.easyretry.core.filter;

import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;

import com.alibaba.easyretry.common.filter.RetryFilter;
import com.alibaba.easyretry.common.filter.RetryFilterDiscover;

import com.google.common.collect.Lists;

/**
 * @author Created by wuhao on 2021/4/9.
 */
public class SPIRetryFilterDiscover implements RetryFilterDiscover {

	@Override
	public List<RetryFilter> discoverAll() {
		ServiceLoader<RetryFilter> retryFilters = ServiceLoader.load(RetryFilter.class);
		Iterator<RetryFilter> iterator = retryFilters.iterator();
		return Lists.newArrayList(iterator);
	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/SimpleRetryFilterRegister.java
================================================
package com.alibaba.easyretry.core.filter;

import java.util.List;

import com.alibaba.easyretry.common.filter.RetryFilter;
import com.alibaba.easyretry.common.filter.RetryFilterRegister;

import com.google.common.collect.Lists;

/**
 * @author Created by wuhao on 2021/4/9.
 */
public class SimpleRetryFilterRegister implements RetryFilterRegister {

	private List<RetryFilter> retryFiltersCache = Lists.newArrayList();

	@Override
	public void register(RetryFilter retryFilter) {
		retryFiltersCache.add(retryFilter);
	}

	@Override
	public List<RetryFilter> export() {
		return retryFiltersCache;
	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/AbstractAsyncPersistenceProcessor.java
================================================
package com.alibaba.easyretry.core.process.async;

import com.alibaba.easyretry.common.processor.AsyncPersistenceProcessor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author Created by wuhao on 2021/3/19.
 */
@Slf4j
public abstract class AbstractAsyncPersistenceProcessor<R> implements AsyncPersistenceProcessor<R> {

	@Override
	public void process() {
		if (!needRetry()) {
			return;
		}
		doProcess();
	}

	protected abstract void doProcess();

	@Override
	public abstract boolean needRetry();

}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/before/AbstractAsyncPersistenceBeforeRetryProcessor.java
================================================
package com.alibaba.easyretry.core.process.async.before;

import java.util.Date;
import java.util.Map;
import java.util.Objects;

import com.alibaba.easyretry.common.RetryConfiguration;
import com.alibaba.easyretry.common.constant.enums.RetryTaskStatusEnum;
import com.alibaba.easyretry.common.entity.RetryTask;
import com.alibaba.easyretry.common.event.before.AfterSaveBeforeRetryEvent;
import com.alibaba.easyretry.common.event.before.PrepSaveBeforeRetryEvent;
import com.alibaba.easyretry.common.retryer.RetryerInfo;
import com.alibaba.easyretry.common.serializer.ArgSerializerInfo;
import com.alibaba.easyretry.core.process.async.AbstractAsyncPersistenceProcessor;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;

/**
 * @author Created by wuhao on 2021/3/19.
 */
@Slf4j
public abstract class AbstractAsyncPersistenceBeforeRetryProcessor<R> extends
	AbstractAsyncPersistenceProcessor<R> {

	protected RetryerInfo<R> retryerInfo;

//	private RetryConfiguration retryConfiguration;

	public AbstractAsyncPersistenceBeforeRetryProcessor(
		RetryerInfo<R> retryerInfo) {
		this.retryerInfo = retryerInfo;
//		this.retryConfiguration = retryConfiguration;
	}

	@Override
	public void doProcess() {
		RetryConfiguration retryConfiguration = retryerInfo.getRetryConfiguration();
		ArgSerializerInfo argSerializerInfo = new ArgSerializerInfo();
		argSerializerInfo.setArgs(retryerInfo.getArgs());
		argSerializerInfo.setExecutorMethodName(retryerInfo.getExecutorMethodName());
		argSerializerInfo.setExecutorName(retryerInfo.getExecutorName());
		String argsStr = retryConfiguration.getRetrySerializerAccess()
			.getCurrentGlobalRetrySerializer().serialize(argSerializerInfo);

		RetryTask retryTask = new RetryTask();
		retryTask.setBizId(retryerInfo.getBizId());
		retryTask.setArgsStr(argsStr);
		retryTask.setStatus(RetryTaskStatusEnum.INIT);
		retryTask.setExecutorMethodName(retryerInfo.getExecutorMethodName());
		retryTask.setExecutorName(retryerInfo.getExecutorName());
		retryTask.setOnFailureMethod(retryerInfo.getOnFailureMethod());
		retryTask.setGmtCreate(new Date());
		retryTask.setGmtModified(new Date());

		Map<String, String> extAttrs = Maps.newHashMap();
		if (Objects.nonNull(retryerInfo.getResultPredicate())) {
			extAttrs.put("resultPredicateSerializer",
				retryConfiguration.getResultPredicateSerializer()
					.serialize(retryerInfo.getResultPredicate()));
		}
		retryTask.setExtAttrs(extAttrs);

		PrepSaveBeforeRetryEvent prepSaveBeforeRetryEvent = new PrepSaveBeforeRetryEvent(retryTask);
		retryConfiguration.getRetryEventMulticaster().multicast(prepSaveBeforeRetryEvent);

		retryConfiguration.getRetryTaskAccess().saveRetryTask(retryTask);

		AfterSaveBeforeRetryEvent afterSaveBeforeRetryEvent = new AfterSaveBeforeRetryEvent(
			retryTask);
		retryConfiguration.getRetryEventMulticaster().multicast(afterSaveBeforeRetryEvent);
	}

}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/before/ExceptionPersistenceAsyncBeforeRetryProcessor.java
================================================
package com.alibaba.easyretry.core.process.async.before;

import java.util.Objects;

import com.alibaba.easyretry.common.RetryConfiguration;
import com.alibaba.easyretry.common.retryer.RetryerInfo;

import org.apache.commons.lang3.ClassUtils;

/**
 * @author Created by wuhao on 2021/3/19.
 */
public class ExceptionPersistenceAsyncBeforeRetryProcessor<R> extends
	AbstractAsyncPersistenceBeforeRetryProcessor<R> {

	private Throwable throwable;

	public ExceptionPersistenceAsyncBeforeRetryProcessor(Throwable throwable,
		RetryerInfo<R> retryerInfo) {
		super(retryerInfo);
		this.throwable = throwable;
	}

	@Override
	public boolean needRetry() {
		Class<? extends Throwable> onException = retryerInfo.getOnException();
		if (Objects.isNull(onException)) {
			return true;
		}
		return ClassUtils.isAssignable(retryerInfo.getOnException(), throwable.getClass());
	}

	@Override
	public R getResult() throws Throwable {
		if (retryerInfo.isReThrowException()) {
			throw throwable;
		} else {
			return null;
		}
	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/before/ResultAsynPersistenceBeforeRetryProcessor.java
================================================
package com.alibaba.easyretry.core.process.async.before;

import java.util.Objects;

import com.alibaba.easyretry.common.AbstractResultPredicate;
import com.alibaba.easyretry.common.retryer.RetryerInfo;

/**
 * @author Created by wuhao on 2021/3/19.
 */
public class ResultAsynPersistenceBeforeRetryProcessor<R> extends
    AbstractAsyncPersistenceBeforeRetryProcessor<R> {

	private final R result;

	public ResultAsynPersistenceBeforeRetryProcessor(R result, RetryerInfo<R> retryerInfo) {
		super(retryerInfo);
		this.result = result;
	}

	@Override
	public boolean needRetry() {
		AbstractResultPredicate<R> easyRetryPredicate = retryerInfo.getResultPredicate();
		if (Objects.nonNull(easyRetryPredicate)) {
			return easyRetryPredicate.apply(result);
		} else {
			return false;
		}
	}

	@Override
	public R getResult() {
		return result;
	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/on/AbstractAsyncPersistenceOnRetryProcessor.java
================================================
package com.alibaba.easyretry.core.process.async.on;

import com.alibaba.easyretry.common.constant.enums.HandleResultEnum;
import com.alibaba.easyretry.core.context.MaxAttemptsPersistenceRetryContext;
import com.alibaba.easyretry.core.process.async.AbstractAsyncPersistenceProcessor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author Created by wuhao on 2021/3/19.
 */
@Slf4j
public abstract class AbstractAsyncPersistenceOnRetryProcessor<R> extends
	AbstractAsyncPersistenceProcessor<R> {

	protected MaxAttemptsPersistenceRetryContext context;

	private HandleResultEnum retryResult;


	public AbstractAsyncPersistenceOnRetryProcessor(MaxAttemptsPersistenceRetryContext context) {
		this.context = context;
	}

	@Override
	public void process() {
		if (!needRetry()) {
			retryResult = HandleResultEnum.SUCCESS;
			return;
		}
		doProcess();
	}

	@Override
	public void doProcess() {
		if (context.getStopStrategy().shouldStop(context)) {
			log.error(context.getInvocation() + " will stop");
			retryResult = HandleResultEnum.STOP;
		} else {
			log.error(context.getInvocation() + " will try later");
			context.getWaitStrategy().backOff(context);
			retryResult = HandleResultEnum.FAILURE;
		}
	}

	public HandleResultEnum getRetryResult() {
		return retryResult;
	}

}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/on/ExceptionPersistenceAsynOnRetryProcessor.java
================================================
package com.alibaba.easyretry.core.process.async.on;

import com.alibaba.easyretry.core.context.MaxAttemptsPersistenceRetryContext;

/**
 * @author Created by wuhao on 2021/3/19.
 */
public class ExceptionPersistenceAsynOnRetryProcessor<R> extends
	AbstractAsyncPersistenceOnRetryProcessor<R> {

	private final Throwable throwable;

	public ExceptionPersistenceAsynOnRetryProcessor(Throwable throwable,
													MaxAttemptsPersistenceRetryContext context) {
		super(context);
		this.throwable = throwable;
	}

	@Override
	public boolean needRetry() {
		return true;
	}

	@Override
	public R getResult() {
		return null;
	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/on/ResultAsynPersistenceOnRetryProcessor.java
================================================
package com.alibaba.easyretry.core.process.async.on;

import com.alibaba.easyretry.common.AbstractResultPredicate;
import com.alibaba.easyretry.core.context.MaxAttemptsPersistenceRetryContext;

import org.apache.commons.lang3.StringUtils;

/**
 * @author Created by wuhao on 2021/3/19.
 */
public class ResultAsynPersistenceOnRetryProcessor<R> extends
    AbstractAsyncPersistenceOnRetryProcessor<R> {

	private R result;

	public ResultAsynPersistenceOnRetryProcessor(R result,
												 MaxAttemptsPersistenceRetryContext context) {
		super(context);
		this.result = result;
	}

	@Override
	public boolean needRetry() {
		String resultPredicateSerializerStr = context.getAttribute("resultPredicateSerializer");
		if (StringUtils.isBlank(resultPredicateSerializerStr)) {
			return false;
		}
		AbstractResultPredicate resultPredicate = context.getResultPredicateSerializer()
			.deSerialize(resultPredicateSerializerStr);
		return resultPredicate.apply(result);
	}

	@Override
	public R getResult() {
		return result;
	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/package-info.java
================================================
/**
 * @author Created by wuhao on 2021/3/19.
 */
package com.alibaba.easyretry.core.process;


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/serializer/FastJsonRetryArgSerializer.java
================================================
package com.alibaba.easyretry.core.serializer;

import java.util.stream.Stream;

import com.alibaba.easyretry.common.serializer.ArgSerializerInfo;
import com.alibaba.easyretry.common.serializer.RetryArgSerializer;
import com.alibaba.fastjson.JSON;

import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils;

/**
 *
 */
public class FastJsonRetryArgSerializer implements RetryArgSerializer {

	public static final String SPLIT = "||";

	public static final String INNER_SPLIT = "&&";

	@Override
	public String serialize(ArgSerializerInfo argSerializerInfo) {
		StringBuilder sb = new StringBuilder();
		Stream.of(argSerializerInfo.getArgs()).forEach(
			(arg) -> sb.append(JSON.toJSONString(arg)).append(INNER_SPLIT)
				.append(arg.getClass().getName()).append(SPLIT));
		if (sb.length() >= SPLIT.length()) {
			return sb.subSequence(0, sb.length() - SPLIT.length()).toString();
		} else {
			return null;
		}
	}

	@Override
	public ArgSerializerInfo deSerialize(String argsStr) {
		String[] strs = StringUtils.split(argsStr, SPLIT);
		Object[] arg = Stream.of(strs)
			.map((str) -> {
				String[] inner = str.split(INNER_SPLIT);
				try {
					return JSON.parseObject(inner[0], ClassUtils.getClass(inner[1]));
				} catch (ClassNotFoundException e) {
					throw new RuntimeException(e);
				}
			})
			.toArray();
		ArgSerializerInfo argSerializerInfo = new ArgSerializerInfo();
		argSerializerInfo.setArgs(arg);
		return argSerializerInfo;
	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/serializer/HessianResultPredicateSerializer.java
================================================
package com.alibaba.easyretry.core.serializer;

import com.alibaba.easyretry.common.AbstractResultPredicate;
import com.alibaba.easyretry.common.serializer.ResultPredicateSerializer;
import com.alibaba.easyretry.core.utils.HessianSerializerUtils;

/**
 * @author Created by wuhao on 2021/3/18.
 */
public class HessianResultPredicateSerializer implements ResultPredicateSerializer {

	@Override
	public String serialize(AbstractResultPredicate serializeInfo) {
		return HessianSerializerUtils.serialize(serializeInfo);
	}

	@Override
	public AbstractResultPredicate deSerialize(String infoStr) {
		return HessianSerializerUtils.deSerialize(infoStr, AbstractResultPredicate.class);
	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/serializer/HessianRetryArgSerializer.java
================================================
package com.alibaba.easyretry.core.serializer;

/**
 * @author Created by wuhao on 2021/2/22.
 */

import com.alibaba.easyretry.common.serializer.ArgSerializerInfo;
import com.alibaba.easyretry.common.serializer.RetryArgSerializer;
import com.alibaba.easyretry.core.utils.HessianSerializerUtils;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class HessianRetryArgSerializer implements RetryArgSerializer {

	@Override
	public String serialize(ArgSerializerInfo argSerializerInfo) {
		Object[] args = argSerializerInfo.getArgs();
		if (args.length == 0) {
			throw new IllegalStateException("No args found");
		}
		return HessianSerializerUtils.serialize(args);
	}

	@Override
	public ArgSerializerInfo deSerialize(String argStr) {
		Object[] result = HessianSerializerUtils.deSerialize(argStr, Object[].class);
		ArgSerializerInfo argSerializerInfo = new ArgSerializerInfo();
		argSerializerInfo.setArgs(result);
		return argSerializerInfo;
	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/strategy/DefaultRetryStrategy.java
================================================
package com.alibaba.easyretry.core.strategy;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import com.alibaba.easyretry.common.RetryContext;
import com.alibaba.easyretry.common.strategy.StopStrategy;
import com.alibaba.easyretry.common.strategy.WaitStrategy;
import com.alibaba.easyretry.core.context.MaxAttemptsPersistenceRetryContext;

import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class DefaultRetryStrategy implements StopStrategy, WaitStrategy {

	private static final Long MAX_INTERNAL_TIME = 15 * 60 * 1000L;
	private static final Long BASE_INTERNAL_TIME = 5000L;
	private final Map<String, Long> internalTimeMap = Maps.newConcurrentMap();
	private final Map<String, Integer> retryTimeMap = Maps.newConcurrentMap();

	@Override
	public boolean shouldStop(RetryContext context) {
		MaxAttemptsPersistenceRetryContext maxAttemptsPersistenceRetryContext
			= (MaxAttemptsPersistenceRetryContext)context;
		Integer retryTimes = retryTimeMap.get(context.getId());
		if (Objects.isNull(retryTimes)) {
			retryTimes = 1;
		}
		log.warn(
			"shouldStop retryTime is {} id is {} maxRetryTime is {}",
			retryTimes,
			context.getId(),
			maxAttemptsPersistenceRetryContext.getMaxRetryTimes());
		return retryTimes >= maxAttemptsPersistenceRetryContext.getMaxRetryTimes();
	}

	@Override
	public boolean shouldWait(RetryContext context) {
		MaxAttemptsPersistenceRetryContext maxAttemptsPersistenceRetryContext
			= (MaxAttemptsPersistenceRetryContext)context;
		internalTimeMap.putIfAbsent(context.getId(), 0L);
		Long priority = maxAttemptsPersistenceRetryContext.getNextRetryTime(TimeUnit.MILLISECONDS);
		if (Objects.isNull(priority)) {
			priority = 0L;
		}
		return System.currentTimeMillis() < priority;
	}

	@Override
	public void backOff(RetryContext context) {
		MaxAttemptsPersistenceRetryContext maxAttemptsPersistenceRetryContext
			= (MaxAttemptsPersistenceRetryContext)context;

		Integer retryTime = retryTimeMap.get(context.getId());
		Long lastInternalTime = internalTimeMap.get(context.getId());
		if (Objects.isNull(retryTime)) {
			retryTime = 1;
		}
		if (Objects.isNull(lastInternalTime)) {
			lastInternalTime = 0L;
		}
		long nextInternalTime = retryTime * (lastInternalTime + BASE_INTERNAL_TIME);
		nextInternalTime = Math.min(nextInternalTime, MAX_INTERNAL_TIME);

		internalTimeMap.put(context.getId(), nextInternalTime);

		retryTime++;
		retryTimeMap.put(context.getId(), retryTime);
		maxAttemptsPersistenceRetryContext
			.setNextRetryTime(System.currentTimeMillis() + nextInternalTime, TimeUnit.MILLISECONDS);
		log.warn(
			"backOff nextInternalTime is {} id is {} retryTime is {}",
			nextInternalTime,
			context.getId(),
			retryTime);
	}

	@Override
	public void clear(RetryContext context) {
		internalTimeMap.remove(context.getId());
		retryTimeMap.remove(context.getId());
	}
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/utils/HessianSerializerUtils.java
================================================
package com.alibaba.easyretry.core.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;

import com.caucho.hessian.io.HessianInput;
import com.caucho.hessian.io.HessianOutput;

/**
 * @author Created by wuhao on 2021/3/18.
 */
public class HessianSerializerUtils {

	public static <T> String serialize(T t) {
		try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
			HessianOutput ho = new HessianOutput(os);
			ho.writeObject(t);
			return Base64.getEncoder().encodeToString(os.toByteArray());
		} catch (IOException e) {
			throw new IllegalStateException("HessianSerializationConverter.serialize failed.", e);
		}
	}

	public static <T> T deSerialize(String str, Class<T> tClass) {
		byte[] convertBytes = Base64.getDecoder().decode(str);
		try (ByteArrayInputStream is = new ByteArrayInputStream(convertBytes)) {
			HessianInput hi = new HessianInput(is);
			return (T)hi.readObject(tClass);
		} catch (IOException e) {
			throw new IllegalStateException("HessianSerializationConverter.deSerialize failed.", e);
		}
	}

}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/utils/LogUtils.java
================================================
package com.alibaba.easyretry.core.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Created by wuhao on 2020/11/13.
 */
public class LogUtils {

	public static final Logger CONSISTENCY_LOGGER = LoggerFactory.getLogger("aRetryConsistency");
}


================================================
FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/utils/PrintUtils.java
================================================
package com.alibaba.easyretry.core.utils;

import com.alibaba.easyretry.common.RetryContext;

import lombok.extern.slf4j.Slf4j;

/**
 * @author Created by wuhao on 2020/11/14.
 */
@Slf4j
public class PrintUtils {

	public static void monitorInfo(String action, RetryContext context) {
		monitorInfo(action, context, "");
	}

	public static void monitorInfo(String action, RetryContext context, String extraInfo) {
		log.info(action + " arg is {} task id is {} " + extraInfo, context.getInvocation(),
			context.getId());
	}
}


================================================
FILE: easy-retry-core/src/test/java/com/alibaba/easyretry/core/utils/TestClass.java
================================================
package com.alibaba.easyretry.core.utils;

class TestClass {

	public void say() {
		System.out.println("1");
	}

}


================================================
FILE: easy-retry-extensions/easy-retry-guava-extension/pom.xml
================================================
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xmlns="http://maven.apache.org/POM/4.0.0"
		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.alibaba</groupId>
		<artifactId>easy-retry-extensions</artifactId>
		<version>${revision}</version>
		<relativePath>../pom.xml</relativePath>
	</parent>

	<artifactId>easy-retry-guava-extension</artifactId>

	<name>easy-retry-guava-extension</name>
	<description>easy-retry-guava-extension</description>

	<dependencies>
		<dependency>
			<groupId>${project.groupId}</groupId>
			<artifactId>easy-retry-common</artifactId>
		</dependency>

		<dependency>
			<groupId>${project.groupId}</groupId>
			<artifactId>easy-retry-core</artifactId>
		</dependency>
		<dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
		</dependency>

		<dependency>
			<groupId>com.github.rholder</groupId>
			<artifactId>guava-retrying</artifactId>
			<version>2.0.0</version>
		</dependency>
	</dependencies>
</project>


================================================
FILE: easy-retry-extensions/easy-retry-guava-extension/src/main/java/com/alibaba/easyretry/extension/guava/GuavaRetrySyncExecutor.java
================================================
package com.alibaba.easyretry.extension.guava;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

import com.alibaba.easyretry.common.AbstractResultPredicate;
import com.alibaba.easyretry.common.AbstractRetrySyncExecutor;
import com.alibaba.easyretry.common.SCallable;
import com.alibaba.easyretry.common.retryer.RetryerInfo;
import com.github.rholder.retry.Retryer;
import com.github.rholder.retry.RetryerBuilder;
import com.github.rholder.retry.StopStrategies;
import com.github.rholder.retry.WaitStrategies;

public class GuavaRetrySyncExecutor<V> extends AbstractRetrySyncExecutor<V> {

	private static final long WAIT_TIME = 1000L;

	@Override
	public V call(SCallable<V> callable) throws Throwable {

		RetryerInfo<V> retryerInfo = getRetryerInfo();
		Class<? extends Throwable> onException = Throwable.class;
		if (Objects.nonNull(retryerInfo.getOnException())) {
			onException = retryerInfo.getOnException();
		}

		RetryerBuilder<V> retryerBuilder = RetryerBuilder.<V>newBuilder()
			.retryIfExceptionOfType(onException)
			.withStopStrategy(StopStrategies.stopAfterAttempt(retryerInfo.getRetryConfiguration().getMaxRetryTimes()))
			.withWaitStrategy(WaitStrategies.fixedWait(WAIT_TIME, TimeUnit.MILLISECONDS));

		AbstractResultPredicate<V> resultPredicate = retryerInfo.getResultPredicate();
		if (Objects.nonNull(resultPredicate)) {
			retryerBuilder.retryIfResult(resultPredicate::apply);
		}

		Retryer<V> retryer = retryerBuilder.build();
		return retryer.call(() -> {
			try {
				return callable.call();
			} catch (Throwable t) {
				throw new Exception(t);
			}
		});
	}
}


================================================
FILE: easy-retry-extensions/easy-retry-guava-extension/src/main/java/com/alibaba/easyretry/extension/guava/package-info.java
================================================
package com.alibaba.easyretry.extension.guava;


================================================
FILE: easy-retry-extensions/easy-retry-mybatis-extension/pom.xml
================================================
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xmlns="http://maven.apache.org/POM/4.0.0"
		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.alibaba</groupId>
		<artifactId>easy-retry-extensions</artifactId>
		<version>${revision}</version>
		<relativePath>../pom.xml</relativePath>
	</parent>

	<artifactId>easy-retry-mybatis-extension</artifactId>
	<name>easy-retry-mybatis-extension</name>
	<description>easy-retry-mybatis-extension</description>
	<properties>
		<mybatis.version>3.5.6</mybatis.version>
		<h2.version>1.4.200</h2.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>easy-retry-common</artifactId>
		</dependency>

		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>${mybatis.version}</version>
		</dependency>

		<dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
		</dependency>

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
		</dependency>

		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<version>${h2.version}</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>com.zaxxer</groupId>
			<artifactId>HikariCP</artifactId>
			<version>4.0.3</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>1.2.3</version>
			<scope>test</scope>
		</dependency>

    </dependencies>
</project>

================================================
FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/access/MybatisRetryTaskAccess.java
================================================
package com.alibaba.easyretry.extension.mybatis.access;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import com.alibaba.easyretry.common.access.RetryTaskAccess;
import com.alibaba.easyretry.common.constant.enums.RetryTaskStatusEnum;
import com.alibaba.easyretry.common.entity.RetryTask;
import com.alibaba.easyretry.extension.mybatis.common.utils.HostUtils;
import com.alibaba.easyretry.extension.mybatis.dao.RetryTaskDAO;
import com.alibaba.easyretry.extension.mybatis.po.RetryTaskPO;
import com.alibaba.easyretry.extension.mybatis.query.RetryTaskQuery;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;

/**
 * @author Created by wuhao on 2020/11/8.
 */
@AllArgsConstructor
public class MybatisRetryTaskAccess implements RetryTaskAccess {

	private final RetryTaskDAO retryTaskDAO;

	@Override
	public boolean saveRetryTask(RetryTask retryTask) {
		RetryTaskPO retryTaskPO = covert(retryTask);
		return retryTaskDAO.saveRetryTask(retryTaskPO);
	}

	@Override
	public boolean handlingRetryTask(RetryTask retryTask) {
		return updateRetryTaskStatus(retryTask, RetryTaskStatusEnum.HANDLING);
	}

	@Override
	public boolean finishRetryTask(RetryTask retryTask) {
		RetryTaskPO retryTaskPO = new RetryTaskPO().setId(retryTask.getId());
		return retryTaskDAO.deleteRetryTask(retryTaskPO);
//		return updateRetryTaskStatus(retryTask, RetryTaskStatusEnum.FINISH);
	}

	@Override
	public boolean stopRetryTask(RetryTask retryTask) {
		return updateRetryTaskStatus(retryTask, RetryTaskStatusEnum.ERROR);
	}

	private boolean updateRetryTaskStatus(RetryTask retryTask, RetryTaskStatusEnum status) {
		RetryTaskPO retryTaskPO = new RetryTaskPO();
		retryTaskPO.setId(retryTask.getId());
		retryTaskPO.setRetryStatus(status.getCode());
		return retryTaskDAO.updateRetryTask(retryTaskPO);
	}

	@Override
	public List<RetryTask> listAvailableTasks(Long lastId) {
		RetryTaskQuery retryTaskQuery = new RetryTaskQuery();
		retryTaskQuery.setRetryStatus(
			Lists.newArrayList(
				RetryTaskStatusEnum.INIT.getCode(), RetryTaskStatusEnum.HANDLING.getCode()));
		retryTaskQuery.setLastId(lastId);
		retryTaskQuery.setSharding(HostUtils.getHostIP());
		List<RetryTaskPO> retryTasks = retryTaskDAO.listRetryTask(retryTaskQuery);
		return convert(retryTasks);
	}

	private List<RetryTask> convert(List<RetryTaskPO> retryTasks) {
		return retryTasks.stream().map(this::convert).collect(Collectors.toList());
	}

	private RetryTask convert(RetryTaskPO retryTaskPO) {
		RetryTask retryTask = new RetryTask();
		retryTask.setId(retryTaskPO.getId());
		retryTask.setStatus(RetryTaskStatusEnum.fromCode(retryTaskPO.getRetryStatus()));
		retryTask.setArgsStr(retryTaskPO.getArgsStr());
		retryTask.setGmtCreate(retryTaskPO.getGmtCreate());
		retryTask.setGmtModified(retryTaskPO.getGmtModified());
		retryTask.setExecutorName(retryTaskPO.getExecutorName());
		retryTask.setExecutorMethodName(retryTaskPO.getExecutorMethodName());
		retryTask.setBizId(retryTaskPO.getBizId());
		retryTask.setExtAttrs(JSON.parseObject(retryTaskPO.getExtAttrs(),
			new TypeReference<Map<String, String>>() {}));
		return retryTask;
	}

	private RetryTaskPO covert(RetryTask retryTask) {
		RetryTaskPO retryTaskPO = new RetryTaskPO();
		retryTaskPO.setId(retryTask.getId());
		retryTaskPO.setSharding(HostUtils.getHostIP());
		retryTaskPO.setBizId(retryTask.getBizId());
		retryTaskPO.setExecutorName(retryTask.getExecutorName());
		retryTaskPO.setExecutorMethodName(retryTask.getExecutorMethodName());

		Map<String, String> extAttrs = retryTask.getExtAttrs();
		if (Objects.isNull(extAttrs)) {
			extAttrs = Maps.newHashMap();
		}
		extAttrs.put("onFailureMethod", retryTask.getOnFailureMethod());
		retryTaskPO.setExtAttrs(JSON.toJSONString(extAttrs));
		retryTaskPO.setRetryStatus(retryTask.getStatus().getCode());
		retryTaskPO.setArgsStr(retryTask.getArgsStr());
		retryTaskPO.setGmtCreate(retryTask.getGmtCreate());
		retryTaskPO.setGmtModified(retryTask.getGmtModified());
		return retryTaskPO;
	}

}


================================================
FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/common/utils/HostUtils.java
================================================
package com.alibaba.easyretry.extension.mybatis.common.utils;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Objects;

public class HostUtils {

	private static final String IP;

	static {
		InetAddress address = null;
		try {
			address = InetAddress.getLocalHost();
		} catch (UnknownHostException e) {
			// do noting
		}
		if (Objects.isNull(address)) {
			IP = "UNKNOW-IP";
		} else {
			IP = address.getHostAddress();
		}
	}

	public static String getHostIP() {
		return IP;
	}
}


================================================
FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/dao/BaseDAOSupport.java
================================================
package com.alibaba.easyretry.extension.mybatis.dao;

import java.util.Objects;
import java.util.function.Function;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

/**
 * @author wuhao
 */
public abstract class BaseDAOSupport {

	private final SqlSessionFactory sqlSessionFactory;

	public BaseDAOSupport(SqlSessionFactory sqlSessionFactory) {
		this.sqlSessionFactory = sqlSessionFactory;
	}

	protected <T> T execute(Function<SqlSession, T> function) {
		Objects.requireNonNull(sqlSessionFactory, "require sqlSessionFactory non null");
		try (final SqlSession session = sqlSessionFactory.openSession(false)) {
			return function.apply(session);
		}
	}

	protected <T> T execute(Function<SqlSession, T> function, boolean autoCommit) {
		Objects.requireNonNull(sqlSessionFactory, "require sqlSessionFactory non null");
		try (final SqlSession session = sqlSessionFactory.openSession(autoCommit)) {
			return function.apply(session);
		}
	}
}


================================================
FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/dao/RetryTaskDAO.java
================================================
package com.alibaba.easyretry.extension.mybatis.dao;

import java.util.List;

import com.alibaba.easyretry.extension.mybatis.po.RetryTaskPO;
import com.alibaba.easyretry.extension.mybatis.query.RetryTaskQuery;

/**
 * @author Created by wuhao on 2020/11/8.
 */
public interface RetryTaskDAO {

	boolean saveRetryTask(RetryTaskPO retryTaskPO);

	List<RetryTaskPO> listRetryTask(RetryTaskQuery retryTaskQuery);

	boolean updateRetryTask(RetryTaskPO retryTaskPO);

	boolean deleteRetryTask(RetryTaskPO retryTaskPO);
}


================================================
FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/dao/RetryTaskDAOImpl.java
================================================
package com.alibaba.easyretry.extension.mybatis.dao;

import java.util.List;

import com.alibaba.easyretry.extension.mybatis.po.RetryTaskPO;
import com.alibaba.easyretry.extension.mybatis.query.RetryTaskQuery;

import java.util.List;

import org.apache.ibatis.session.SqlSessionFactory;

/**
 * @author Created by wuhao on 2020/11/8.
 */
public class RetryTaskDAOImpl extends BaseDAOSupport implements RetryTaskDAO {

	public RetryTaskDAOImpl(SqlSessionFactory sqlSessionFactory) {
		super(sqlSessionFactory);
	}

	@Override
	public boolean saveRetryTask(RetryTaskPO retryTaskPO) {
		return execute(
			sqlSession ->
				sqlSession.insert("com.alibaba.easyretry.extension.mybatis.dao.RetryTaskDAO.saveRetryTask", retryTaskPO) > 0
			, true);
	}

	@Override
	public List<RetryTaskPO> listRetryTask(RetryTaskQuery retryTaskQuery) {
		return execute(sqlSession ->
			sqlSession.selectList(
				"com.alibaba.easyretry.extension.mybatis.dao.RetryTaskDAO.listRetryTask",
				retryTaskQuery)
		);
	}

	@Override
	public boolean updateRetryTask(RetryTaskPO retryTaskPO) {
		return execute(sqlSession ->
				sqlSession.update(
					"com.alibaba.easyretry.extension.mybatis.dao.RetryTaskDAO.updateRetryTask",
					retryTaskPO)
					> 0
			, true);
	}

	@Override
	public boolean deleteRetryTask(RetryTaskPO retryTaskPO) {
		return execute(sqlSession ->
				sqlSession.delete(
					"com.alibaba.easyretry.extension.mybatis.dao.RetryTaskDAO.deleteRetryTask",
					retryTaskPO)
					> 0
			, true);
	}
}


================================================
FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/po/RetryTaskPO.java
================================================
package com.alibaba.easyretry.extension.mybatis.po;

import java.util.Date;

import com.alibaba.easyretry.common.constant.enums.RetryTaskStatusEnum;

import lombok.Data;
import lombok.experimental.Accessors;

/**
 * @author Created by wuhao on 2020/11/8.
 */
@Data
@Accessors(chain = true)
public class RetryTaskPO {

	/**
	 * 主键id
	 */
	private Long id;

	/**
	 * 分片id
	 */
	private String sharding;

	/**
	 * 业务信息
	 */
	private String bizId;

	/**
	 * 执行者名称
	 */
	private String executorName;

	/**
	 * 执行者方法
	 */
	private String executorMethodName;

	/**
	 * @see RetryTaskStatusEnum
	 */
	private Integer retryStatus;

	private String argsStr;

	private Date gmtCreate;

	private Date gmtModified;

	private String extAttrs;
}


================================================
FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/query/RetryTaskQuery.java
================================================
package com.alibaba.easyretry.extension.mybatis.query;

import java.util.List;

import lombok.Data;
import lombok.experimental.Accessors;

/**
 * @author Created by wuhao on 2020/11/8.
 */
@Data
@Accessors(chain = true)
public class RetryTaskQuery {

	private Long lastId;

	private List<Integer> retryStatus;

	private String sharding;
}


================================================
FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/main/resources/dal/easyretry/easy-mybatis-config.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
	PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

	<settings>
		<setting name="cacheEnabled" value="true"/>
		<setting name="defaultStatementTimeout" value="3000"/>
		<setting name="mapUnderscoreToCamelCase" value="true"/>
		<setting name="useGeneratedKeys" value="true"/>
	</settings>

	<typeAliases>
	</typeAliases>

	<typeHandlers>
	</typeHandlers>

	<mappers>
		<mapper resource="dal/easyretry/mapper/easy-retry-task-mapper.xml"/>
	</mappers>


</configuration>


================================================
FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/main/resources/dal/easyretry/mapper/easy-retry-task-mapper.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.alibaba.easyretry.extension.mybatis.dao.RetryTaskDAO">

	<resultMap id="RetryTaskMAP" type="com.alibaba.easyretry.extension.mybatis.po.RetryTaskPO">
		<result column="id" property="id"/>
		<result column="sharding" property="sharding"/>
		<result column="biz_id" property="bizId"/>
		<result column="executor_name" property="executorName"/>
		<result column="executor_method_name" property="executorMethodName"/>
		<result column="retry_status" property="retryStatus"/>
		<result column="args_str" property="argsStr"/>
		<result column="gmt_create" property="gmtCreate"/>
		<result column="gmt_modified" property="gmtModified"/>
		<result column="ext_attrs" property="extAttrs"/>
	</resultMap>

	<sql id="all_column">
		`id`
		,
		`sharding`,
		`biz_id`,
		`executor_name`,
		`executor_method_name`,
		`retry_status`,
		`args_str`,
		`gmt_create`,
		`gmt_modified`,
		`ext_attrs`
	</sql>

	<insert id="saveRetryTask">
		INSERT INTO easy_retry_task (`id`,
									 `sharding`,
									 `biz_id`,
									 `executor_name`,
									 `executor_method_name`,
									 `retry_status`,
									 `args_str`,
									 `gmt_create`,
									 `gmt_modified`,
									 `ext_attrs`)
		VALUES (#{id},
				#{sharding},
				#{bizId},
				#{executorName},
				#{executorMethodName},
				#{retryStatus},
				#{argsStr},
				#{gmtCreate},
				#{gmtModified},
				#{extAttrs})
	</insert>

	<select id="listRetryTask"
			parameterType="com.alibaba.easyretry.extension.mybatis.query.RetryTaskQuery"
			resultMap="RetryTaskMAP">
		SELECT * FROM easy_retry_task
		<where>
			<if test="sharding != null">
				sharding = #{sharding}
			</if>

			<if test="retryStatus != null">
				AND retry_status IN
				<foreach close=")" collection="retryStatus" item="item" open="(" separator=",">
					#{item}
				</foreach>
			</if>

			<if test="lastId != null">
				AND id > #{lastId}
			</if>
		</where>
		order by id Asc limit 500
	</select>

	<update id="updateRetryTask"
			parameterType="com.alibaba.easyretry.extension.mybatis.po.RetryTaskPO">
		UPDATE easy_retry_task
		SET
		gmt_modified = now()
		<if test="retryStatus != null">
			,retry_status = #{retryStatus}
		</if>
		WHERE
		id=#{id}
	</update>

	<delete id="deleteRetryTask"
			parameterType="com.alibaba.easyretry.extension.mybatis.po.RetryTaskPO">
		DELETE
		FROM easy_retry_task
		WHERE id = #{id}
	</delete>

</mapper>

================================================
FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/test/java/com/alibaba/easyretry/extension/mybatis/DbConfig.java
================================================
package com.alibaba.easyretry.extension.mybatis;

import javax.sql.DataSource;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.Getter;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public final class DbConfig {

	@Getter
	private static final DataSource dataSource;

	static {
		String url = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;INIT=runscript from 'classpath:/task.sql'";
		HikariConfig config = new HikariConfig();
		config.setJdbcUrl(url);
		config.setUsername("sa");
		config.setDriverClassName("org.h2.Driver");
		config.setPassword("sa");
		config.addDataSourceProperty("cachePrepStmts", "true");
		config.addDataSourceProperty("prepStmtCacheSize", "250");
		config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
		dataSource = new HikariDataSource(config);
	}

	@Test
	void test() {
		Assertions.assertNotNull(DbConfig.getDataSource());
	}
}


================================================
FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/test/java/com/alibaba/easyretry/extension/mybatis/MyBatisConfig.java
================================================
package com.alibaba.easyretry.extension.mybatis;

import java.io.IOException;

import lombok.Getter;
import org.apache.ibatis.builder.xml.XMLConfigBuilder;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.logging.slf4j.Slf4jImpl;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public final class MyBatisConfig {

	@Getter
	private static final SqlSessionFactory factory;

	static {
		String resource = "dal/easyretry/easy-mybatis-config.xml";
		Configuration parse;
		try {
			XMLConfigBuilder parser = new XMLConfigBuilder(Resources.getResourceAsStream(resource),
				null, null);
			parse = parser.parse();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		final Environment development = new Environment("development",
			new JdbcTransactionFactory(), DbConfig.getDataSource());
		parse.setEnvironment(development);
		parse.setLogImpl(Slf4jImpl.class);
		factory = new SqlSessionFactoryBuilder().build(parse);
	}

	@Test
	void testNotNull() {
		Assertions.assertNotNull(MyBatisConfig.getFactory());
	}
}


================================================
FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/test/java/com/alibaba/easyretry/extension/mybatis/access/MybatisRetryTaskAccessTest.java
================================================
package com.alibaba.easyretry.extension.mybatis.access;

import java.util.Date;
import java.util.List;
import java.util.Objects;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;

import com.alibaba.easyretry.common.constant.enums.RetryTaskStatusEnum;
import com.alibaba.easyretry.common.entity.RetryTask;
import com.alibaba.easyretry.extension.mybatis.MyBatisConfig;
import com.alibaba.easyretry.extension.mybatis.dao.RetryTaskDAOImpl;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class MybatisRetryTaskAccessTest {

	private static final MybatisRetryTaskAccess ACCESS = new MybatisRetryTaskAccess(
		new RetryTaskDAOImpl(
			MyBatisConfig.getFactory()));

	private static RetryTask task;

	@BeforeAll
	static void prepare() {
		RetryTask retryTask = new RetryTask();
		retryTask.setId(2L);
		retryTask.setGmtCreate(new Date());
		retryTask.setGmtModified(new Date());
		retryTask.setBizId("2");
		retryTask.setStatus(RetryTaskStatusEnum.INIT);
		task = retryTask;
	}

	@Test
	@Order(1)
	void saveTask() {
		Assertions.assertTrue(ACCESS.saveRetryTask(task));
	}

	@Test
	@Order(2)
	void handle() {
//		ACCESS.saveRetryTask(task);
		Assertions.assertTrue(ACCESS.handlingRetryTask(task));
		List<RetryTask> retryTasks = ACCESS.listAvailableTasks(1L);
		Assertions.assertTrue(Objects.nonNull(retryTasks) && !retryTasks.isEmpty());
		Assertions.assertEquals(retryTasks.get(0).getStatus(), RetryTaskStatusEnum.HANDLING);
	}

	@Test
	@Order(3)
	void stop() {
//		ACCESS.saveRetryTask(task);
		boolean b = ACCESS.stopRetryTask(task);
		Assertions.assertTrue(b);
		List<RetryTask> retryTasks = ACCESS.listAvailableTasks(1L);
		Assertions.assertTrue(Objects.isNull(retryTasks) || retryTasks.isEmpty());
	}

	@Test
	@Order(4)
	void finish(){
//		ACCESS.saveRetryTask(task);
		Assertions.assertTrue(ACCESS.finishRetryTask(task));
		List<RetryTask> retryTasks = ACCESS.listAvailableTasks(1L);
		Assertions.assertTrue(Objects.isNull(retryTasks) || retryTasks.isEmpty());
	}
}


================================================
FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/test/java/com/alibaba/easyretry/extension/mybatis/common/utils/HostUtilsTest.java
================================================
package com.alibaba.easyretry.extension.mybatis.common.utils;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertNotNull;

class HostUtilsTest {

	@Test
	void getHostIP() {
		String hostIP = HostUtils.getHostIP();
		assertNotNull(hostIP);
	}
}


================================================
FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/test/java/com/alibaba/easyretry/extension/mybatis/dao/RetryTaskDAOImplTest.java
================================================
package com.alibaba.easyretry.extension.mybatis.dao;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;

import com.alibaba.easyretry.common.constant.enums.RetryTaskStatusEnum;
import com.alibaba.easyretry.extension.mybatis.MyBatisConfig;
import com.alibaba.easyretry.extension.mybatis.po.RetryTaskPO;
import com.alibaba.easyretry.extension.mybatis.query.RetryTaskQuery;

class RetryTaskDAOImplTest {

	private static RetryTaskDAO retryTaskDAO;

	@BeforeAll
	static void prepare() {
		retryTaskDAO = new RetryTaskDAOImpl(MyBatisConfig.getFactory());
	}

	@Test
	@Order(1)
	void saveTask() {
		final RetryTaskPO retryTaskPO = new RetryTaskPO()
			.setId(1L)
			.setGmtCreate(new Date())
			.setBizId("1")
			.setRetryStatus(RetryTaskStatusEnum.HANDLING.getCode())
			.setGmtModified(new Date());

		final boolean result = retryTaskDAO.saveRetryTask(retryTaskPO);
		Assertions.assertTrue(result);
	}

	@Test
	@Order(2)
	void listRetryTask() {
		final RetryTaskPO retryTaskPO = new RetryTaskPO()
			.setId(2L)
			.setGmtCreate(new Date())
			.setBizId("2")
			.setRetryStatus(RetryTaskStatusEnum.HANDLING.getCode())
			.setGmtModified(new Date());

		retryTaskDAO.saveRetryTask(retryTaskPO);
		final RetryTaskQuery retryTaskQuery = new RetryTaskQuery()
			.setRetryStatus(Collections.singletonList(RetryTaskStatusEnum.HANDLING.getCode()));
		List<RetryTaskPO> retryTaskPOS = retryTaskDAO.listRetryTask(retryTaskQuery);
		System.out.println(retryTaskPOS);
		Assertions.assertTrue(!retryTaskPOS.isEmpty());
		Assertions.assertTrue(Objects.nonNull(retryTaskPOS));
		// Assertions.assertTrue(Objects.nonNull(retryTaskPOS) && !retryTaskPOS.isEmpty());
	}

	@Test
	@Order(3)
	void updateRetryTask() {
		//final RetryTaskPO retryTaskPO = new RetryTaskPO()
		//	.setId(1L)
		//	.setBizId("1")
		//	.setRetryStatus(RetryTaskStatusEnum.FINISH.getCode())
		//	.setGmtModified(new Date());
		//
		//boolean b = retryTaskDAO.updateRetryTask(retryTaskPO);
		//Assertions.assertTrue(b);
		//
		//final RetryTaskQuery retryTaskQuery = new RetryTaskQuery()
		//	.setRetryStatus(Collections.singletonList(RetryTaskStatusEnum.FINISH.getCode()));
		//List<RetryTaskPO> retryTaskPOS = retryTaskDAO.listRetryTask(retryTaskQuery);
		//System.out.println(retryTaskPOS);
		//Assertions.assertTrue(Objects.nonNull(retryTaskPOS) && !retryTaskPOS.isEmpty());
	}

	@Test
	@Order(4)
	void deleteRetryTask() {
		final RetryTaskPO retryTaskPO = new RetryTaskPO()
			.setId(3L)
			.setGmtCreate(new Date())
			.setBizId("3")
			.setRetryStatus(RetryTaskStatusEnum.HANDLING.getCode())
			.setGmtModified(new Date());

		retryTaskDAO.saveRetryTask(retryTaskPO);
		boolean b = retryTaskDAO.deleteRetryTask(retryTaskPO);
		Assertions.assertTrue(b);

		final RetryTaskQuery retryTaskQuery = new RetryTaskQuery()
			.setRetryStatus(Collections.singletonList(RetryTaskStatusEnum.FINISH.getCode()));
		List<RetryTaskPO> retryTaskPOS = retryTaskDAO.listRetryTask(retryTaskQuery);
		System.out.println(retryTaskPOS);
		Assertions.assertTrue(Objects.isNull(retryTaskPOS) || retryTaskPOS.isEmpty());
	}

}


================================================
FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/test/resources/logback.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<configuration>

	<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
		</encoder>
	</appender>

	<root level="DEBUG">
		<appender-ref ref="CONSOLE" />
	</root>
</configuration>


================================================
FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/test/resources/task.sql
================================================
CREATE TABLE IF NOT EXISTS easy_retry_task (
    id bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键' PRIMARY KEY,
    gmt_create datetime NOT NULL COMMENT '创建时间',
    gmt_modified datetime NOT NULL COMMENT '修改时间',
    sharding varchar(64) NULL COMMENT '数据库分片字段',
    biz_id varchar(64) NULL COMMENT '业务id',
    executor_name varchar(512) NULL COMMENT '执行名称',
    executor_method_name varchar(512) NULL COMMENT '执行方法名称',
    retry_status tinyint NOT NULL COMMENT '重试状态',
    args_str varchar(3000) NULL COMMENT '执行方法参数',
    ext_attrs varchar(3000) NULL COMMENT '扩展字段'
);


================================================
FILE: easy-retry-extensions/easy-retry-spring-extension/pom.xml
================================================
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xmlns="http://maven.apache.org/POM/4.0.0"
		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.alibaba</groupId>
		<artifactId>easy-retry-extensions</artifactId>
		<version>${revision}</version>
		<relativePath>../pom.xml</relativePath>
	</parent>

	<artifactId>easy-retry-spring-extension</artifactId>

	<name>easy-retry-spring-extension</name>
	<description>easy-retry-spring-extension</description>

	<dependencies>
		<dependency>
			<groupId>${project.groupId}</groupId>
			<artifactId>easy-retry-common</artifactId>
		</dependency>

		<dependency>
			<groupId>${project.groupId}</groupId>
			<artifactId>easy-retry-core</artifactId>
		</dependency>
		<dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>5.1.12.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>5.1.12.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.9.5</version>
		</dependency>
	</dependencies>
</project>


================================================
FILE: easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/RetryListenerInitialize.java
================================================
package com.alibaba.easyretry.extension.spring;

import java.util.Map;

import com.alibaba.easyretry.common.event.RetryEventMulticaster;
import com.alibaba.easyretry.common.event.RetryListener;

import lombok.Setter;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * @author Created by wuhao on 2021/4/9.
 */
public class RetryListenerInitialize implements SmartInitializingSingleton, ApplicationContextAware {

	@Setter
	private RetryEventMulticaster retryEventMulticaster;

	private ApplicationContext applicationContext;

	@Override
	public void afterSingletonsInstantiated() {
		Map<String, RetryListener> retryListenerMap = applicationContext.getBeansOfType(RetryListener.class);
		MapUtils.emptyIfNull(retryListenerMap).values().forEach(
			(retryListener) -> retryEventMulticaster.register(retryListener));
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}

}


================================================
FILE: easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/SPELParamPredicate.java
================================================
package com.alibaba.easyretry.extension.spring;

import java.lang.reflect.Method;

import com.alibaba.easyretry.common.EasyRetryPredicate;

import lombok.Data;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

/**
 * @author Created by wuhao on 2021/3/18.
 */
@Data
public class SPELParamPredicate implements EasyRetryPredicate<Object[], String> {

	private static DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();

	private String bizIdCondition;

	private Method method;

	public SPELParamPredicate(String bizIdCondition, Method method) {
		this.bizIdCondition = bizIdCondition;
		this.method = method;
	}

	public SPELParamPredicate() {
	}

	@Override
	public String apply(Object[] params) {
		ExpressionParser parser = new SpelExpressionParser();
		StandardEvaluationContext context = new StandardEvaluationContext();
		String[] paramNameArr = discoverer.getParameterNames(method);
		if (ArrayUtils.isEmpty(paramNameArr)) {
			return null;
		}
		for (int i = 0; i < paramNameArr.length; i++) {
			context.setVariable(paramNameArr[i], params[i]);
		}
		return parser.parseExpression(bizIdCondition).getValue(context, String.class);
	}
}


================================================
FILE: easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/SPELResultPredicate.java
================================================
package com.alibaba.easyretry.extension.spring;

import com.alibaba.easyretry.common.AbstractResultPredicate;

import lombok.Data;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

/**
 * @author Created by wuhao on 2021/3/18.
 */
@Data
public class SPELResultPredicate<T> extends AbstractResultPredicate<T> {

	private String resultCondition;

	public SPELResultPredicate(String resultCondition) {
		this.resultCondition = resultCondition;
	}

	public SPELResultPredicate() {
	}

	@Override
	public Boolean apply(T result) {
		ExpressionParser parser = new SpelExpressionParser();
		StandardEvaluationContext context = new StandardEvaluationContext();
		context.setVariable("result", result);
		return parser.parseExpression(resultCondition).getValue(context, Boolean.class);
	}
}


================================================
FILE: easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/SpringEventApplicationListener.java
================================================
package com.alibaba.easyretry.extension.spring;

import org.springframework.beans.factory.SmartInitializingSingleton;

import com.alibaba.easyretry.common.filter.RetryFilterInvocationHandler;
import com.alibaba.easyretry.common.filter.RetryFilterRegisterHandler;

import lombok.Setter;

/**
 * @author Created by wuhao on 2021/4/9.
 */
public class SpringEventApplicationListener implements SmartInitializingSingleton {

	@Setter
	private RetryFilterInvocationHandler retryFilterInvocationHandler;

	@Setter
	private RetryFilterRegisterHandler retryFilterRegisterHandler;


	@Override
	public void afterSingletonsInstantiated() {
		retryFilterRegisterHandler.handle();
		retryFilterInvocationHandler.handle();
	}
}


================================================
FILE: easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/SpringRetryFilterDiscover.java
================================================
package com.alibaba.easyretry.extension.spring;

import java.util.List;
import java.util.Map;

import com.alibaba.easyretry.common.filter.RetryFilter;
import com.alibaba.easyretry.common.filter.RetryFilterDiscover;

import com.google.common.collect.Lists;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * @author Created by wuhao on 2021/4/9.
 */
public class SpringRetryFilterDiscover implements RetryFilterDiscover, SmartInitializingSingleton,
	ApplicationContextAware {

	private List<RetryFilter> retryFilters;

	private ApplicationContext applicationContext;

	@Override
	public List<RetryFilter> discoverAll() {
		return retryFilters;
	}

	@Override
	public void afterSingletonsInstantiated() {
		Map<String, RetryFilter> retryFilterMap = applicationContext.getBeansOfType(RetryFilter.class);
		retryFilters = Lists.newArrayList(retryFilterMap.values());
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}
}


================================================
FILE: easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/aop/EasyRetryable.java
================================================
package com.alibaba.easyretry.extension.spring.aop;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import com.alibaba.easyretry.common.constant.enums.RetryTypeEnum;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface EasyRetryable {

	/**
	 * 处理完成以后是否需要把异常重新抛出
	 *
	 * @return 是否需要抛出异
	 */
	boolean reThrowException() default false;

	/**
	 * 通过结果判断是否重试
	 */
	String resultCondition() default "";

	/**
	 * 重试种类
	 */
	RetryTypeEnum retryType() default RetryTypeEnum.ASYNC;

}


================================================
FILE: easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/aop/RetryInterceptor.java
================================================
package com.alibaba.easyretry.extension.spring.aop;

import java.lang.reflect.Method;
import java.util.Objects;

import com.alibaba.easyretry.common.RetryConfiguration;
import com.alibaba.easyretry.common.RetryIdentify;
import com.alibaba.easyretry.common.retryer.Retryer;
import com.alibaba.easyretry.core.RetryerBuilder;
import com.alibaba.easyretry.extension.spring.SPELResultPredicate;

import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.ApplicationContext;

@Aspect
public class RetryInterceptor {

	@Setter
	private RetryConfiguration retryConfiguration;

	@Setter
	private ApplicationContext applicationContext;

	@Around("@annotation(retryable)")
	public Object around(ProceedingJoinPoint invocation, EasyRetryable retryable) throws Throwable {
		if (RetryIdentify.isOnRetry()) {
			return invocation.proceed();
		}

		Retryer<Object> retryer = determineTargetRetryer(invocation, retryable);
		return retryer.call(invocation::proceed);
	}

	private String getBeanId(Class<?> type) {
		String[] names = applicationContext.getBeanNamesForType(type);
		return names.length > 0 ? names[0] : null;
	}

	private Retryer<Object> determineTargetRetryer(ProceedingJoinPoint invocation, EasyRetryable retryable) {
		MethodSignature signature = (MethodSignature)invocation.getSignature();
		RetryerBuilder<Object> retryerBuilder = new RetryerBuilder<Object>()
			.withExecutorName(getBeanId(signature.getDeclaringType()))
			.withExecutorMethodName(signature.getMethod().getName())
			.withArgs(invocation.getArgs())
			.withConfiguration(retryConfiguration)
			.withReThrowException(retryable.reThrowException());
		if (StringUtils.isNotBlank(retryable.resultCondition())) {
			retryerBuilder.withResultPredicate(new SPELResultPredicate<>(retryable.resultCondition()));
		}

		return retryerBuilder.build(retryable.retryType());
	}
}


================================================
FILE: easy-retry-extensions/pom.xml
================================================
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xmlns="http://maven.apache.org/POM/4.0.0"
		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.alibaba</groupId>
		<artifactId>easy-retry</artifactId>
		<version>${revision}</version>
		<relativePath>../pom.xml</relativePath>
	</parent>

	<artifactId>easy-retry-extensions</artifactId>
	<packaging>pom</packaging>

	<name>easy-retry-extensions</name>
	<description>easy-retry-extensions</description>

	<modules>
		<module>easy-retry-spring-extension</module>
		<module>easy-retry-mybatis-extension</module>
		<module>easy-retry-guava-extension</module>
	</modules>

	<dependencies>
	</dependencies>
</project>



================================================
FILE: easy-retry-starters/easy-retry-memory-starter/pom.xml
================================================
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xmlns="http://maven.apache.org/POM/4.0.0"
		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.alibaba</groupId>
		<artifactId>easy-retry-starters</artifactId>
		<version>${revision}</version>
		<relativePath>../pom.xml</relativePath>
	</parent>

	<artifactId>easy-retry-memory-starter</artifactId>
	<name>easy-retry-memory-starter</name>
	<description>easy-retry-memory-starter</description>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-autoconfigure</artifactId>
		</dependency>

		<dependency>
			<groupId>${project.groupId}</groupId>
			<artifactId>easy-retry-spring-extension</artifactId>
		</dependency>

		<dependency>
			<groupId>${project.groupId}</groupId>
			<artifactId>easy-retry-core</artifactId>
		</dependency>
		<dependency>
			<groupId>${project.groupId}</groupId>
			<artifactId>easy-retry-starter-common</artifactId>
		</dependency>
	</dependencies>
</project>

================================================
FILE: easy-retry-starters/easy-retry-memory-starter/src/main/java/com/alibaba/easyretry/memory/MemoryAutoConfiguration.java
================================================
package com.alibaba.easyretry.memory;

import com.alibaba.easyretry.common.RetryConfiguration;
import com.alibaba.easyretry.common.RetryContainer;
import com.alibaba.easyretry.common.RetryExecutor;
import com.alibaba.easyretry.core.access.MemoryRetryTaskAccess;
import com.alibaba.easyretry.core.container.SimpleRetryContainer;
import com.alibaba.easyretry.memory.config.EasyRetryMemoryCompatibleProperties;
import com.alibaba.easyretry.starter.common.CommonAutoConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author Created by wuhao on 2021/2/19.
 */
@Configuration
@Slf4j
@EnableConfigurationProperties(EasyRetryMemoryCompatibleProperties.class)
@ConditionalOnProperty(name = "spring.easyretry.memory.enabled", havingValue = "true")
public class MemoryAutoConfiguration extends CommonAutoConfiguration {

	@Autowired
	private EasyRetryMemoryCompatibleProperties easyRetryMemoryCompatibleProperties;

	@Bean
	@ConditionalOnMissingBean(MemoryRetryTaskAccess.class)
	public MemoryRetryTaskAccess retryTaskAccess() {
		return new MemoryRetryTaskAccess();
	}

	@Bean(initMethod = "start")
	public RetryContainer retryContainer(
		RetryConfiguration configuration, RetryExecutor defaultRetryExecutor) {
		log.warn("RetryConfiguration start");
		return new SimpleRetryContainer(
			configuration,
			defaultRetryExecutor);
	}

	@Override
	public Integer getMaxRetryTimes() {
		return easyRetryMemoryCompatibleProperties.getMaxRetryTimes();
	}
}


================================================
FILE: easy-retry-starters/easy-retry-memory-starter/src/main/java/com/alibaba/easyretry/memory/config/EasyRetryMemoryCompatibleProperties.java
================================================
package com.alibaba.easyretry.memory.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * @author Created by wuhao on 2021/2/21.
 */
@ConfigurationProperties(prefix = "spring.easyretry.memory")
@Data
public class EasyRetryMemoryCompatibleProperties {

	private Integer maxRetryTimes = 5;

	private String namespace = "easy-retry";
}


================================================
FILE: easy-retry-starters/easy-retry-memory-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json
================================================
{
	"properties": [
		{
			"name": "spring.easyretry.memory.enabled",
			"type": "java.lang.Boolean",
			"description": "enable AmoebaCompatible or not."
		},
		{
			"name": "spring.easyretry.memory.maxRetryTimes",
			"type": "java.lang.Integer",
			"description": "definition the maxRetryTimes"
		}
	]
}

================================================
FILE: easy-retry-starters/easy-retry-memory-starter/src/main/resources/META-INF/spring.factories
================================================
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.alibaba.easyretry.memory.MemoryAutoConfiguration

================================================
FILE: easy-retry-starters/easy-retry-mybatis-starter/pom.xml
================================================
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xmlns="http://maven.apache.org/POM/4.0.0"
		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.alibaba</groupId>
		<artifactId>easy-retry-starters</artifactId>
		<version>${revision}</version>
		<relativePath>../pom.xml</relativePath>
	</parent>

	<artifactId>easy-retry-mybatis-starter</artifactId>
	<name>easy-retry-mybatis-starter</name>
	<description>easy-retry-mybatis-starter</description>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-autoconfigure</artifactId>
		</dependency>

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>easy-retry-spring-extension</artifactId>
		</dependency>

		<dependency>
			<groupId>${project.groupId}</groupId>
			<artifactId>easy-retry-core</artifactId>
		</dependency>

		<dependency>
			<groupId>${project.groupId}</groupId>
			<artifactId>easy-retry-mybatis-extension</artifactId>
		</dependency>

		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>2.0.6</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>5.1.12.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>${project.groupId}</groupId>
			<artifactId>easy-retry-starter-common</artifactId>
		</dependency>

	</dependencies>

</project>

================================================
FILE: easy-retry-starters/easy-retry-mybatis-starter/src/main/java/com/alibaba/easyretry/mybatis/MybatisAutoConfiguration.java
================================================
package com.alibaba.easyretry.mybatis;

import com.alibaba.easyretry.common.RetryConfiguration;
import com.alibaba.easyretry.common.RetryContainer;
import com.alibaba.easyretry.common.RetryExecutor;
import com.alibaba.easyretry.common.access.RetryTaskAccess;
import com.alibaba.easyretry.core.container.SimpleRetryContainer;
import com.alibaba.easyretry.extension.mybatis.access.MybatisRetryTaskAccess;
import com.alibaba.easyretry.extension.mybatis.dao.RetryTaskDAO;
import com.alibaba.easyretry.extension.mybatis.dao.RetryTaskDAOImpl;
import com.alibaba.easyretry.mybatis.conifg.EasyRetryMybatisProperties;
import com.alibaba.easyretry.starter.common.CommonAutoConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;

import javax.sql.DataSource;

/**
 * @author Created by wuhao on 2021/2/19.
 */
@Configuration
@Slf4j
@EnableConfigurationProperties(EasyRetryMybatisProperties.class)
@ConditionalOnProperty(name = "spring.easyretry.mybatis.enabled", matchIfMissing = true)
public class MybatisAutoConfiguration extends CommonAutoConfiguration {

	@Autowired
	private EasyRetryMybatisProperties easyRetryMybatisProperties;

	@Value("classpath:/dal/easyretry/easy-mybatis-config.xml")
	private Resource easyRetryMybatisResouse;

	@Bean("easyRetrySqlSessionFactory")
	public SqlSessionFactory sqlSessionFactory(
		@Qualifier("easyRetryMybatisDataSource") DataSource easyRetryMybatisDataSource)
		throws Exception {
		SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
		sqlSessionFactoryBean.setDataSource(easyRetryMybatisDataSource);
		sqlSessionFactoryBean.setConfigLocation(easyRetryMybatisResouse);
		return sqlSessionFactoryBean.getObject();
	}

	@Bean(initMethod = "start")
	public RetryContainer retryContainer(
		RetryConfiguration configuration, RetryExecutor defaultRetryExecutor) {
		log.warn("RetryConfiguration start");
		return new SimpleRetryContainer(
			configuration, defaultRetryExecutor);
	}

	@Bean
	public RetryTaskDAO retryTaskDAO(
		@Qualifier("easyRetrySqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
		return new RetryTaskDAOImpl(sqlSessionFactory);
	}

	@Bean
	public RetryTaskAccess retryTaskAccess(RetryTaskDAO retryTaskDAO) {
		return new MybatisRetryTaskAccess(retryTaskDAO);
	}

	@Override
	public Integer getMaxRetryTimes() {
		return easyRetryMybatisProperties.getMaxRetryTimes();
	}
}


================================================
FILE: easy-retry-starters/easy-retry-mybatis-starter/src/main/java/com/alibaba/easyretry/mybatis/conifg/EasyRetryMybatisProperties.java
================================================
package com.alibaba.easyretry.mybatis.conifg;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * @author Created by wuhao on 2021/2/21.
 */
@ConfigurationProperties(prefix = "spring.easyretry.mybatis")
@Data
public class EasyRetryMybatisProperties {

	private Integer maxRetryTimes = 5;

}


================================================
FILE: easy-retry-starters/easy-retry-mybatis-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json
================================================
{
	"properties": [
		{
			"name": "spring.easyretry.mybatis.enabled",
			"type": "java.lang.Boolean",
			"description": "enable AmoebaCompatible or not."
		},
		{
			"name": "spring.easyretry.mybatis.maxRetryTimes",
			"type": "java.lang.Integer",
			"description": "definition the maxRetryTimes"
		}
	]
}

================================================
FILE: easy-retry-starters/easy-retry-mybatis-starter/src/main/resources/META-INF/spring.factories
================================================
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.alibaba.easyretry.mybatis.MybatisAutoConfiguration

================================================
FILE: easy-retry-starters/easy-retry-starter-common/pom.xml
================================================
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xmlns="http://maven.apache.org/POM/4.0.0"
		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.alibaba</groupId>
		<artifactId>easy-retry-starters</artifactId>
		<version>${revision}</version>
		<relativePath>../pom.xml</relativePath>
	</parent>

	<artifactId>easy-retry-starter-common</artifactId>
	<name>easy-retry-starter-common</name>
	<description>easy-retry-starter-common</description>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-autoconfigure</artifactId>
		</dependency>

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>easy-retry-spring-extension</artifactId>
		</dependency>

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>easy-retry-guava-extension</artifactId>
		</dependency>

		<dependency>
			<groupId>${project.groupId}</groupId>
			<artifactId>easy-retry-core</artifactId>
		</dependency>

	</dependencies>

</project>

================================================
FILE: easy-retry-starters/easy-retry-starter-common/src/main/java/com/alibaba/easyretry/starter/common/CommonAutoConfiguration.java
================================================
package com.alibaba.easyretry.starter.common;

import org.springframework.beans.BeansException;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;

import com.alibaba.easyretry.common.RetryConfiguration;
import com.alibaba.easyretry.common.RetryExecutor;
import com.alibaba.easyretry.common.access.RetrySerializerAccess;
import com.alibaba.easyretry.common.access.RetryStrategyAccess;
import com.alibaba.easyretry.common.access.RetryTaskAccess;
import com.alibaba.easyretry.common.event.RetryEventMulticaster;
import com.alibaba.easyretry.common.filter.RetryFilterDiscover;
import com.alibaba.easyretry.common.filter.RetryFilterInvocation;
import com.alibaba.easyretry.common.filter.RetryFilterInvocationHandler;
import com.alibaba.easyretry.common.filter.RetryFilterRegister;
import com.alibaba.easyretry.common.filter.RetryFilterRegisterHandler;
import com.alibaba.easyretry.common.resolve.ExecutorSolver;
import com.alibaba.easyretry.common.serializer.ResultPredicateSerializer;
import com.alibaba.easyretry.common.strategy.StopStrategy;
import com.alibaba.easyretry.common.strategy.WaitStrategy;
import com.alibaba.easyretry.core.PersistenceRetryExecutor;
import com.alibaba.easyretry.core.access.DefaultRetrySerializerAccess;
import com.alibaba.easyretry.core.event.SimpleRetryEventMulticaster;
import com.alibaba.easyretry.core.filter.DefaultRetryFilterInvocationHandler;
import com.alibaba.easyretry.core.filter.DefaultRetryFilterRegisterHandler;
import com.alibaba.easyretry.core.filter.SimpleRetryFilterRegister;
import com.alibaba.easyretry.core.serializer.HessianResultPredicateSerializer;
import com.alibaba.easyretry.core.strategy.DefaultRetryStrategy;
import com.alibaba.easyretry.extension.spring.RetryListenerInitialize;
import com.alibaba.easyretry.extension.spring.SpringEventApplicationListener;
import com.alibaba.easyretry.extension.spring.SpringRetryFilterDiscover;
import com.alibaba.easyretry.extension.spring.aop.RetryInterceptor;

import lombok.extern.slf4j.Slf4j;

/**
 * @author Created by wuhao on 2021/2/19.
 */
@Slf4j
public abstract class CommonAutoConfiguration implements ApplicationContextAware {

	protected ApplicationContext applicationContext;

	@Bean
	@ConditionalOnMissingBean(RetryConfiguration.class)
	public RetryConfiguration configuration(RetryTaskAccess retryTaskAccess,
											RetryEventMulticaster retryEventMulticaster) {
		DefaultRetryStrategy defaultRetryStrategy = new DefaultRetryStrategy();
		return new RetryConfiguration() {
			@Override
			public RetryTaskAccess getRetryTaskAccess() {
				return retryTaskAccess;
			}

			@Override
			public RetrySerializerAccess getRetrySerializerAccess() {
				return new DefaultRetrySerializerAccess();
			}

			@Override
			public RetryStrategyAccess getRetryStrategyAccess() {
				return new RetryStrategyAccess() {

					@Override
					public StopStrategy getCurrentGlobalStopStrategy() {
						return defaultRetryStrategy;
					}

					@Override
					public WaitStrategy getCurrentGlobalWaitStrategy() {
						return defaultRetryStrategy;
					}
				};
			}

			@Override
			public ExecutorSolver getExecutorSolver() {
				return executorName -> applicationContext.getBean(executorName);
			}

			@Override
			public ResultPredicateSerializer getResultPredicateSerializer() {
				return new HessianResultPredicateSerializer();
			}

			@Override
			public Integer getMaxRetryTimes() {
				return CommonAutoConfiguration.this.getMaxRetryTimes();
			}

			@Override
			public RetryEventMulticaster getRetryEventMulticaster() {
				return retryEventMulticaster;
			}
		};
	}

	@Bean
	@ConditionalOnMissingBean(RetryInterceptor.class)
	public RetryInterceptor retryInterceptor(RetryConfiguration configuration) {
		RetryInterceptor retryInterceptor = new RetryInterceptor();
		retryInterceptor.setApplicationContext(applicationContext);
		retryInterceptor.setRetryConfiguration(configuration);
		return retryInterceptor;
	}

	@Bean
	@ConditionalOnMissingBean(RetryExecutor.class)
	public RetryExecutor defaultRetryExecutor(RetryConfiguration configuration,
														 RetryFilterInvocation retryInvocationHandler) {
		PersistenceRetryExecutor persistenceRetryExecutor = new PersistenceRetryExecutor();
		persistenceRetryExecutor.setRetryConfiguration(configuration);
		persistenceRetryExecutor.setRetryFilterInvocation(retryInvocationHandler);
		return persistenceRetryExecutor;
	}

	@Bean
	@ConditionalOnMissingBean(RetryEventMulticaster.class)
	public RetryEventMulticaster retryEventMulticaster() {
		return new SimpleRetryEventMulticaster();
	}

	@Bean
	@ConditionalOnMissingBean(RetryListenerInitialize.class)
	public RetryListenerInitialize retryListenerInitialize(RetryEventMulticaster retryEventMulticaster) {
		RetryListenerInitialize retryListenerInitialize = new RetryListenerInitialize();
		retryListenerInitialize.setRetryEventMulticaster(retryEventMulticaster);
		return retryListenerInitialize;
	}

	@Bean
	@ConditionalOnMissingBean(SpringRetryFilterDiscover.class)
	public SpringRetryFilterDiscover springRetryFilterDiscover() {
		return new SpringRetryFilterDiscover();
	}

	@Bean
	@ConditionalOnMissingBean(RetryFilterRegister.class)
	public SimpleRetryFilterRegister simpleRetryFilterRegister() {
		return new SimpleRetryFilterRegister();
	}

	@Bean
	@ConditionalOnMissingBean(RetryFilterInvocationHandler.class)
	public DefaultRetryFilterInvocationHandler retryInvocationHandler(RetryFilterRegister simpleRetryFilterRegister) {
		DefaultRetryFilterInvocationHandler defaultRetryFilterInvocationHandler
			= new DefaultRetryFilterInvocationHandler();
		defaultRetryFilterInvocationHandler.setRetryFilterRegister(simpleRetryFilterRegister);
		return defaultRetryFilterInvocationHandler;
	}

	@Bean
	@ConditionalOnMissingBean(RetryFilterRegisterHandler.class)
	public RetryFilterRegisterHandler retryFilterRegisterHandler(RetryFilterDiscover springRetryFilterDiscover,
																 RetryFilterRegister simpleRetryFilterRegister) {
		DefaultRetryFilterRegisterHandler defaultRetryFilterRegisterHandler = new DefaultRetryFilterRegisterHandler();
		defaultRetryFilterRegisterHandler.setRetryFilterRegister(simpleRetryFilterRegister);
		defaultRetryFilterRegisterHandler.setRetryFilterDiscover(springRetryFilterDiscover);
		return defaultRetryFilterRegisterHandler;
	}

	@Bean
	public SpringEventApplicationListener easyRetryApplicationListener(RetryFilterInvocationHandler retryFilterInvocationHandler,
															RetryFilterRegisterHandler retryFilterRegisterHandler) {
		SpringEventApplicationListener springEventApplicationListener = new SpringEventApplicationListener();
		springEventApplicationListener.setRetryFilterRegisterHandler(retryFilterRegisterHandler);
		springEventApplicationListener.setRetryFilterInvocationHandler(retryFilterInvocationHandler);
		return springEventApplicationListener;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}

	public abstract Integer getMaxRetryTimes();

}


================================================
FILE: easy-retry-starters/pom.xml
================================================
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xmlns="http://maven.apache.org/POM/4.0.0"
		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.alibaba</groupId>
		<artifactId>easy-retry</artifactId>
		<version>${revision}</version>
		<relativePath>../pom.xml</relativePath>
	</parent>

	<artifactId>easy-retry-starters</artifactId>
	<packaging>pom</packaging>

	<name>easy-retry-starters</name>
	<description>easy-retry-starters</description>

	<modules>
		<module>easy-retry-memory-starter</module>
		<module>easy-retry-mybatis-starter</module>
		<module>easy-retry-starter-common</module>
	</modules>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-autoconfigure</artifactId>
				<version>2.4.0</version>
			</dependency>
		</dependencies>
	</dependencyManagement>

</project>

================================================
FILE: pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xmlns="http://maven.apache.org/POM/4.0.0"
		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

	<modelVersion>4.0.0</modelVersion>
	<groupId>com.alibaba</groupId>
	<artifactId>easy-retry</artifactId>
	<version>${revision}</version>
	<packaging>pom</packaging>
	<properties>
		<maven.compiler.target>1.8</maven.compiler.target>
		<maven.compiler.source>1.8</maven.compiler.source>
		<java.version>1.8</java.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<revision>1.0.3</revision>
		<slf4j.version>1.7.30</slf4j.version>
		<lombok.version>1.18.18</lombok.version>
		<guava.version>16.0</guava.version>
		<fastjson.version>1.2.73</fastjson.version>
		<maven-source-plugin.version>2.2.1</maven-source-plugin.version>
		<maven-javadoc-plugin.version>3.2.0</maven-javadoc-plugin.version>
		<maven-gpg-plugin.version>1.6</maven-gpg-plugin.version>
	</properties>
	<modules>
		<module>easy-retry-common</module>
		<module>easy-retry-core</module>
		<module>easy-retry-extensions</module>
		<module>easy-retry-starters</module>
	</modules>

	<name>easy-retry</name>
	<description>easy-retry</description>
	<url>https://github.com/alibaba/easy-retry</url>


	<scm>
		<url>https://github.com/alibaba/easy-retry</url>
		<connection>scm:git@github.com:alibaba/easy-retry.git</connection>
	</scm>

	<organization>
		<name>Alibaba Group</name>
		<url>https://github.com/alibaba</url>
	</organization>

	<developers>
		<developer>
			<name>wuhao</name>
			<email>wuhao7171@gmail.com</email>
		</developer>
	</developers>

	<licenses>
		<license>
			<name>MIT License</name>
			<url>http://www.opensource.org/licenses/mit-license.php</url>
		</license>
	</licenses>

	<dependencies>
		<dependency>
			<groupId>org.junit.jupiter</groupId>
			<artifactId>junit-jupiter</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.junit</groupId>
				<artifactId>junit-bom</artifactId>
				<version>5.7.1</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>

			<dependency>
				<groupId>org.slf4j</groupId>
				<artifactId>slf4j-api</artifactId>
				<version>${slf4j.version}</version>
			</dependency>
			<dependency>
				<groupId>org.projectlombok</groupId>
				<artifactId>lombok</artifactId>
				<version>${lombok.version}</version>
				<optional>true</optional>
			</dependency>

			<dependency>
				<groupId>com.google.guava</groupId>
				<artifactId>guava</artifactId>
				<version>${guava.version}</version>
			</dependency>

			<dependency>
				<groupId>com.alibaba</groupId>
				<artifactId>easy-retry-core</artifactId>
				<version>${project.version}</version>
			</dependency>

			<dependency>
				<groupId>com.alibaba</groupId>
				<artifactId>easy-retry-common</artifactId>
				<version>${project.version}</version>
			</dependency>

			<dependency>
				<groupId>com.caucho</groupId>
				<artifactId>hessian</artifactId>
				<version>4.0.60</version>
				<scope>provided</scope>
			</dependency>

			<dependency>
				<groupId>org.apache.commons</groupId>
				<artifactId>commons-lang3</artifactId>
				<version>3.11</version>
			</dependency>

			<dependency>
				<groupId>com.alibaba</groupId>
				<artifactId>fastjson</artifactId>
				<version>${fastjson.version}</version>
			</dependency>

			<dependency>
				<groupId>org.apache.commons</groupId>
				<artifactId>commons-collections4</artifactId>
				<version>4.4</version>
			</dependency>
			<dependency>
				<groupId>${project.groupId}</groupId>
				<artifactId>easy-retry-spring-extension</artifactId>
				<version>${project.version}</version>
			</dependency>
			<dependency>
				<groupId>${project.groupId}</groupId>
				<artifactId>easy-retry-guava-extension</artifactId>
				<version>${project.version}</version>
			</dependency>

			<dependency>
				<groupId>${project.groupId}</groupId>
				<artifactId>easy-retry-mybatis-extension</artifactId>
				<version>${project.version}</version>
			</dependency>

			<dependency>
				<groupId>${project.groupId}</groupId>
				<artifactId>easy-retry-starter-common</artifactId>
				<version>${project.version}</version>
			</dependency>
		</dependencies>
	</dependencyManagement>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
					<encoding>UTF-8</encoding>
				</configuration>
			</plugin>

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-resources-plugin</artifactId>
				<version>3.2.0</version>
				<configuration>
					<encoding>UTF-8</encoding>
				</configuration>
			</plugin>

			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>flatten-maven-plugin</artifactId>
				<version>1.1.0</version>
				<configuration>
					<updatePomFile>true</updatePomFile>
					<flattenMode>oss</flattenMode>
				</configuration>
				<executions>
					<execution>
						<id>flatten</id>
						<phase>process-resources</phase>
						<goals>
							<goal>flatten</goal>
						</goals>
					</execution>
					<execution>
						<id>flatten.clean</id>
						<phase>clean</phase>
						<goals>
							<goal>clean</goal>
						</goals>
					</execution>
				</executions>
			</plugin>

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<version>3.0.0-M5</version>
			</plugin>
		</plugins>
	</build>

	<profiles>
		<profile>
			<id>release</id>
			<build>
				<plugins>
					<plugin>
						<groupId>org.apache.maven.plugins</groupId>
						<artifactId>maven-gpg-plugin</artifactId>
						<version>${maven-gpg-plugin.version}</version>
						<executions>
							<execution>
								<phase>verify</phase>
								<goals>
									<goal>sign</goal>
								</goals>
							</execution>
						</executions>
					</plugin>

					<plugin>
						<groupId>org.apache.maven.plugins</groupId>
						<artifactId>maven-source-plugin</artifactId>
						<version>3.2.1</version>
						<executions>
							<execution>
								<id>attach-sources</id>
								<goals>
									<goal>jar</goal>
								</goals>
							</execution>
						</executions>
					</plugin>

					<plugin>
						<groupId>org.apache.maven.plugins</groupId>
						<artifactId>maven-javadoc-plugin</artifactId>
						<version>${maven-javadoc-plugin.version}</version>
						<executions>
							<execution>
								<id>attach-javadocs</id>
								<goals>
									<goal>jar</goal>
								</goals>
							</execution>
						</executions>
					</plugin>
				</plugins>
			</build>

			<distributionManagement>
				<snapshotRepository>
					<id>esnapshots</id>
					<url>https://oss.sonatype.org/content/repositories/snapshots</url>
				</snapshotRepository>
				<repository>
					<id>erelease</id>
					<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
				</repository>
			</distributionManagement>
		</profile>
	</profiles>
</project>
Download .txt
gitextract_y0h1aiip/

├── .editorconfig
├── .github/
│   └── workflows/
│       └── maven.yml
├── .gitignore
├── LICENSE
├── README.md
├── config/
│   └── intellij-java-google-style.xml
├── easy-retry-common/
│   ├── pom.xml
│   └── src/
│       └── main/
│           └── java/
│               └── com/
│                   └── alibaba/
│                       └── easyretry/
│                           └── common/
│                               ├── AbstractResultPredicate.java
│                               ├── AbstractRetrySyncExecutor.java
│                               ├── EasyRetryPredicate.java
│                               ├── Invocation.java
│                               ├── RetryConfiguration.java
│                               ├── RetryContainer.java
│                               ├── RetryContext.java
│                               ├── RetryExecutor.java
│                               ├── RetryIdentify.java
│                               ├── RetryLifecycle.java
│                               ├── RetrySyncExecutor.java
│                               ├── SCallable.java
│                               ├── SimpleMethodInvocation.java
│                               ├── access/
│                               │   ├── RetrySerializerAccess.java
│                               │   ├── RetryStrategyAccess.java
│                               │   └── RetryTaskAccess.java
│                               ├── constant/
│                               │   ├── enums/
│                               │   │   ├── HandleResultEnum.java
│                               │   │   ├── RetryTaskStatusEnum.java
│                               │   │   └── RetryTypeEnum.java
│                               │   └── package-info.java
│                               ├── entity/
│                               │   └── RetryTask.java
│                               ├── event/
│                               │   ├── RetryEvent.java
│                               │   ├── RetryEventMulticaster.java
│                               │   ├── RetryListener.java
│                               │   ├── before/
│                               │   │   ├── AfterSaveBeforeRetryEvent.java
│                               │   │   ├── BeforeRetryEvent.java
│                               │   │   └── PrepSaveBeforeRetryEvent.java
│                               │   └── on/
│                               │       ├── FailureOnRetryEvent.java
│                               │       ├── OnRetryEvent.java
│                               │       ├── StopOnRetryEvent.java
│                               │       └── SuccessOnRetryEvent.java
│                               ├── filter/
│                               │   ├── AbstractRetryFilter.java
│                               │   ├── RetryFilter.java
│                               │   ├── RetryFilterDiscover.java
│                               │   ├── RetryFilterInvocation.java
│                               │   ├── RetryFilterInvocationHandler.java
│                               │   ├── RetryFilterRegister.java
│                               │   ├── RetryFilterRegisterHandler.java
│                               │   └── RetryFilterResponse.java
│                               ├── processor/
│                               │   ├── AsyncPersistenceProcessor.java
│                               │   ├── RetryProcessor.java
│                               │   └── SyncProcessor.java
│                               ├── resolve/
│                               │   └── ExecutorSolver.java
│                               ├── retryer/
│                               │   ├── Retryer.java
│                               │   └── RetryerInfo.java
│                               ├── serializer/
│                               │   ├── ArgDeSerializerInfo.java
│                               │   ├── ArgSerializerInfo.java
│                               │   ├── EasyRetrySerializer.java
│                               │   ├── ResultPredicateSerializer.java
│                               │   └── RetryArgSerializer.java
│                               └── strategy/
│                                   ├── RetryStrategy.java
│                                   ├── StopStrategy.java
│                                   └── WaitStrategy.java
├── easy-retry-core/
│   ├── pom.xml
│   └── src/
│       ├── main/
│       │   └── java/
│       │       └── com/
│       │           └── alibaba/
│       │               └── easyretry/
│       │                   └── core/
│       │                       ├── DegradeAbleRetryExecutor.java
│       │                       ├── PersistenceRetryExecutor.java
│       │                       ├── PersistenceRetryer.java
│       │                       ├── PersistenceRetryerBuilder.java
│       │                       ├── RetryerBuilder.java
│       │                       ├── SyncRetryer.java
│       │                       ├── SyncRetryerBuilder.java
│       │                       ├── access/
│       │                       │   ├── DefaultRetrySerializerAccess.java
│       │                       │   └── MemoryRetryTaskAccess.java
│       │                       ├── container/
│       │                       │   └── SimpleRetryContainer.java
│       │                       ├── context/
│       │                       │   └── MaxAttemptsPersistenceRetryContext.java
│       │                       ├── degrade/
│       │                       │   └── EasyRetryDegradeHelper.java
│       │                       ├── event/
│       │                       │   └── SimpleRetryEventMulticaster.java
│       │                       ├── filter/
│       │                       │   ├── DefaultRetryFilterInvocationHandler.java
│       │                       │   ├── DefaultRetryFilterRegisterHandler.java
│       │                       │   ├── IdentifyRetryFilter.java
│       │                       │   ├── MethodExcuteRetryFilter.java
│       │                       │   ├── NOOPRetryFilter.java
│       │                       │   ├── SPIRetryFilterDiscover.java
│       │                       │   └── SimpleRetryFilterRegister.java
│       │                       ├── process/
│       │                       │   ├── async/
│       │                       │   │   ├── AbstractAsyncPersistenceProcessor.java
│       │                       │   │   ├── before/
│       │                       │   │   │   ├── AbstractAsyncPersistenceBeforeRetryProcessor.java
│       │                       │   │   │   ├── ExceptionPersistenceAsyncBeforeRetryProcessor.java
│       │                       │   │   │   └── ResultAsynPersistenceBeforeRetryProcessor.java
│       │                       │   │   └── on/
│       │                       │   │       ├── AbstractAsyncPersistenceOnRetryProcessor.java
│       │                       │   │       ├── ExceptionPersistenceAsynOnRetryProcessor.java
│       │                       │   │       └── ResultAsynPersistenceOnRetryProcessor.java
│       │                       │   └── package-info.java
│       │                       ├── serializer/
│       │                       │   ├── FastJsonRetryArgSerializer.java
│       │                       │   ├── HessianResultPredicateSerializer.java
│       │                       │   └── HessianRetryArgSerializer.java
│       │                       ├── strategy/
│       │                       │   └── DefaultRetryStrategy.java
│       │                       └── utils/
│       │                           ├── HessianSerializerUtils.java
│       │                           ├── LogUtils.java
│       │                           └── PrintUtils.java
│       └── test/
│           └── java/
│               └── com/
│                   └── alibaba/
│                       └── easyretry/
│                           └── core/
│                               └── utils/
│                                   └── TestClass.java
├── easy-retry-extensions/
│   ├── easy-retry-guava-extension/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── alibaba/
│   │                       └── easyretry/
│   │                           └── extension/
│   │                               └── guava/
│   │                                   ├── GuavaRetrySyncExecutor.java
│   │                                   └── package-info.java
│   ├── easy-retry-mybatis-extension/
│   │   ├── pom.xml
│   │   └── src/
│   │       ├── main/
│   │       │   ├── java/
│   │       │   │   └── com/
│   │       │   │       └── alibaba/
│   │       │   │           └── easyretry/
│   │       │   │               └── extension/
│   │       │   │                   └── mybatis/
│   │       │   │                       ├── access/
│   │       │   │                       │   └── MybatisRetryTaskAccess.java
│   │       │   │                       ├── common/
│   │       │   │                       │   └── utils/
│   │       │   │                       │       └── HostUtils.java
│   │       │   │                       ├── dao/
│   │       │   │                       │   ├── BaseDAOSupport.java
│   │       │   │                       │   ├── RetryTaskDAO.java
│   │       │   │                       │   └── RetryTaskDAOImpl.java
│   │       │   │                       ├── po/
│   │       │   │                       │   └── RetryTaskPO.java
│   │       │   │                       └── query/
│   │       │   │                           └── RetryTaskQuery.java
│   │       │   └── resources/
│   │       │       └── dal/
│   │       │           └── easyretry/
│   │       │               ├── easy-mybatis-config.xml
│   │       │               └── mapper/
│   │       │                   └── easy-retry-task-mapper.xml
│   │       └── test/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── alibaba/
│   │           │           └── easyretry/
│   │           │               └── extension/
│   │           │                   └── mybatis/
│   │           │                       ├── DbConfig.java
│   │           │                       ├── MyBatisConfig.java
│   │           │                       ├── access/
│   │           │                       │   └── MybatisRetryTaskAccessTest.java
│   │           │                       ├── common/
│   │           │                       │   └── utils/
│   │           │                       │       └── HostUtilsTest.java
│   │           │                       └── dao/
│   │           │                           └── RetryTaskDAOImplTest.java
│   │           └── resources/
│   │               ├── logback.xml
│   │               └── task.sql
│   ├── easy-retry-spring-extension/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── alibaba/
│   │                       └── easyretry/
│   │                           └── extension/
│   │                               └── spring/
│   │                                   ├── RetryListenerInitialize.java
│   │                                   ├── SPELParamPredicate.java
│   │                                   ├── SPELResultPredicate.java
│   │                                   ├── SpringEventApplicationListener.java
│   │                                   ├── SpringRetryFilterDiscover.java
│   │                                   └── aop/
│   │                                       ├── EasyRetryable.java
│   │                                       └── RetryInterceptor.java
│   └── pom.xml
├── easy-retry-starters/
│   ├── easy-retry-memory-starter/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── alibaba/
│   │           │           └── easyretry/
│   │           │               └── memory/
│   │           │                   ├── MemoryAutoConfiguration.java
│   │           │                   └── config/
│   │           │                       └── EasyRetryMemoryCompatibleProperties.java
│   │           └── resources/
│   │               └── META-INF/
│   │                   ├── additional-spring-configuration-metadata.json
│   │                   └── spring.factories
│   ├── easy-retry-mybatis-starter/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── alibaba/
│   │           │           └── easyretry/
│   │           │               └── mybatis/
│   │           │                   ├── MybatisAutoConfiguration.java
│   │           │                   └── conifg/
│   │           │                       └── EasyRetryMybatisProperties.java
│   │           └── resources/
│   │               └── META-INF/
│   │                   ├── additional-spring-configuration-metadata.json
│   │                   └── spring.factories
│   ├── easy-retry-starter-common/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── com/
│   │                   └── alibaba/
│   │                       └── easyretry/
│   │                           └── starter/
│   │                               └── common/
│   │                                   └── CommonAutoConfiguration.java
│   └── pom.xml
└── pom.xml
Download .txt
SYMBOL INDEX (390 symbols across 112 files)

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/AbstractResultPredicate.java
  class AbstractResultPredicate (line 6) | public abstract class AbstractResultPredicate<T> implements EasyRetryPre...
    method apply (line 8) | @Override

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/AbstractRetrySyncExecutor.java
  class AbstractRetrySyncExecutor (line 9) | public abstract class AbstractRetrySyncExecutor<V> implements RetrySyncE...
    method setRetryerInfo (line 13) | @Override
    method getRetryerInfo (line 18) | public RetryerInfo<V> getRetryerInfo() {
    method call (line 23) | @Override

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/EasyRetryPredicate.java
  type EasyRetryPredicate (line 8) | public interface EasyRetryPredicate<T, R> extends Serializable {
    method apply (line 10) | R apply(T result);

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/Invocation.java
  type Invocation (line 6) | public interface Invocation {
    method invoke (line 8) | Object invoke() throws Throwable;

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryConfiguration.java
  type RetryConfiguration (line 13) | public interface RetryConfiguration {
    method getRetryTaskAccess (line 15) | RetryTaskAccess getRetryTaskAccess();
    method getRetrySerializerAccess (line 17) | RetrySerializerAccess getRetrySerializerAccess();
    method getRetryStrategyAccess (line 19) | RetryStrategyAccess getRetryStrategyAccess();
    method getExecutorSolver (line 21) | ExecutorSolver getExecutorSolver();
    method getResultPredicateSerializer (line 23) | ResultPredicateSerializer getResultPredicateSerializer();
    method getMaxRetryTimes (line 25) | Integer getMaxRetryTimes();
    method getRetryEventMulticaster (line 27) | RetryEventMulticaster getRetryEventMulticaster();
    method getRetrySyncExecutor (line 29) | default AbstractRetrySyncExecutor getRetrySyncExecutor() {

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryContainer.java
  type RetryContainer (line 6) | public interface RetryContainer extends RetryLifecycle {

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryContext.java
  type RetryContext (line 3) | public interface RetryContext extends RetryLifecycle {
    method setAttribute (line 5) | void setAttribute(String key, String value);
    method getAttribute (line 7) | String getAttribute(String key);
    method getId (line 12) | String getId();
    method getInvocation (line 14) | Invocation getInvocation();

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryExecutor.java
  type RetryExecutor (line 8) | public interface RetryExecutor {
    method doExecute (line 10) | HandleResultEnum doExecute(RetryContext context);

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryIdentify.java
  class RetryIdentify (line 8) | public class RetryIdentify {
    method start (line 14) | public static void start() {
    method stop (line 18) | public static void stop() {
    method isOnRetry (line 22) | public static boolean isOnRetry() {

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryLifecycle.java
  type RetryLifecycle (line 6) | public interface RetryLifecycle {
    method start (line 8) | void start();
    method stop (line 10) | void stop();

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetrySyncExecutor.java
  type RetrySyncExecutor (line 9) | public interface RetrySyncExecutor<V> {
    method call (line 11) | V call(SCallable<V> callable) throws Throwable;
    method setRetryerInfo (line 13) | void setRetryerInfo(RetryerInfo<V> retryerInfo);

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/SCallable.java
  type SCallable (line 8) | @FunctionalInterface
    method call (line 11) | V call() throws Throwable;

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/SimpleMethodInvocation.java
  class SimpleMethodInvocation (line 12) | @AllArgsConstructor
    method invoke (line 24) | @Override
    method toString (line 29) | @Override

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/access/RetrySerializerAccess.java
  type RetrySerializerAccess (line 10) | public interface RetrySerializerAccess {
    method getCurrentGlobalRetrySerializer (line 15) | RetryArgSerializer getCurrentGlobalRetrySerializer();

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/access/RetryStrategyAccess.java
  type RetryStrategyAccess (line 11) | public interface RetryStrategyAccess {
    method getCurrentGlobalStopStrategy (line 16) | StopStrategy getCurrentGlobalStopStrategy();
    method getCurrentGlobalWaitStrategy (line 21) | WaitStrategy getCurrentGlobalWaitStrategy();

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/access/RetryTaskAccess.java
  type RetryTaskAccess (line 10) | public interface RetryTaskAccess {
    method saveRetryTask (line 15) | boolean saveRetryTask(RetryTask retryTask);
    method handlingRetryTask (line 20) | boolean handlingRetryTask(RetryTask retryTask);
    method finishRetryTask (line 25) | boolean finishRetryTask(RetryTask retryTask);
    method stopRetryTask (line 30) | boolean stopRetryTask(RetryTask retryTask);
    method listAvailableTasks (line 35) | List<RetryTask> listAvailableTasks(Long lastId);

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/constant/enums/HandleResultEnum.java
  type HandleResultEnum (line 8) | public enum HandleResultEnum {

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/constant/enums/RetryTaskStatusEnum.java
  type RetryTaskStatusEnum (line 14) | public enum RetryTaskStatusEnum {
    method RetryTaskStatusEnum (line 44) | RetryTaskStatusEnum(int code, String desc) {
    method fromCode (line 49) | public static RetryTaskStatusEnum fromCode(int code) {

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/constant/enums/RetryTypeEnum.java
  type RetryTypeEnum (line 8) | public enum RetryTypeEnum {

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/entity/RetryTask.java
  class RetryTask (line 15) | @Data

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/RetryEvent.java
  type RetryEvent (line 6) | public interface RetryEvent {
    method getName (line 8) | String getName();
    method isOnRetry (line 10) | boolean isOnRetry();
    method setAttribute (line 12) | void setAttribute(String key, String vule);

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/RetryEventMulticaster.java
  type RetryEventMulticaster (line 6) | public interface RetryEventMulticaster {
    method register (line 8) | void register(RetryListener listener);
    method multicast (line 10) | void multicast(RetryEvent retryEvent);

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/RetryListener.java
  type RetryListener (line 6) | public interface RetryListener<T extends RetryEvent> {
    method onRetryEvent (line 8) | void onRetryEvent(T event);

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/before/AfterSaveBeforeRetryEvent.java
  class AfterSaveBeforeRetryEvent (line 8) | public class AfterSaveBeforeRetryEvent extends BeforeRetryEvent {
    method AfterSaveBeforeRetryEvent (line 10) | public AfterSaveBeforeRetryEvent(RetryTask retryTask) {

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/before/BeforeRetryEvent.java
  class BeforeRetryEvent (line 14) | public abstract class BeforeRetryEvent implements RetryEvent {
    method BeforeRetryEvent (line 18) | public BeforeRetryEvent(RetryTask retryTask) {
    method isOnRetry (line 22) | @Override
    method setAttribute (line 27) | @Override
    method getName (line 36) | @Override

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/before/PrepSaveBeforeRetryEvent.java
  class PrepSaveBeforeRetryEvent (line 8) | public class PrepSaveBeforeRetryEvent extends BeforeRetryEvent {
    method PrepSaveBeforeRetryEvent (line 10) | public PrepSaveBeforeRetryEvent(RetryTask retryTask) {

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/on/FailureOnRetryEvent.java
  class FailureOnRetryEvent (line 8) | public class FailureOnRetryEvent extends OnRetryEvent {
    method FailureOnRetryEvent (line 10) | public FailureOnRetryEvent(RetryContext retryContext) {

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/on/OnRetryEvent.java
  class OnRetryEvent (line 9) | public abstract class OnRetryEvent implements RetryEvent {
    method OnRetryEvent (line 13) | public OnRetryEvent(RetryContext retryContext) {
    method setAttribute (line 17) | @Override
    method getAttribute (line 22) | public String getAttribute(String key) {
    method isOnRetry (line 26) | @Override
    method getName (line 31) | @Override

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/on/StopOnRetryEvent.java
  class StopOnRetryEvent (line 8) | public class StopOnRetryEvent extends OnRetryEvent {
    method StopOnRetryEvent (line 10) | public StopOnRetryEvent(RetryContext retryContext) {

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/on/SuccessOnRetryEvent.java
  class SuccessOnRetryEvent (line 8) | public class SuccessOnRetryEvent extends OnRetryEvent {
    method SuccessOnRetryEvent (line 10) | public SuccessOnRetryEvent(RetryContext retryContext) {

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/AbstractRetryFilter.java
  class AbstractRetryFilter (line 6) | public abstract class AbstractRetryFilter implements RetryFilter {
    method setNext (line 10) | @Override

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilter.java
  type RetryFilter (line 8) | public interface RetryFilter {
    method doFilter (line 10) | RetryFilterResponse doFilter(RetryContext retryContext) throws Throwable;
    method setNext (line 12) | void setNext(RetryFilter next);

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterDiscover.java
  type RetryFilterDiscover (line 8) | public interface RetryFilterDiscover {
    method discoverAll (line 10) | List<RetryFilter> discoverAll();

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterInvocation.java
  type RetryFilterInvocation (line 8) | public interface RetryFilterInvocation {
    method invoke (line 10) | RetryFilterResponse invoke(RetryContext retryContext) throws Throwable;

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterInvocationHandler.java
  type RetryFilterInvocationHandler (line 6) | public interface RetryFilterInvocationHandler {
    method handle (line 7) | void handle();

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterRegister.java
  type RetryFilterRegister (line 8) | public interface RetryFilterRegister {
    method register (line 10) | void register(RetryFilter retryFilter);
    method export (line 12) | List<RetryFilter> export();

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterRegisterHandler.java
  type RetryFilterRegisterHandler (line 6) | public interface RetryFilterRegisterHandler {
    method handle (line 8) | void handle();

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterResponse.java
  class RetryFilterResponse (line 8) | @Data

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/processor/AsyncPersistenceProcessor.java
  type AsyncPersistenceProcessor (line 6) | public interface AsyncPersistenceProcessor<R> extends RetryProcessor {
    method process (line 8) | @Override
    method needRetry (line 11) | boolean needRetry();
    method getResult (line 13) | R getResult() throws Throwable;

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/processor/RetryProcessor.java
  type RetryProcessor (line 6) | public interface RetryProcessor {
    method process (line 8) | void process();

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/processor/SyncProcessor.java
  type SyncProcessor (line 6) | public interface SyncProcessor<R> extends RetryProcessor {
    method getResult (line 8) | R getResult() throws Throwable;

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/resolve/ExecutorSolver.java
  type ExecutorSolver (line 6) | public interface ExecutorSolver {
    method resolver (line 8) | Object resolver(String executorName);

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/retryer/Retryer.java
  type Retryer (line 8) | public interface Retryer<V> {
    method call (line 10) | V call(SCallable<V> callable) throws Throwable;

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/retryer/RetryerInfo.java
  class RetryerInfo (line 12) | @Data

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/ArgDeSerializerInfo.java
  class ArgDeSerializerInfo (line 8) | @Data

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/ArgSerializerInfo.java
  class ArgSerializerInfo (line 8) | @Data

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/EasyRetrySerializer.java
  type EasyRetrySerializer (line 6) | public interface EasyRetrySerializer<T> {
    method serialize (line 8) | String serialize(T serializeInfo);
    method deSerialize (line 10) | T deSerialize(String infoStr);

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/ResultPredicateSerializer.java
  type ResultPredicateSerializer (line 8) | public interface ResultPredicateSerializer extends EasyRetrySerializer<A...

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/RetryArgSerializer.java
  type RetryArgSerializer (line 6) | public interface RetryArgSerializer extends EasyRetrySerializer<ArgSeria...

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/strategy/RetryStrategy.java
  type RetryStrategy (line 8) | public interface RetryStrategy {
    method clear (line 10) | void clear(RetryContext context);

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/strategy/StopStrategy.java
  type StopStrategy (line 8) | public interface StopStrategy extends RetryStrategy {
    method shouldStop (line 10) | boolean shouldStop(RetryContext context);

FILE: easy-retry-common/src/main/java/com/alibaba/easyretry/common/strategy/WaitStrategy.java
  type WaitStrategy (line 8) | public interface WaitStrategy extends RetryStrategy {
    method shouldWait (line 10) | boolean shouldWait(RetryContext context);
    method backOff (line 12) | void backOff(RetryContext context);

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/DegradeAbleRetryExecutor.java
  class DegradeAbleRetryExecutor (line 13) | @Slf4j
    method doExecute (line 22) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/PersistenceRetryExecutor.java
  class PersistenceRetryExecutor (line 30) | @Slf4j
    method doExecute (line 39) | @Override
    method handle (line 50) | private HandleResultEnum handle(RetryContext context) {
    method finish (line 98) | private void finish(RetryContext context) {
    method stop (line 112) | private void stop(RetryContext context) {

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/PersistenceRetryer.java
  class PersistenceRetryer (line 15) | @Slf4j
    method PersistenceRetryer (line 21) | public PersistenceRetryer(RetryerInfo<V> retryerInfo) {
    method call (line 25) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/PersistenceRetryerBuilder.java
  class PersistenceRetryerBuilder (line 10) | public class PersistenceRetryerBuilder<T> {
    method PersistenceRetryerBuilder (line 14) | public PersistenceRetryerBuilder(RetryConfiguration retryConfiguration) {
    method of (line 19) | public static <T> PersistenceRetryerBuilder<T> of(RetryConfiguration r...
    method withExecutorName (line 23) | public PersistenceRetryerBuilder<T> withExecutorName(String executorNa...
    method withExecutorMethodName (line 28) | public PersistenceRetryerBuilder<T> withExecutorMethodName(String exec...
    method withBizId (line 33) | public PersistenceRetryerBuilder<T> withBizId(String bizId) {
    method withArgs (line 38) | public PersistenceRetryerBuilder<T> withArgs(Object[] args) {
    method withOnException (line 43) | public PersistenceRetryerBuilder<T> withOnException(Class<? extends Th...
    method withOnFailureMethod (line 48) | public PersistenceRetryerBuilder<T> withOnFailureMethod(String onFailu...
    method withReThrowException (line 53) | public PersistenceRetryerBuilder<T> withReThrowException(boolean reThr...
    method withNamespace (line 58) | public PersistenceRetryerBuilder<T> withNamespace(String namespace) {
    method withConfiguration (line 63) | public PersistenceRetryerBuilder<T> withConfiguration(RetryConfigurati...
    method withResultPredicate (line 68) | public PersistenceRetryerBuilder<T> withResultPredicate(AbstractResult...
    method build (line 73) | public PersistenceRetryer<T> build() {

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/RetryerBuilder.java
  class RetryerBuilder (line 11) | public class RetryerBuilder<T> {
    method withExecutorName (line 43) | public RetryerBuilder<T> withExecutorName(String executorName) {
    method withExecutorMethodName (line 48) | public RetryerBuilder<T> withExecutorMethodName(String executorMethodN...
    method withBizId (line 53) | public RetryerBuilder<T> withBizId(String bizId) {
    method withArgs (line 58) | public RetryerBuilder<T> withArgs(Object[] args) {
    method withOnException (line 63) | public RetryerBuilder<T> withOnException(Class<? extends Throwable> on...
    method withOnFailureMethod (line 68) | public RetryerBuilder<T> withOnFailureMethod(String onFailureMethod) {
    method withReThrowException (line 73) | public RetryerBuilder<T> withReThrowException(boolean reThrowException) {
    method withNamespace (line 78) | public RetryerBuilder<T> withNamespace(String namespace) {
    method withConfiguration (line 83) | public RetryerBuilder<T> withConfiguration(RetryConfiguration retryCon...
    method withResultPredicate (line 88) | public RetryerBuilder<T> withResultPredicate(AbstractResultPredicate<T...
    method build (line 93) | public Retryer<T> build(RetryTypeEnum retryTypeEnum) {
    method buildSyncRetryer (line 101) | private SyncRetryer<T> buildSyncRetryer() {
    method buildAsyncRetryer (line 107) | private PersistenceRetryer<T> buildAsyncRetryer() {

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/SyncRetryer.java
  class SyncRetryer (line 15) | @Slf4j
    method SyncRetryer (line 21) | public SyncRetryer(RetryerInfo<V> retryerInfo) {
    method call (line 25) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/SyncRetryerBuilder.java
  class SyncRetryerBuilder (line 11) | public class SyncRetryerBuilder<T> {
    method SyncRetryerBuilder (line 15) | public SyncRetryerBuilder(RetryConfiguration retryConfiguration) {
    method of (line 20) | public static <T> SyncRetryerBuilder<T> of(RetryConfiguration retryCon...
    method withConfiguration (line 24) | public SyncRetryerBuilder<T> withConfiguration(RetryConfiguration retr...
    method build (line 30) | public SyncRetryer<T> build() {

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/access/DefaultRetrySerializerAccess.java
  class DefaultRetrySerializerAccess (line 10) | public class DefaultRetrySerializerAccess implements RetrySerializerAcce...
    method getCurrentGlobalRetrySerializer (line 12) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/access/MemoryRetryTaskAccess.java
  class MemoryRetryTaskAccess (line 17) | public class MemoryRetryTaskAccess implements RetryTaskAccess {
    method saveRetryTask (line 23) | @Override
    method handlingRetryTask (line 31) | @Override
    method finishRetryTask (line 38) | @Override
    method stopRetryTask (line 44) | @Override
    method listAvailableTasks (line 51) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/container/SimpleRetryContainer.java
  class SimpleRetryContainer (line 24) | @Slf4j
    method SimpleRetryContainer (line 33) | public SimpleRetryContainer() {
    method SimpleRetryContainer (line 36) | public SimpleRetryContainer(
    method start (line 42) | @Override
    method stop (line 65) | @Override
    class TaskConsumer (line 69) | public class TaskConsumer implements Runnable {
      method TaskConsumer (line 76) | private TaskConsumer(BlockingQueue<RetryContext> queue) {
      method run (line 80) | @Override
      method doExecute (line 93) | private void doExecute() {
    class TaskProducer (line 119) | public class TaskProducer implements Runnable {
      method TaskProducer (line 130) | public TaskProducer(BlockingQueue<RetryContext> queue) {
      method run (line 134) | @Override
      method doSelect (line 148) | private void doSelect() {

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/context/MaxAttemptsPersistenceRetryContext.java
  class MaxAttemptsPersistenceRetryContext (line 25) | @Data
    method compareTo (line 48) | @Override
    method start (line 53) | @Override
    method stop (line 57) | @Override
    method setAttribute (line 63) | @Override
    method getAttribute (line 72) | @Override
    method getNextRetryTime (line 82) | public Long getNextRetryTime(TimeUnit unit) {
    method setNextRetryTime (line 86) | public void setNextRetryTime(Long nexRetryTime, TimeUnit unit) {
    method getId (line 90) | @Override
    class RetryContextBuilder (line 95) | public static class RetryContextBuilder {
      method RetryContextBuilder (line 103) | public RetryContextBuilder(RetryConfiguration retryConfiguration, Re...
      method buildInvocation (line 109) | public RetryContextBuilder buildInvocation() {
      method buildRetryArgSerializer (line 124) | public RetryContextBuilder buildRetryArgSerializer() {
      method buildStopStrategy (line 130) | public RetryContextBuilder buildStopStrategy() {
      method buildWaitStrategy (line 136) | public RetryContextBuilder buildWaitStrategy() {
      method buildRetryTask (line 142) | public RetryContextBuilder buildRetryTask() {
      method buildMaxRetryTimes (line 147) | public RetryContextBuilder buildMaxRetryTimes() {
      method buildOnFailureMethod (line 152) | public RetryContextBuilder buildOnFailureMethod() {
      method buildResultPredicateSerializer (line 157) | public RetryContextBuilder buildResultPredicateSerializer() {
      method buildPriority (line 163) | public RetryContextBuilder buildPriority(Long priority) {
      method build (line 168) | public MaxAttemptsPersistenceRetryContext build() {

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/degrade/EasyRetryDegradeHelper.java
  type EasyRetryDegradeHelper (line 8) | public interface EasyRetryDegradeHelper {
    method degrade (line 16) | boolean degrade(RetryContext retryContext);

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/event/SimpleRetryEventMulticaster.java
  class SimpleRetryEventMulticaster (line 16) | public class SimpleRetryEventMulticaster implements RetryEventMulticaster {
    method register (line 21) | @Override
    method multicast (line 26) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/DefaultRetryFilterInvocationHandler.java
  class DefaultRetryFilterInvocationHandler (line 18) | public class DefaultRetryFilterInvocationHandler implements RetryFilterI...
    method invoke (line 25) | @Override
    method handle (line 30) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/DefaultRetryFilterRegisterHandler.java
  class DefaultRetryFilterRegisterHandler (line 16) | public class DefaultRetryFilterRegisterHandler implements RetryFilterReg...
    method handle (line 24) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/IdentifyRetryFilter.java
  class IdentifyRetryFilter (line 11) | public class IdentifyRetryFilter extends AbstractRetryFilter {
    method doFilter (line 13) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/MethodExcuteRetryFilter.java
  class MethodExcuteRetryFilter (line 10) | public class MethodExcuteRetryFilter implements RetryFilter {
    method doFilter (line 12) | @Override
    method setNext (line 19) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/NOOPRetryFilter.java
  class NOOPRetryFilter (line 10) | public class NOOPRetryFilter extends AbstractRetryFilter {
    method doFilter (line 12) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/SPIRetryFilterDiscover.java
  class SPIRetryFilterDiscover (line 15) | public class SPIRetryFilterDiscover implements RetryFilterDiscover {
    method discoverAll (line 17) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/SimpleRetryFilterRegister.java
  class SimpleRetryFilterRegister (line 13) | public class SimpleRetryFilterRegister implements RetryFilterRegister {
    method register (line 17) | @Override
    method export (line 22) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/AbstractAsyncPersistenceProcessor.java
  class AbstractAsyncPersistenceProcessor (line 9) | @Slf4j
    method process (line 12) | @Override
    method doProcess (line 20) | protected abstract void doProcess();
    method needRetry (line 22) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/before/AbstractAsyncPersistenceBeforeRetryProcessor.java
  class AbstractAsyncPersistenceBeforeRetryProcessor (line 21) | @Slf4j
    method AbstractAsyncPersistenceBeforeRetryProcessor (line 29) | public AbstractAsyncPersistenceBeforeRetryProcessor(
    method doProcess (line 35) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/before/ExceptionPersistenceAsyncBeforeRetryProcessor.java
  class ExceptionPersistenceAsyncBeforeRetryProcessor (line 13) | public class ExceptionPersistenceAsyncBeforeRetryProcessor<R> extends
    method ExceptionPersistenceAsyncBeforeRetryProcessor (line 18) | public ExceptionPersistenceAsyncBeforeRetryProcessor(Throwable throwable,
    method needRetry (line 24) | @Override
    method getResult (line 33) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/before/ResultAsynPersistenceBeforeRetryProcessor.java
  class ResultAsynPersistenceBeforeRetryProcessor (line 11) | public class ResultAsynPersistenceBeforeRetryProcessor<R> extends
    method ResultAsynPersistenceBeforeRetryProcessor (line 16) | public ResultAsynPersistenceBeforeRetryProcessor(R result, RetryerInfo...
    method needRetry (line 21) | @Override
    method getResult (line 31) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/on/AbstractAsyncPersistenceOnRetryProcessor.java
  class AbstractAsyncPersistenceOnRetryProcessor (line 11) | @Slf4j
    method AbstractAsyncPersistenceOnRetryProcessor (line 20) | public AbstractAsyncPersistenceOnRetryProcessor(MaxAttemptsPersistence...
    method process (line 24) | @Override
    method doProcess (line 33) | @Override
    method getRetryResult (line 45) | public HandleResultEnum getRetryResult() {

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/on/ExceptionPersistenceAsynOnRetryProcessor.java
  class ExceptionPersistenceAsynOnRetryProcessor (line 8) | public class ExceptionPersistenceAsynOnRetryProcessor<R> extends
    method ExceptionPersistenceAsynOnRetryProcessor (line 13) | public ExceptionPersistenceAsynOnRetryProcessor(Throwable throwable,
    method needRetry (line 19) | @Override
    method getResult (line 24) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/on/ResultAsynPersistenceOnRetryProcessor.java
  class ResultAsynPersistenceOnRetryProcessor (line 11) | public class ResultAsynPersistenceOnRetryProcessor<R> extends
    method ResultAsynPersistenceOnRetryProcessor (line 16) | public ResultAsynPersistenceOnRetryProcessor(R result,
    method needRetry (line 22) | @Override
    method getResult (line 33) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/serializer/FastJsonRetryArgSerializer.java
  class FastJsonRetryArgSerializer (line 15) | public class FastJsonRetryArgSerializer implements RetryArgSerializer {
    method serialize (line 21) | @Override
    method deSerialize (line 34) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/serializer/HessianResultPredicateSerializer.java
  class HessianResultPredicateSerializer (line 10) | public class HessianResultPredicateSerializer implements ResultPredicate...
    method serialize (line 12) | @Override
    method deSerialize (line 17) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/serializer/HessianRetryArgSerializer.java
  class HessianRetryArgSerializer (line 13) | @Slf4j
    method serialize (line 16) | @Override
    method deSerialize (line 25) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/strategy/DefaultRetryStrategy.java
  class DefaultRetryStrategy (line 15) | @Slf4j
    method shouldStop (line 23) | @Override
    method shouldWait (line 39) | @Override
    method backOff (line 51) | @Override
    method clear (line 80) | @Override

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/utils/HessianSerializerUtils.java
  class HessianSerializerUtils (line 14) | public class HessianSerializerUtils {
    method serialize (line 16) | public static <T> String serialize(T t) {
    method deSerialize (line 26) | public static <T> T deSerialize(String str, Class<T> tClass) {

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/utils/LogUtils.java
  class LogUtils (line 9) | public class LogUtils {

FILE: easy-retry-core/src/main/java/com/alibaba/easyretry/core/utils/PrintUtils.java
  class PrintUtils (line 10) | @Slf4j
    method monitorInfo (line 13) | public static void monitorInfo(String action, RetryContext context) {
    method monitorInfo (line 17) | public static void monitorInfo(String action, RetryContext context, St...

FILE: easy-retry-core/src/test/java/com/alibaba/easyretry/core/utils/TestClass.java
  class TestClass (line 3) | class TestClass {
    method say (line 5) | public void say() {

FILE: easy-retry-extensions/easy-retry-guava-extension/src/main/java/com/alibaba/easyretry/extension/guava/GuavaRetrySyncExecutor.java
  class GuavaRetrySyncExecutor (line 15) | public class GuavaRetrySyncExecutor<V> extends AbstractRetrySyncExecutor...
    method call (line 19) | @Override

FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/access/MybatisRetryTaskAccess.java
  class MybatisRetryTaskAccess (line 25) | @AllArgsConstructor
    method saveRetryTask (line 30) | @Override
    method handlingRetryTask (line 36) | @Override
    method finishRetryTask (line 41) | @Override
    method stopRetryTask (line 48) | @Override
    method updateRetryTaskStatus (line 53) | private boolean updateRetryTaskStatus(RetryTask retryTask, RetryTaskSt...
    method listAvailableTasks (line 60) | @Override
    method convert (line 72) | private List<RetryTask> convert(List<RetryTaskPO> retryTasks) {
    method convert (line 76) | private RetryTask convert(RetryTaskPO retryTaskPO) {
    method covert (line 91) | private RetryTaskPO covert(RetryTask retryTask) {

FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/common/utils/HostUtils.java
  class HostUtils (line 7) | public class HostUtils {
    method getHostIP (line 25) | public static String getHostIP() {

FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/dao/BaseDAOSupport.java
  class BaseDAOSupport (line 12) | public abstract class BaseDAOSupport {
    method BaseDAOSupport (line 16) | public BaseDAOSupport(SqlSessionFactory sqlSessionFactory) {
    method execute (line 20) | protected <T> T execute(Function<SqlSession, T> function) {
    method execute (line 27) | protected <T> T execute(Function<SqlSession, T> function, boolean auto...

FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/dao/RetryTaskDAO.java
  type RetryTaskDAO (line 11) | public interface RetryTaskDAO {
    method saveRetryTask (line 13) | boolean saveRetryTask(RetryTaskPO retryTaskPO);
    method listRetryTask (line 15) | List<RetryTaskPO> listRetryTask(RetryTaskQuery retryTaskQuery);
    method updateRetryTask (line 17) | boolean updateRetryTask(RetryTaskPO retryTaskPO);
    method deleteRetryTask (line 19) | boolean deleteRetryTask(RetryTaskPO retryTaskPO);

FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/dao/RetryTaskDAOImpl.java
  class RetryTaskDAOImpl (line 15) | public class RetryTaskDAOImpl extends BaseDAOSupport implements RetryTas...
    method RetryTaskDAOImpl (line 17) | public RetryTaskDAOImpl(SqlSessionFactory sqlSessionFactory) {
    method saveRetryTask (line 21) | @Override
    method listRetryTask (line 29) | @Override
    method updateRetryTask (line 38) | @Override
    method deleteRetryTask (line 48) | @Override

FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/po/RetryTaskPO.java
  class RetryTaskPO (line 13) | @Data

FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/query/RetryTaskQuery.java
  class RetryTaskQuery (line 11) | @Data

FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/test/java/com/alibaba/easyretry/extension/mybatis/DbConfig.java
  class DbConfig (line 11) | public final class DbConfig {
    method test (line 29) | @Test

FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/test/java/com/alibaba/easyretry/extension/mybatis/MyBatisConfig.java
  class MyBatisConfig (line 17) | public final class MyBatisConfig {
    method testNotNull (line 39) | @Test

FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/test/java/com/alibaba/easyretry/extension/mybatis/access/MybatisRetryTaskAccessTest.java
  class MybatisRetryTaskAccessTest (line 19) | @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
    method prepare (line 28) | @BeforeAll
    method saveTask (line 39) | @Test
    method handle (line 45) | @Test
    method stop (line 55) | @Test
    method finish (line 65) | @Test

FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/test/java/com/alibaba/easyretry/extension/mybatis/common/utils/HostUtilsTest.java
  class HostUtilsTest (line 7) | class HostUtilsTest {
    method getHostIP (line 9) | @Test

FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/test/java/com/alibaba/easyretry/extension/mybatis/dao/RetryTaskDAOImplTest.java
  class RetryTaskDAOImplTest (line 18) | class RetryTaskDAOImplTest {
    method prepare (line 22) | @BeforeAll
    method saveTask (line 27) | @Test
    method listRetryTask (line 41) | @Test
    method updateRetryTask (line 61) | @Test
    method deleteRetryTask (line 80) | @Test

FILE: easy-retry-extensions/easy-retry-mybatis-extension/src/test/resources/task.sql
  type easy_retry_task (line 1) | CREATE TABLE IF NOT EXISTS easy_retry_task (

FILE: easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/RetryListenerInitialize.java
  class RetryListenerInitialize (line 18) | public class RetryListenerInitialize implements SmartInitializingSinglet...
    method afterSingletonsInstantiated (line 25) | @Override
    method setApplicationContext (line 32) | @Override

FILE: easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/SPELParamPredicate.java
  class SPELParamPredicate (line 17) | @Data
    method SPELParamPredicate (line 26) | public SPELParamPredicate(String bizIdCondition, Method method) {
    method SPELParamPredicate (line 31) | public SPELParamPredicate() {
    method apply (line 34) | @Override

FILE: easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/SPELResultPredicate.java
  class SPELResultPredicate (line 13) | @Data
    method SPELResultPredicate (line 18) | public SPELResultPredicate(String resultCondition) {
    method SPELResultPredicate (line 22) | public SPELResultPredicate() {
    method apply (line 25) | @Override

FILE: easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/SpringEventApplicationListener.java
  class SpringEventApplicationListener (line 13) | public class SpringEventApplicationListener implements SmartInitializing...
    method afterSingletonsInstantiated (line 22) | @Override

FILE: easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/SpringRetryFilterDiscover.java
  class SpringRetryFilterDiscover (line 18) | public class SpringRetryFilterDiscover implements RetryFilterDiscover, S...
    method discoverAll (line 25) | @Override
    method afterSingletonsInstantiated (line 30) | @Override
    method setApplicationContext (line 36) | @Override

FILE: easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/aop/RetryInterceptor.java
  class RetryInterceptor (line 20) | @Aspect
    method around (line 29) | @Around("@annotation(retryable)")
    method getBeanId (line 39) | private String getBeanId(Class<?> type) {
    method determineTargetRetryer (line 44) | private Retryer<Object> determineTargetRetryer(ProceedingJoinPoint inv...

FILE: easy-retry-starters/easy-retry-memory-starter/src/main/java/com/alibaba/easyretry/memory/MemoryAutoConfiguration.java
  class MemoryAutoConfiguration (line 23) | @Configuration
    method retryTaskAccess (line 32) | @Bean
    method retryContainer (line 38) | @Bean(initMethod = "start")
    method getMaxRetryTimes (line 47) | @Override

FILE: easy-retry-starters/easy-retry-memory-starter/src/main/java/com/alibaba/easyretry/memory/config/EasyRetryMemoryCompatibleProperties.java
  class EasyRetryMemoryCompatibleProperties (line 9) | @ConfigurationProperties(prefix = "spring.easyretry.memory")

FILE: easy-retry-starters/easy-retry-mybatis-starter/src/main/java/com/alibaba/easyretry/mybatis/MybatisAutoConfiguration.java
  class MybatisAutoConfiguration (line 32) | @Configuration
    method sqlSessionFactory (line 44) | @Bean("easyRetrySqlSessionFactory")
    method retryContainer (line 54) | @Bean(initMethod = "start")
    method retryTaskDAO (line 62) | @Bean
    method retryTaskAccess (line 68) | @Bean
    method getMaxRetryTimes (line 73) | @Override

FILE: easy-retry-starters/easy-retry-mybatis-starter/src/main/java/com/alibaba/easyretry/mybatis/conifg/EasyRetryMybatisProperties.java
  class EasyRetryMybatisProperties (line 9) | @ConfigurationProperties(prefix = "spring.easyretry.mybatis")

FILE: easy-retry-starters/easy-retry-starter-common/src/main/java/com/alibaba/easyretry/starter/common/CommonAutoConfiguration.java
  class CommonAutoConfiguration (line 42) | @Slf4j
    method configuration (line 47) | @Bean
    method retryInterceptor (line 101) | @Bean
    method defaultRetryExecutor (line 110) | @Bean
    method retryEventMulticaster (line 120) | @Bean
    method retryListenerInitialize (line 126) | @Bean
    method springRetryFilterDiscover (line 134) | @Bean
    method simpleRetryFilterRegister (line 140) | @Bean
    method retryInvocationHandler (line 146) | @Bean
    method retryFilterRegisterHandler (line 155) | @Bean
    method easyRetryApplicationListener (line 165) | @Bean
    method setApplicationContext (line 174) | @Override
    method getMaxRetryTimes (line 179) | public abstract Integer getMaxRetryTimes();
Condensed preview — 140 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (190K chars).
[
  {
    "path": ".editorconfig",
    "chars": 488,
    "preview": "root = true\n\n[*]\ncharset = utf-8\n\n[*.java]\nindent_style = tab\nindent_size = 4\nend_of_line = lf\ntrim_trailing_whitespace "
  },
  {
    "path": ".github/workflows/maven.yml",
    "chars": 631,
    "preview": "# This workflow will build a Java project with Maven\n# For more information see: https://help.github.com/actions/languag"
  },
  {
    "path": ".gitignore",
    "chars": 447,
    "preview": "# Compiled class file\n*.class\n*.classpath\n*.factorypath\n\n# Log file\n*.log\n\n# BlueJ files\n*.ctxt\n\n# Mobile Tools for Java"
  },
  {
    "path": "LICENSE",
    "chars": 1064,
    "preview": "MIT License\n\nCopyright (c) 2021 Alibaba\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof"
  },
  {
    "path": "README.md",
    "chars": 2129,
    "preview": "# Easy-Retry\n\n一种存储介质可扩展的持久化重试方案\n![img](img/readme/arch.jpg)\n\n### Getting started\n\n#### Memory Retry\n\n1. 增加pom依赖\n\n```xml\n"
  },
  {
    "path": "config/intellij-java-google-style.xml",
    "chars": 19654,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<code_scheme name=\"GoogleStyle\">\n\t<option name=\"OTHER_INDENT_OPTIONS\">\n\t\t<value>\n"
  },
  {
    "path": "easy-retry-common/pom.xml",
    "chars": 1006,
    "preview": "<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\t\t xmlns=\"http://maven.apache.org/POM/4.0.0\"\n\t\t xsi:schem"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/AbstractResultPredicate.java",
    "chars": 239,
    "preview": "package com.alibaba.easyretry.common;\n\n/**\n * @author Created by wuhao on 2021/3/26.\n */\npublic abstract class AbstractR"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/AbstractRetrySyncExecutor.java",
    "chars": 531,
    "preview": "package com.alibaba.easyretry.common;\n\nimport com.alibaba.easyretry.common.retryer.RetryerInfo;\n\n/**\n * @author zhangchi"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/EasyRetryPredicate.java",
    "chars": 208,
    "preview": "package com.alibaba.easyretry.common;\n\nimport java.io.Serializable;\n\n/**\n * @author Created by wuhao on 2021/3/18.\n */\np"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/Invocation.java",
    "chars": 158,
    "preview": "package com.alibaba.easyretry.common;\n\n/**\n * @author Created by wuhao on 2021/3/29.\n */\npublic interface Invocation {\n\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryConfiguration.java",
    "chars": 919,
    "preview": "package com.alibaba.easyretry.common;\n\nimport com.alibaba.easyretry.common.access.RetrySerializerAccess;\nimport com.alib"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryContainer.java",
    "chars": 149,
    "preview": "package com.alibaba.easyretry.common;\n\n/**\n * @author Created by wuhao on 2020/11/5.\n */\npublic interface RetryContainer"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryContext.java",
    "chars": 248,
    "preview": "package com.alibaba.easyretry.common;\n\npublic interface RetryContext extends RetryLifecycle {\n\n\tvoid setAttribute(String"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryExecutor.java",
    "chars": 245,
    "preview": "package com.alibaba.easyretry.common;\n\nimport com.alibaba.easyretry.common.constant.enums.HandleResultEnum;\n\n/**\n * @aut"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryIdentify.java",
    "chars": 551,
    "preview": "package com.alibaba.easyretry.common;\n\nimport java.util.Objects;\n\n/**\n * @author Created by wuhao on 2021/2/20.\n */\npubl"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryLifecycle.java",
    "chars": 156,
    "preview": "package com.alibaba.easyretry.common;\n\n/**\n * @author Created by wuhao on 2020/11/2.\n */\npublic interface RetryLifecycle"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetrySyncExecutor.java",
    "chars": 296,
    "preview": "package com.alibaba.easyretry.common;\n\nimport com.alibaba.easyretry.common.retryer.RetryerInfo;\n\n/**\n * @author zhangchi"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/SCallable.java",
    "chars": 224,
    "preview": "package com.alibaba.easyretry.common;\n\nimport java.io.Serializable;\n\n/**\n * @author Created by wuhao on 2020/11/5.\n */\n@"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/SimpleMethodInvocation.java",
    "chars": 680,
    "preview": "package com.alibaba.easyretry.common;\n\nimport java.lang.reflect.Method;\nimport java.util.Arrays;\n\nimport lombok.AllArgsC"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/access/RetrySerializerAccess.java",
    "chars": 381,
    "preview": "package com.alibaba.easyretry.common.access;\n\nimport com.alibaba.easyretry.common.serializer.RetryArgSerializer;\n\n/**\n *"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/access/RetryStrategyAccess.java",
    "chars": 446,
    "preview": "package com.alibaba.easyretry.common.access;\n\nimport com.alibaba.easyretry.common.strategy.StopStrategy;\nimport com.alib"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/access/RetryTaskAccess.java",
    "chars": 533,
    "preview": "package com.alibaba.easyretry.common.access;\n\nimport java.util.List;\n\nimport com.alibaba.easyretry.common.entity.RetryTa"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/constant/enums/HandleResultEnum.java",
    "chars": 304,
    "preview": "package com.alibaba.easyretry.common.constant.enums;\n\n/**\n * 重试任务重试结果\n *\n * @author Created by wuhao on 2020/11/1.\n */\np"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/constant/enums/RetryTaskStatusEnum.java",
    "chars": 822,
    "preview": "package com.alibaba.easyretry.common.constant.enums;\n\nimport java.util.Map;\nimport java.util.stream.Collectors;\nimport j"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/constant/enums/RetryTypeEnum.java",
    "chars": 203,
    "preview": "package com.alibaba.easyretry.common.constant.enums;\n\n/**\n * 重试种类\n *\n * @author Created by zhangchi on 2023-07-12\n */\npu"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/constant/package-info.java",
    "chars": 97,
    "preview": "/**\n * @author Created by wuhao on 2020/11/6.\n */\npackage com.alibaba.easyretry.common.constant;\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/entity/RetryTask.java",
    "chars": 733,
    "preview": "package com.alibaba.easyretry.common.entity;\n\nimport java.util.Date;\nimport java.util.Map;\n\nimport com.alibaba.easyretry"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/RetryEvent.java",
    "chars": 216,
    "preview": "package com.alibaba.easyretry.common.event;\n\n/**\n * @author Created by wuhao on 2021/3/25.\n */\npublic interface RetryEve"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/RetryEventMulticaster.java",
    "chars": 221,
    "preview": "package com.alibaba.easyretry.common.event;\n\n/**\n * @author Created by wuhao on 2021/3/26.\n */\npublic interface RetryEve"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/RetryListener.java",
    "chars": 183,
    "preview": "package com.alibaba.easyretry.common.event;\n\n/**\n * @author Created by wuhao on 2021/3/25.\n */\npublic interface RetryLis"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/before/AfterSaveBeforeRetryEvent.java",
    "chars": 306,
    "preview": "package com.alibaba.easyretry.common.event.before;\n\nimport com.alibaba.easyretry.common.entity.RetryTask;\n\n/**\n * @autho"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/before/BeforeRetryEvent.java",
    "chars": 850,
    "preview": "package com.alibaba.easyretry.common.event.before;\n\nimport java.util.Map;\nimport java.util.Objects;\n\nimport com.alibaba."
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/before/PrepSaveBeforeRetryEvent.java",
    "chars": 304,
    "preview": "package com.alibaba.easyretry.common.event.before;\n\nimport com.alibaba.easyretry.common.entity.RetryTask;\n\n/**\n * @autho"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/on/FailureOnRetryEvent.java",
    "chars": 292,
    "preview": "package com.alibaba.easyretry.common.event.on;\n\nimport com.alibaba.easyretry.common.RetryContext;\n\n/**\n * @author Create"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/on/OnRetryEvent.java",
    "chars": 739,
    "preview": "package com.alibaba.easyretry.common.event.on;\n\nimport com.alibaba.easyretry.common.RetryContext;\nimport com.alibaba.eas"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/on/StopOnRetryEvent.java",
    "chars": 286,
    "preview": "package com.alibaba.easyretry.common.event.on;\n\nimport com.alibaba.easyretry.common.RetryContext;\n\n/**\n * @author Create"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/on/SuccessOnRetryEvent.java",
    "chars": 292,
    "preview": "package com.alibaba.easyretry.common.event.on;\n\nimport com.alibaba.easyretry.common.RetryContext;\n\n/**\n * @author Create"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/AbstractRetryFilter.java",
    "chars": 271,
    "preview": "package com.alibaba.easyretry.common.filter;\n\n/**\n * @author Created by wuhao on 2021/3/22.\n */\npublic abstract class Ab"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilter.java",
    "chars": 291,
    "preview": "package com.alibaba.easyretry.common.filter;\n\nimport com.alibaba.easyretry.common.RetryContext;\n\n/**\n * @author Created "
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterDiscover.java",
    "chars": 195,
    "preview": "package com.alibaba.easyretry.common.filter;\n\nimport java.util.List;\n\n/**\n * @author Created by wuhao on 2021/4/9.\n */\np"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterInvocation.java",
    "chars": 265,
    "preview": "package com.alibaba.easyretry.common.filter;\n\nimport com.alibaba.easyretry.common.RetryContext;\n\n/**\n * @author Created "
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterInvocationHandler.java",
    "chars": 163,
    "preview": "package com.alibaba.easyretry.common.filter;\n\n/**\n * @author Created by wuhao on 2021/3/19.\n */\npublic interface RetryFi"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterRegister.java",
    "chars": 234,
    "preview": "package com.alibaba.easyretry.common.filter;\n\nimport java.util.List;\n\n/**\n * @author Created by wuhao on 2021/3/22.\n */\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterRegisterHandler.java",
    "chars": 161,
    "preview": "package com.alibaba.easyretry.common.filter;\n\n/**\n * @author Created by wuhao on 2021/4/9.\n */\npublic interface RetryFil"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterResponse.java",
    "chars": 188,
    "preview": "package com.alibaba.easyretry.common.filter;\n\nimport lombok.Data;\n\n/**\n * @author Created by wuhao on 2021/3/22.\n */\n@Da"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/processor/AsyncPersistenceProcessor.java",
    "chars": 259,
    "preview": "package com.alibaba.easyretry.common.processor;\n\n/**\n * @author Created by wuhao on 2021/3/19.\n */\npublic interface Asyn"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/processor/RetryProcessor.java",
    "chars": 154,
    "preview": "package com.alibaba.easyretry.common.processor;\n\n/**\n * @author Created by wuhao on 2021/3/19.\n */\npublic interface Retr"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/processor/SyncProcessor.java",
    "chars": 198,
    "preview": "package com.alibaba.easyretry.common.processor;\n\n/**\n * @author Created by zhangchi on 2023-07-12\n */\npublic interface S"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/resolve/ExecutorSolver.java",
    "chars": 173,
    "preview": "package com.alibaba.easyretry.common.resolve;\n\n/**\n * @author Created by wuhao on 2020/11/8.\n */\npublic interface Execut"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/retryer/Retryer.java",
    "chars": 228,
    "preview": "package com.alibaba.easyretry.common.retryer;\n\nimport com.alibaba.easyretry.common.SCallable;\n\n/**\n * @author Created by"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/retryer/RetryerInfo.java",
    "chars": 779,
    "preview": "package com.alibaba.easyretry.common.retryer;\n\nimport com.alibaba.easyretry.common.AbstractResultPredicate;\nimport com.a"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/ArgDeSerializerInfo.java",
    "chars": 190,
    "preview": "package com.alibaba.easyretry.common.serializer;\n\nimport lombok.Data;\n\n/**\n * @author Created by wuhao on 2020/11/1.\n */"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/ArgSerializerInfo.java",
    "chars": 331,
    "preview": "package com.alibaba.easyretry.common.serializer;\n\nimport lombok.Data;\n\n/**\n * @author Created by wuhao on 2020/11/1.\n */"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/EasyRetrySerializer.java",
    "chars": 215,
    "preview": "package com.alibaba.easyretry.common.serializer;\n\n/**\n * @author Created by wuhao on 2021/3/18.\n */\npublic interface Eas"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/ResultPredicateSerializer.java",
    "chars": 263,
    "preview": "package com.alibaba.easyretry.common.serializer;\n\nimport com.alibaba.easyretry.common.AbstractResultPredicate;\n\n/**\n * @"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/RetryArgSerializer.java",
    "chars": 160,
    "preview": "package com.alibaba.easyretry.common.serializer;\n\n/**\n * Retry 序列化器\n */\npublic interface RetryArgSerializer extends Easy"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/strategy/RetryStrategy.java",
    "chars": 220,
    "preview": "package com.alibaba.easyretry.common.strategy;\n\nimport com.alibaba.easyretry.common.RetryContext;\n\n/**\n * @author Create"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/strategy/StopStrategy.java",
    "chars": 249,
    "preview": "package com.alibaba.easyretry.common.strategy;\n\nimport com.alibaba.easyretry.common.RetryContext;\n\n/**\n * @author Create"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/strategy/WaitStrategy.java",
    "chars": 287,
    "preview": "package com.alibaba.easyretry.common.strategy;\n\nimport com.alibaba.easyretry.common.RetryContext;\n\n/**\n * @author Create"
  },
  {
    "path": "easy-retry-core/pom.xml",
    "chars": 1341,
    "preview": "<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\t\t xmlns=\"http://maven.apache.org/POM/4.0.0\"\n\t\t xsi:schem"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/DegradeAbleRetryExecutor.java",
    "chars": 775,
    "preview": "package com.alibaba.easyretry.core;\n\nimport com.alibaba.easyretry.common.RetryContext;\nimport com.alibaba.easyretry.comm"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/PersistenceRetryExecutor.java",
    "chars": 5708,
    "preview": "package com.alibaba.easyretry.core;\n\nimport java.lang.reflect.InvocationTargetException;\n\nimport com.alibaba.easyretry.c"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/PersistenceRetryer.java",
    "chars": 1479,
    "preview": "package com.alibaba.easyretry.core;\n\nimport com.alibaba.easyretry.common.SCallable;\nimport com.alibaba.easyretry.common."
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/PersistenceRetryerBuilder.java",
    "chars": 2513,
    "preview": "package com.alibaba.easyretry.core;\n\nimport com.alibaba.easyretry.common.AbstractResultPredicate;\nimport com.alibaba.eas"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/RetryerBuilder.java",
    "chars": 3121,
    "preview": "package com.alibaba.easyretry.core;\n\nimport com.alibaba.easyretry.common.AbstractResultPredicate;\nimport com.alibaba.eas"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/SyncRetryer.java",
    "chars": 845,
    "preview": "package com.alibaba.easyretry.core;\n\n\nimport com.alibaba.easyretry.common.AbstractRetrySyncExecutor;\nimport com.alibaba."
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/SyncRetryerBuilder.java",
    "chars": 867,
    "preview": "package com.alibaba.easyretry.core;\n\nimport java.util.Objects;\n\nimport com.alibaba.easyretry.common.RetryConfiguration;\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/access/DefaultRetrySerializerAccess.java",
    "chars": 499,
    "preview": "package com.alibaba.easyretry.core.access;\n\nimport com.alibaba.easyretry.common.access.RetrySerializerAccess;\nimport com"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/access/MemoryRetryTaskAccess.java",
    "chars": 1708,
    "preview": "package com.alibaba.easyretry.core.access;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ato"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/container/SimpleRetryContainer.java",
    "chars": 5468,
    "preview": "package com.alibaba.easyretry.core.container;\n\nimport java.util.List;\nimport java.util.concurrent.BlockingQueue;\nimport "
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/context/MaxAttemptsPersistenceRetryContext.java",
    "chars": 4957,
    "preview": "package com.alibaba.easyretry.core.context;\n\nimport java.lang.reflect.Method;\nimport java.util.Map;\nimport java.util.Obj"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/degrade/EasyRetryDegradeHelper.java",
    "chars": 321,
    "preview": "package com.alibaba.easyretry.core.degrade;\n\nimport com.alibaba.easyretry.common.RetryContext;\n\n/**\n * @author Created b"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/event/SimpleRetryEventMulticaster.java",
    "chars": 833,
    "preview": "package com.alibaba.easyretry.core.event;\n\nimport java.util.List;\nimport java.util.Objects;\n\nimport com.alibaba.easyretr"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/DefaultRetryFilterInvocationHandler.java",
    "chars": 1567,
    "preview": "package com.alibaba.easyretry.core.filter;\n\nimport java.util.List;\n\nimport com.alibaba.easyretry.common.RetryContext;\nim"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/DefaultRetryFilterRegisterHandler.java",
    "chars": 899,
    "preview": "package com.alibaba.easyretry.core.filter;\n\nimport java.util.List;\n\nimport com.alibaba.easyretry.common.filter.RetryFilt"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/IdentifyRetryFilter.java",
    "chars": 603,
    "preview": "package com.alibaba.easyretry.core.filter;\n\nimport com.alibaba.easyretry.common.RetryContext;\nimport com.alibaba.easyret"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/MethodExcuteRetryFilter.java",
    "chars": 659,
    "preview": "package com.alibaba.easyretry.core.filter;\n\nimport com.alibaba.easyretry.common.RetryContext;\nimport com.alibaba.easyret"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/NOOPRetryFilter.java",
    "chars": 471,
    "preview": "package com.alibaba.easyretry.core.filter;\n\nimport com.alibaba.easyretry.common.RetryContext;\nimport com.alibaba.easyret"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/SPIRetryFilterDiscover.java",
    "chars": 648,
    "preview": "package com.alibaba.easyretry.core.filter;\n\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.ServiceLo"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/SimpleRetryFilterRegister.java",
    "chars": 605,
    "preview": "package com.alibaba.easyretry.core.filter;\n\nimport java.util.List;\n\nimport com.alibaba.easyretry.common.filter.RetryFilt"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/AbstractAsyncPersistenceProcessor.java",
    "chars": 501,
    "preview": "package com.alibaba.easyretry.core.process.async;\n\nimport com.alibaba.easyretry.common.processor.AsyncPersistenceProcess"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/before/AbstractAsyncPersistenceBeforeRetryProcessor.java",
    "chars": 2892,
    "preview": "package com.alibaba.easyretry.core.process.async.before;\n\nimport java.util.Date;\nimport java.util.Map;\nimport java.util."
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/before/ExceptionPersistenceAsyncBeforeRetryProcessor.java",
    "chars": 1021,
    "preview": "package com.alibaba.easyretry.core.process.async.before;\n\nimport java.util.Objects;\n\nimport com.alibaba.easyretry.common"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/before/ResultAsynPersistenceBeforeRetryProcessor.java",
    "chars": 848,
    "preview": "package com.alibaba.easyretry.core.process.async.before;\n\nimport java.util.Objects;\n\nimport com.alibaba.easyretry.common"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/on/AbstractAsyncPersistenceOnRetryProcessor.java",
    "chars": 1275,
    "preview": "package com.alibaba.easyretry.core.process.async.on;\n\nimport com.alibaba.easyretry.common.constant.enums.HandleResultEnu"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/on/ExceptionPersistenceAsynOnRetryProcessor.java",
    "chars": 629,
    "preview": "package com.alibaba.easyretry.core.process.async.on;\n\nimport com.alibaba.easyretry.core.context.MaxAttemptsPersistenceRe"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/on/ResultAsynPersistenceOnRetryProcessor.java",
    "chars": 1027,
    "preview": "package com.alibaba.easyretry.core.process.async.on;\n\nimport com.alibaba.easyretry.common.AbstractResultPredicate;\nimpor"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/package-info.java",
    "chars": 94,
    "preview": "/**\n * @author Created by wuhao on 2021/3/19.\n */\npackage com.alibaba.easyretry.core.process;\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/serializer/FastJsonRetryArgSerializer.java",
    "chars": 1480,
    "preview": "package com.alibaba.easyretry.core.serializer;\n\nimport java.util.stream.Stream;\n\nimport com.alibaba.easyretry.common.ser"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/serializer/HessianResultPredicateSerializer.java",
    "chars": 686,
    "preview": "package com.alibaba.easyretry.core.serializer;\n\nimport com.alibaba.easyretry.common.AbstractResultPredicate;\nimport com."
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/serializer/HessianRetryArgSerializer.java",
    "chars": 950,
    "preview": "package com.alibaba.easyretry.core.serializer;\n\n/**\n * @author Created by wuhao on 2021/2/22.\n */\n\nimport com.alibaba.ea"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/strategy/DefaultRetryStrategy.java",
    "chars": 2900,
    "preview": "package com.alibaba.easyretry.core.strategy;\n\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.concurren"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/utils/HessianSerializerUtils.java",
    "chars": 1119,
    "preview": "package com.alibaba.easyretry.core.utils;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nim"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/utils/LogUtils.java",
    "chars": 274,
    "preview": "package com.alibaba.easyretry.core.utils;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * @author Crea"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/utils/PrintUtils.java",
    "chars": 526,
    "preview": "package com.alibaba.easyretry.core.utils;\n\nimport com.alibaba.easyretry.common.RetryContext;\n\nimport lombok.extern.slf4j"
  },
  {
    "path": "easy-retry-core/src/test/java/com/alibaba/easyretry/core/utils/TestClass.java",
    "chars": 116,
    "preview": "package com.alibaba.easyretry.core.utils;\n\nclass TestClass {\n\n\tpublic void say() {\n\t\tSystem.out.println(\"1\");\n\t}\n\n}\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-guava-extension/pom.xml",
    "chars": 1104,
    "preview": "<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\t\t xmlns=\"http://maven.apache.org/POM/4.0.0\"\n\t\t xsi:schem"
  },
  {
    "path": "easy-retry-extensions/easy-retry-guava-extension/src/main/java/com/alibaba/easyretry/extension/guava/GuavaRetrySyncExecutor.java",
    "chars": 1609,
    "preview": "package com.alibaba.easyretry.extension.guava;\n\nimport java.util.Objects;\nimport java.util.concurrent.TimeUnit;\n\nimport "
  },
  {
    "path": "easy-retry-extensions/easy-retry-guava-extension/src/main/java/com/alibaba/easyretry/extension/guava/package-info.java",
    "chars": 47,
    "preview": "package com.alibaba.easyretry.extension.guava;\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/pom.xml",
    "chars": 1799,
    "preview": "<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\t\t xmlns=\"http://maven.apache.org/POM/4.0.0\"\n\t\t xsi:schem"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/access/MybatisRetryTaskAccess.java",
    "chars": 4168,
    "preview": "package com.alibaba.easyretry.extension.mybatis.access;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.O"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/common/utils/HostUtils.java",
    "chars": 524,
    "preview": "package com.alibaba.easyretry.extension.mybatis.common.utils;\n\nimport java.net.InetAddress;\nimport java.net.UnknownHostE"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/dao/BaseDAOSupport.java",
    "chars": 993,
    "preview": "package com.alibaba.easyretry.extension.mybatis.dao;\n\nimport java.util.Objects;\nimport java.util.function.Function;\n\nimp"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/dao/RetryTaskDAO.java",
    "chars": 515,
    "preview": "package com.alibaba.easyretry.extension.mybatis.dao;\n\nimport java.util.List;\n\nimport com.alibaba.easyretry.extension.myb"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/dao/RetryTaskDAOImpl.java",
    "chars": 1491,
    "preview": "package com.alibaba.easyretry.extension.mybatis.dao;\n\nimport java.util.List;\n\nimport com.alibaba.easyretry.extension.myb"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/po/RetryTaskPO.java",
    "chars": 731,
    "preview": "package com.alibaba.easyretry.extension.mybatis.po;\n\nimport java.util.Date;\n\nimport com.alibaba.easyretry.common.constan"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/query/RetryTaskQuery.java",
    "chars": 339,
    "preview": "package com.alibaba.easyretry.extension.mybatis.query;\n\nimport java.util.List;\n\nimport lombok.Data;\nimport lombok.experi"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/main/resources/dal/easyretry/easy-mybatis-config.xml",
    "chars": 589,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE configuration\n\tPUBLIC \"-//mybatis.org//DTD Config 3.0//EN\"\n\t\"http://myb"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/main/resources/dal/easyretry/mapper/easy-retry-task-mapper.xml",
    "chars": 2534,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\"\n\t\"http://mybatis.org"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/test/java/com/alibaba/easyretry/extension/mybatis/DbConfig.java",
    "chars": 937,
    "preview": "package com.alibaba.easyretry.extension.mybatis;\n\nimport javax.sql.DataSource;\n\nimport com.zaxxer.hikari.HikariConfig;\ni"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/test/java/com/alibaba/easyretry/extension/mybatis/MyBatisConfig.java",
    "chars": 1341,
    "preview": "package com.alibaba.easyretry.extension.mybatis;\n\nimport java.io.IOException;\n\nimport lombok.Getter;\nimport org.apache.i"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/test/java/com/alibaba/easyretry/extension/mybatis/access/MybatisRetryTaskAccessTest.java",
    "chars": 2167,
    "preview": "package com.alibaba.easyretry.extension.mybatis.access;\n\nimport java.util.Date;\nimport java.util.List;\nimport java.util."
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/test/java/com/alibaba/easyretry/extension/mybatis/common/utils/HostUtilsTest.java",
    "chars": 283,
    "preview": "package com.alibaba.easyretry.extension.mybatis.common.utils;\n\nimport org.junit.jupiter.api.Test;\n\nimport static org.jun"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/test/java/com/alibaba/easyretry/extension/mybatis/dao/RetryTaskDAOImplTest.java",
    "chars": 3263,
    "preview": "package com.alibaba.easyretry.extension.mybatis.dao;\n\nimport java.util.Collections;\nimport java.util.Date;\nimport java.u"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/test/resources/logback.xml",
    "chars": 326,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration>\n\n\t<appender name=\"CONSOLE\" class=\"ch.qos.logback.core.ConsoleAppe"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/test/resources/task.sql",
    "chars": 575,
    "preview": "CREATE TABLE IF NOT EXISTS easy_retry_task (\n    id bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键' PRIMARY KEY,\n  "
  },
  {
    "path": "easy-retry-extensions/easy-retry-spring-extension/pom.xml",
    "chars": 1404,
    "preview": "<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\t\t xmlns=\"http://maven.apache.org/POM/4.0.0\"\n\t\t xsi:schem"
  },
  {
    "path": "easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/RetryListenerInitialize.java",
    "chars": 1221,
    "preview": "package com.alibaba.easyretry.extension.spring;\n\nimport java.util.Map;\n\nimport com.alibaba.easyretry.common.event.RetryE"
  },
  {
    "path": "easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/SPELParamPredicate.java",
    "chars": 1439,
    "preview": "package com.alibaba.easyretry.extension.spring;\n\nimport java.lang.reflect.Method;\n\nimport com.alibaba.easyretry.common.E"
  },
  {
    "path": "easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/SPELResultPredicate.java",
    "chars": 941,
    "preview": "package com.alibaba.easyretry.extension.spring;\n\nimport com.alibaba.easyretry.common.AbstractResultPredicate;\n\nimport lo"
  },
  {
    "path": "easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/SpringEventApplicationListener.java",
    "chars": 715,
    "preview": "package com.alibaba.easyretry.extension.spring;\n\nimport org.springframework.beans.factory.SmartInitializingSingleton;\n\ni"
  },
  {
    "path": "easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/SpringRetryFilterDiscover.java",
    "chars": 1219,
    "preview": "package com.alibaba.easyretry.extension.spring;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport com.alibaba.easyre"
  },
  {
    "path": "easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/aop/EasyRetryable.java",
    "chars": 625,
    "preview": "package com.alibaba.easyretry.extension.spring.aop;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotatio"
  },
  {
    "path": "easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/aop/RetryInterceptor.java",
    "chars": 2063,
    "preview": "package com.alibaba.easyretry.extension.spring.aop;\n\nimport java.lang.reflect.Method;\nimport java.util.Objects;\n\nimport "
  },
  {
    "path": "easy-retry-extensions/pom.xml",
    "chars": 789,
    "preview": "<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\t\t xmlns=\"http://maven.apache.org/POM/4.0.0\"\n\t\t xsi:schem"
  },
  {
    "path": "easy-retry-starters/easy-retry-memory-starter/pom.xml",
    "chars": 1117,
    "preview": "<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\t\t xmlns=\"http://maven.apache.org/POM/4.0.0\"\n\t\t xsi:schem"
  },
  {
    "path": "easy-retry-starters/easy-retry-memory-starter/src/main/java/com/alibaba/easyretry/memory/MemoryAutoConfiguration.java",
    "chars": 1973,
    "preview": "package com.alibaba.easyretry.memory;\n\nimport com.alibaba.easyretry.common.RetryConfiguration;\nimport com.alibaba.easyre"
  },
  {
    "path": "easy-retry-starters/easy-retry-memory-starter/src/main/java/com/alibaba/easyretry/memory/config/EasyRetryMemoryCompatibleProperties.java",
    "chars": 393,
    "preview": "package com.alibaba.easyretry.memory.config;\n\nimport lombok.Data;\nimport org.springframework.boot.context.properties.Con"
  },
  {
    "path": "easy-retry-starters/easy-retry-memory-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json",
    "chars": 303,
    "preview": "{\n\t\"properties\": [\n\t\t{\n\t\t\t\"name\": \"spring.easyretry.memory.enabled\",\n\t\t\t\"type\": \"java.lang.Boolean\",\n\t\t\t\"description\": \""
  },
  {
    "path": "easy-retry-starters/easy-retry-memory-starter/src/main/resources/META-INF/spring.factories",
    "chars": 117,
    "preview": "org.springframework.boot.autoconfigure.EnableAutoConfiguration=\\\ncom.alibaba.easyretry.memory.MemoryAutoConfiguration"
  },
  {
    "path": "easy-retry-starters/easy-retry-mybatis-starter/pom.xml",
    "chars": 1532,
    "preview": "<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\t\t xmlns=\"http://maven.apache.org/POM/4.0.0\"\n\t\t xsi:schem"
  },
  {
    "path": "easy-retry-starters/easy-retry-mybatis-starter/src/main/java/com/alibaba/easyretry/mybatis/MybatisAutoConfiguration.java",
    "chars": 3057,
    "preview": "package com.alibaba.easyretry.mybatis;\n\nimport com.alibaba.easyretry.common.RetryConfiguration;\nimport com.alibaba.easyr"
  },
  {
    "path": "easy-retry-starters/easy-retry-mybatis-starter/src/main/java/com/alibaba/easyretry/mybatis/conifg/EasyRetryMybatisProperties.java",
    "chars": 344,
    "preview": "package com.alibaba.easyretry.mybatis.conifg;\n\nimport lombok.Data;\nimport org.springframework.boot.context.properties.Co"
  },
  {
    "path": "easy-retry-starters/easy-retry-mybatis-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json",
    "chars": 305,
    "preview": "{\n\t\"properties\": [\n\t\t{\n\t\t\t\"name\": \"spring.easyretry.mybatis.enabled\",\n\t\t\t\"type\": \"java.lang.Boolean\",\n\t\t\t\"description\": "
  },
  {
    "path": "easy-retry-starters/easy-retry-mybatis-starter/src/main/resources/META-INF/spring.factories",
    "chars": 119,
    "preview": "org.springframework.boot.autoconfigure.EnableAutoConfiguration=\\\ncom.alibaba.easyretry.mybatis.MybatisAutoConfiguration"
  },
  {
    "path": "easy-retry-starters/easy-retry-starter-common/pom.xml",
    "chars": 1107,
    "preview": "<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\t\t xmlns=\"http://maven.apache.org/POM/4.0.0\"\n\t\t xsi:schem"
  },
  {
    "path": "easy-retry-starters/easy-retry-starter-common/src/main/java/com/alibaba/easyretry/starter/common/CommonAutoConfiguration.java",
    "chars": 7241,
    "preview": "package com.alibaba.easyretry.starter.common;\n\nimport org.springframework.beans.BeansException;\nimport org.springframewo"
  },
  {
    "path": "easy-retry-starters/pom.xml",
    "chars": 993,
    "preview": "<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\t\t xmlns=\"http://maven.apache.org/POM/4.0.0\"\n\t\t xsi:schem"
  },
  {
    "path": "pom.xml",
    "chars": 7271,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\t\t xmlns=\"http://m"
  }
]

About this extraction

This page contains the full source code of the alibaba/easy-retry GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 140 files (152.9 KB), approximately 46.2k tokens, and a symbol index with 390 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!