[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\ncharset = utf-8\n\n[*.java]\nindent_style = tab\nindent_size = 4\nend_of_line = lf\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[*.{json, yml, xml}]\nindent_style = tab\nindent_size = 4\n\n[*.md]\ninsert_final_newline = false\ntrim_trailing_whitespace = false\n\n[*.properties]\nij_properties_align_group_field_declarations = false\nij_properties_keep_blank_lines = false\nij_properties_key_value_delimiter = equals\nij_properties_spaces_around_key_value_delimiter = false"
  },
  {
    "path": ".github/workflows/maven.yml",
    "content": "# This workflow will build a Java project with Maven\n# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven\n\nname: Java CI with Maven\n\non:\n    push:\n        branches: [ main ]\n    pull_request:\n        branches: [ main ]\n\n\njobs:\n    build:\n        runs-on: ubuntu-latest\n        steps:\n            -   uses: actions/checkout@v2\n            -   name: Set up JDK 1.8\n                uses: actions/setup-java@v1\n                with:\n                    java-version: 1.8\n            -   name: Build with Maven\n                run: mvn -B package --file pom.xml\n"
  },
  {
    "path": ".gitignore",
    "content": "# 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 (J2ME)\n.mtj.tmp/\n\n# Package Files #\n*.jar\n*.war\n*.ear\n*.zip\n*.tar.gz\n*.rar\n\n# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml\nhs_err_pid*\n\n# IDE Files #\n*.iml\n.idea\n.idea/\n.project\n.settings\ntarget\n.DS_Store\n\n# temp ignore\n*.cache\n*.diff\n*.patch\n*.tmp\n\n# Maven ignore\n.flattened-pom.xml\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2021 Alibaba\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# 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<dependency>\n    <groupId>com.alibaba</groupId>\n    <artifactId>easy-retry-memory-starter</artifactId>\n    <version>${last-version}</version>\n</dependency>\n```\n\n2. 在application.properties增加配置\n\n`spring.easyretry.memory.enabled = true`\n\n3. 在需要重试的方法上增加`@EasyRetryable`注解\n\n```java\npublic class MemoryUserService {\n    @EasyRetryable\n    public User getUserById(Long userId){\n        return new User();\n    }\n}\n```\n\n#### Mybatis Retry\n\n1. 增加pom依赖\n```xml\n<dependency>\n    <groupId>com.alibaba</groupId>\n    <artifactId>easy-retry-mybatis-starter</artifactId>\n    <version>${last-version}</version>\n</dependency>\n```\n\n2. 在application.properties增加配置\n\n`spring.easyretry.mybatis.enabled = true`\n\n3. 声明`javax.sql.DataSource`的`Bean`实例，参考下面例子（以`druid`连接池为例）\n```\n@Bean(name = \"easyRetryMybatisDataSource\", initMethod = \"init\", destroyMethod = \"close\")\npublic DataSource easyRetryMybatisDataSource() {\n    DruidDataSource tds = new DruidDataSource();\n    tds.setUrl(\"\");\n    tds.setUsername(\"\");\n    tds.setPassword(\"\");\n    ...\n    return tds;\n}\n```\n\n4. 新增持久化表\n\n```\nCREATE TABLE `easy_retry_task` (\n  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',\n  `gmt_create` datetime NOT NULL COMMENT '创建时间',\n  `gmt_modified` datetime NOT NULL COMMENT '修改时间',\n  `sharding` varchar(64) DEFAULT NULL COMMENT '数据库分片字段',\n  `biz_id` varchar(64) DEFAULT NULL COMMENT '业务id',\n  `executor_name` varchar(512) NOT NULL COMMENT '执行名称',\n  `executor_method_name` varchar(512) NOT NULL COMMENT '执行方法名称',\n  `retry_status` tinyint(4) NOT NULL COMMENT '重试状态',\n  `args_str` varchar(7168) DEFAULT NULL COMMENT '执行方法参数',\n  `ext_attrs` varchar(3000) DEFAULT NULL COMMENT '扩展字段',\n  PRIMARY KEY (`id`)\n) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COMMENT='easy_retry_task'\n;\n```\n\n5. 在需要重试的方法上增加@EasyRetryable注解\n\n```java\npublic class MybatisUserService {\n    @EasyRetryable\n    public User getUserById(Long userId){\n        return new User();\n    }\n}\n```\n\n### Built With\n\n• JDK1.8\n\n• Spring Framework5+\n\n• Spring Boot2.4+\n\n• Maven3.0\n"
  },
  {
    "path": "config/intellij-java-google-style.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<code_scheme name=\"GoogleStyle\">\n\t<option name=\"OTHER_INDENT_OPTIONS\">\n\t\t<value>\n\t\t\t<option name=\"INDENT_SIZE\" value=\"2\"/>\n\t\t\t<option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\"/>\n\t\t\t<option name=\"TAB_SIZE\" value=\"2\"/>\n\t\t\t<option name=\"USE_TAB_CHARACTER\" value=\"false\"/>\n\t\t\t<option name=\"SMART_TABS\" value=\"false\"/>\n\t\t\t<option name=\"LABEL_INDENT_SIZE\" value=\"0\"/>\n\t\t\t<option name=\"LABEL_INDENT_ABSOLUTE\" value=\"false\"/>\n\t\t\t<option name=\"USE_RELATIVE_INDENTS\" value=\"false\"/>\n\t\t</value>\n\t</option>\n\t<option name=\"INSERT_INNER_CLASS_IMPORTS\" value=\"true\"/>\n\t<option name=\"CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND\" value=\"999\"/>\n\t<option name=\"NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND\" value=\"999\"/>\n\t<option name=\"PACKAGES_TO_USE_IMPORT_ON_DEMAND\">\n\t\t<value/>\n\t</option>\n\t<option name=\"IMPORT_LAYOUT_TABLE\">\n\t\t<value>\n\t\t\t<package name=\"\" static=\"true\" withSubpackages=\"true\"/>\n\t\t\t<emptyLine/>\n\t\t\t<package name=\"\" static=\"false\" withSubpackages=\"true\"/>\n\t\t</value>\n\t</option>\n\t<option name=\"RIGHT_MARGIN\" value=\"100\"/>\n\t<option name=\"JD_ALIGN_PARAM_COMMENTS\" value=\"false\"/>\n\t<option name=\"JD_ALIGN_EXCEPTION_COMMENTS\" value=\"false\"/>\n\t<option name=\"JD_P_AT_EMPTY_LINES\" value=\"false\"/>\n\t<option name=\"JD_KEEP_EMPTY_PARAMETER\" value=\"false\"/>\n\t<option name=\"JD_KEEP_EMPTY_EXCEPTION\" value=\"false\"/>\n\t<option name=\"JD_KEEP_EMPTY_RETURN\" value=\"false\"/>\n\t<option name=\"KEEP_CONTROL_STATEMENT_IN_ONE_LINE\" value=\"false\"/>\n\t<option name=\"KEEP_BLANK_LINES_BEFORE_RBRACE\" value=\"0\"/>\n\t<option name=\"KEEP_BLANK_LINES_IN_CODE\" value=\"1\"/>\n\t<option name=\"BLANK_LINES_AFTER_CLASS_HEADER\" value=\"0\"/>\n\t<option name=\"ALIGN_MULTILINE_PARAMETERS\" value=\"false\"/>\n\t<option name=\"ALIGN_MULTILINE_FOR\" value=\"false\"/>\n\t<option name=\"CALL_PARAMETERS_WRAP\" value=\"1\"/>\n\t<option name=\"METHOD_PARAMETERS_WRAP\" value=\"1\"/>\n\t<option name=\"EXTENDS_LIST_WRAP\" value=\"1\"/>\n\t<option name=\"THROWS_KEYWORD_WRAP\" value=\"1\"/>\n\t<option name=\"METHOD_CALL_CHAIN_WRAP\" value=\"1\"/>\n\t<option name=\"BINARY_OPERATION_WRAP\" value=\"1\"/>\n\t<option name=\"BINARY_OPERATION_SIGN_ON_NEXT_LINE\" value=\"true\"/>\n\t<option name=\"TERNARY_OPERATION_WRAP\" value=\"1\"/>\n\t<option name=\"TERNARY_OPERATION_SIGNS_ON_NEXT_LINE\" value=\"true\"/>\n\t<option name=\"FOR_STATEMENT_WRAP\" value=\"1\"/>\n\t<option name=\"ARRAY_INITIALIZER_WRAP\" value=\"1\"/>\n\t<option name=\"WRAP_COMMENTS\" value=\"true\"/>\n\t<option name=\"IF_BRACE_FORCE\" value=\"3\"/>\n\t<option name=\"DOWHILE_BRACE_FORCE\" value=\"3\"/>\n\t<option name=\"WHILE_BRACE_FORCE\" value=\"3\"/>\n\t<option name=\"FOR_BRACE_FORCE\" value=\"3\"/>\n\t<option name=\"SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE\" value=\"true\"/>\n\t<AndroidXmlCodeStyleSettings>\n\t\t<option name=\"USE_CUSTOM_SETTINGS\" value=\"true\"/>\n\t\t<option name=\"LAYOUT_SETTINGS\">\n\t\t\t<value>\n\t\t\t\t<option name=\"INSERT_BLANK_LINE_BEFORE_TAG\" value=\"false\"/>\n\t\t\t</value>\n\t\t</option>\n\t</AndroidXmlCodeStyleSettings>\n\t<JSCodeStyleSettings>\n\t\t<option name=\"INDENT_CHAINED_CALLS\" value=\"false\"/>\n\t</JSCodeStyleSettings>\n\t<Python>\n\t\t<option name=\"USE_CONTINUATION_INDENT_FOR_ARGUMENTS\" value=\"true\"/>\n\t</Python>\n\t<TypeScriptCodeStyleSettings>\n\t\t<option name=\"INDENT_CHAINED_CALLS\" value=\"false\"/>\n\t</TypeScriptCodeStyleSettings>\n\t<XML>\n\t\t<option name=\"XML_ALIGN_ATTRIBUTES\" value=\"false\"/>\n\t\t<option name=\"XML_LEGACY_SETTINGS_IMPORTED\" value=\"true\"/>\n\t</XML>\n\t<codeStyleSettings language=\"CSS\">\n\t\t<indentOptions>\n\t\t\t<option name=\"INDENT_SIZE\" value=\"2\"/>\n\t\t\t<option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\"/>\n\t\t\t<option name=\"TAB_SIZE\" value=\"2\"/>\n\t\t</indentOptions>\n\t</codeStyleSettings>\n\t<codeStyleSettings language=\"ECMA Script Level 4\">\n\t\t<option name=\"KEEP_BLANK_LINES_IN_CODE\" value=\"1\"/>\n\t\t<option name=\"ALIGN_MULTILINE_PARAMETERS\" value=\"false\"/>\n\t\t<option name=\"ALIGN_MULTILINE_FOR\" value=\"false\"/>\n\t\t<option name=\"CALL_PARAMETERS_WRAP\" value=\"1\"/>\n\t\t<option name=\"METHOD_PARAMETERS_WRAP\" value=\"1\"/>\n\t\t<option name=\"EXTENDS_LIST_WRAP\" value=\"1\"/>\n\t\t<option name=\"BINARY_OPERATION_WRAP\" value=\"1\"/>\n\t\t<option name=\"BINARY_OPERATION_SIGN_ON_NEXT_LINE\" value=\"true\"/>\n\t\t<option name=\"TERNARY_OPERATION_WRAP\" value=\"1\"/>\n\t\t<option name=\"TERNARY_OPERATION_SIGNS_ON_NEXT_LINE\" value=\"true\"/>\n\t\t<option name=\"FOR_STATEMENT_WRAP\" value=\"1\"/>\n\t\t<option name=\"ARRAY_INITIALIZER_WRAP\" value=\"1\"/>\n\t\t<option name=\"IF_BRACE_FORCE\" value=\"3\"/>\n\t\t<option name=\"DOWHILE_BRACE_FORCE\" value=\"3\"/>\n\t\t<option name=\"WHILE_BRACE_FORCE\" value=\"3\"/>\n\t\t<option name=\"FOR_BRACE_FORCE\" value=\"3\"/>\n\t\t<option name=\"PARENT_SETTINGS_INSTALLED\" value=\"true\"/>\n\t</codeStyleSettings>\n\t<codeStyleSettings language=\"HTML\">\n\t\t<indentOptions>\n\t\t\t<option name=\"INDENT_SIZE\" value=\"2\"/>\n\t\t\t<option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\"/>\n\t\t\t<option name=\"TAB_SIZE\" value=\"2\"/>\n\t\t</indentOptions>\n\t</codeStyleSettings>\n\t<codeStyleSettings language=\"JAVA\">\n\t\t<option name=\"KEEP_CONTROL_STATEMENT_IN_ONE_LINE\" value=\"false\"/>\n\t\t<option name=\"KEEP_BLANK_LINES_IN_CODE\" value=\"1\"/>\n\t\t<option name=\"BLANK_LINES_AFTER_CLASS_HEADER\" value=\"1\"/>\n\t\t<option name=\"ALIGN_MULTILINE_PARAMETERS\" value=\"false\"/>\n\t\t<option name=\"ALIGN_MULTILINE_RESOURCES\" value=\"false\"/>\n\t\t<option name=\"ALIGN_MULTILINE_FOR\" value=\"false\"/>\n\t\t<option name=\"CALL_PARAMETERS_WRAP\" value=\"1\"/>\n\t\t<option name=\"METHOD_PARAMETERS_WRAP\" value=\"1\"/>\n\t\t<option name=\"EXTENDS_LIST_WRAP\" value=\"1\"/>\n\t\t<option name=\"THROWS_KEYWORD_WRAP\" value=\"1\"/>\n\t\t<option name=\"METHOD_CALL_CHAIN_WRAP\" value=\"1\"/>\n\t\t<option name=\"BINARY_OPERATION_WRAP\" value=\"1\"/>\n\t\t<option name=\"BINARY_OPERATION_SIGN_ON_NEXT_LINE\" value=\"true\"/>\n\t\t<option name=\"TERNARY_OPERATION_WRAP\" value=\"1\"/>\n\t\t<option name=\"TERNARY_OPERATION_SIGNS_ON_NEXT_LINE\" value=\"true\"/>\n\t\t<option name=\"FOR_STATEMENT_WRAP\" value=\"1\"/>\n\t\t<option name=\"ARRAY_INITIALIZER_WRAP\" value=\"1\"/>\n\t\t<option name=\"WRAP_COMMENTS\" value=\"true\"/>\n\t\t<option name=\"IF_BRACE_FORCE\" value=\"3\"/>\n\t\t<option name=\"DOWHILE_BRACE_FORCE\" value=\"3\"/>\n\t\t<option name=\"WHILE_BRACE_FORCE\" value=\"3\"/>\n\t\t<option name=\"FOR_BRACE_FORCE\" value=\"3\"/>\n\t\t<option name=\"PARENT_SETTINGS_INSTALLED\" value=\"true\"/>\n\t\t<indentOptions>\n\t\t\t<option name=\"INDENT_SIZE\" value=\"2\"/>\n\t\t\t<option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\"/>\n\t\t\t<option name=\"TAB_SIZE\" value=\"2\"/>\n\t\t</indentOptions>\n\t</codeStyleSettings>\n\t<codeStyleSettings language=\"JSON\">\n\t\t<indentOptions>\n\t\t\t<option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\"/>\n\t\t\t<option name=\"TAB_SIZE\" value=\"2\"/>\n\t\t</indentOptions>\n\t</codeStyleSettings>\n\t<codeStyleSettings language=\"JavaScript\">\n\t\t<option name=\"RIGHT_MARGIN\" value=\"80\"/>\n\t\t<option name=\"KEEP_BLANK_LINES_IN_CODE\" value=\"1\"/>\n\t\t<option name=\"ALIGN_MULTILINE_PARAMETERS\" value=\"false\"/>\n\t\t<option name=\"ALIGN_MULTILINE_FOR\" value=\"false\"/>\n\t\t<option name=\"CALL_PARAMETERS_WRAP\" value=\"1\"/>\n\t\t<option name=\"METHOD_PARAMETERS_WRAP\" value=\"1\"/>\n\t\t<option name=\"BINARY_OPERATION_WRAP\" value=\"1\"/>\n\t\t<option name=\"BINARY_OPERATION_SIGN_ON_NEXT_LINE\" value=\"true\"/>\n\t\t<option name=\"TERNARY_OPERATION_WRAP\" value=\"1\"/>\n\t\t<option name=\"TERNARY_OPERATION_SIGNS_ON_NEXT_LINE\" value=\"true\"/>\n\t\t<option name=\"FOR_STATEMENT_WRAP\" value=\"1\"/>\n\t\t<option name=\"ARRAY_INITIALIZER_WRAP\" value=\"1\"/>\n\t\t<option name=\"IF_BRACE_FORCE\" value=\"3\"/>\n\t\t<option name=\"DOWHILE_BRACE_FORCE\" value=\"3\"/>\n\t\t<option name=\"WHILE_BRACE_FORCE\" value=\"3\"/>\n\t\t<option name=\"FOR_BRACE_FORCE\" value=\"3\"/>\n\t\t<option name=\"PARENT_SETTINGS_INSTALLED\" value=\"true\"/>\n\t\t<indentOptions>\n\t\t\t<option name=\"INDENT_SIZE\" value=\"2\"/>\n\t\t\t<option name=\"TAB_SIZE\" value=\"2\"/>\n\t\t</indentOptions>\n\t</codeStyleSettings>\n\t<codeStyleSettings language=\"PROTO\">\n\t\t<option name=\"RIGHT_MARGIN\" value=\"80\"/>\n\t\t<indentOptions>\n\t\t\t<option name=\"INDENT_SIZE\" value=\"2\"/>\n\t\t\t<option name=\"CONTINUATION_INDENT_SIZE\" value=\"2\"/>\n\t\t\t<option name=\"TAB_SIZE\" value=\"2\"/>\n\t\t</indentOptions>\n\t</codeStyleSettings>\n\t<codeStyleSettings language=\"protobuf\">\n\t\t<option name=\"RIGHT_MARGIN\" value=\"80\"/>\n\t\t<indentOptions>\n\t\t\t<option name=\"INDENT_SIZE\" value=\"2\"/>\n\t\t\t<option name=\"CONTINUATION_INDENT_SIZE\" value=\"2\"/>\n\t\t\t<option name=\"TAB_SIZE\" value=\"2\"/>\n\t\t</indentOptions>\n\t</codeStyleSettings>\n\t<codeStyleSettings language=\"Python\">\n\t\t<option name=\"KEEP_BLANK_LINES_IN_CODE\" value=\"1\"/>\n\t\t<option name=\"RIGHT_MARGIN\" value=\"80\"/>\n\t\t<option name=\"ALIGN_MULTILINE_PARAMETERS\" value=\"false\"/>\n\t\t<option name=\"PARENT_SETTINGS_INSTALLED\" value=\"true\"/>\n\t\t<indentOptions>\n\t\t\t<option name=\"INDENT_SIZE\" value=\"2\"/>\n\t\t\t<option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\"/>\n\t\t\t<option name=\"TAB_SIZE\" value=\"2\"/>\n\t\t</indentOptions>\n\t</codeStyleSettings>\n\t<codeStyleSettings language=\"SASS\">\n\t\t<indentOptions>\n\t\t\t<option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\"/>\n\t\t\t<option name=\"TAB_SIZE\" value=\"2\"/>\n\t\t</indentOptions>\n\t</codeStyleSettings>\n\t<codeStyleSettings language=\"SCSS\">\n\t\t<indentOptions>\n\t\t\t<option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\"/>\n\t\t\t<option name=\"TAB_SIZE\" value=\"2\"/>\n\t\t</indentOptions>\n\t</codeStyleSettings>\n\t<codeStyleSettings language=\"TypeScript\">\n\t\t<indentOptions>\n\t\t\t<option name=\"INDENT_SIZE\" value=\"2\"/>\n\t\t\t<option name=\"TAB_SIZE\" value=\"2\"/>\n\t\t</indentOptions>\n\t</codeStyleSettings>\n\t<codeStyleSettings language=\"XML\">\n\t\t<indentOptions>\n\t\t\t<option name=\"INDENT_SIZE\" value=\"2\"/>\n\t\t\t<option name=\"CONTINUATION_INDENT_SIZE\" value=\"2\"/>\n\t\t\t<option name=\"TAB_SIZE\" value=\"2\"/>\n\t\t</indentOptions>\n\t\t<arrangement>\n\t\t\t<rules>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>xmlns:android</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>^$</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>xmlns:.*</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>^$</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t\t<order>BY_NAME</order>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*:id</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>style</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>^$</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>^$</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t\t<order>BY_NAME</order>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*:.*Style</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t\t<order>BY_NAME</order>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*:layout_width</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*:layout_height</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*:layout_weight</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*:layout_margin</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*:layout_marginTop</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*:layout_marginBottom</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*:layout_marginStart</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*:layout_marginEnd</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*:layout_marginLeft</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*:layout_marginRight</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*:layout_.*</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t\t<order>BY_NAME</order>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*:padding</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*:paddingTop</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*:paddingBottom</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*:paddingStart</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*:paddingEnd</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*:paddingLeft</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*:paddingRight</NAME>\n\t\t\t\t\t\t\t\t<XML_ATTRIBUTE/>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*</NAME>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res/android\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t\t<order>BY_NAME</order>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*</NAME>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/apk/res-auto\n\t\t\t\t\t\t\t\t</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t\t<order>BY_NAME</order>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*</NAME>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>http://schemas.android.com/tools</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t\t<order>BY_NAME</order>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t\t<section>\n\t\t\t\t\t<rule>\n\t\t\t\t\t\t<match>\n\t\t\t\t\t\t\t<AND>\n\t\t\t\t\t\t\t\t<NAME>.*</NAME>\n\t\t\t\t\t\t\t\t<XML_NAMESPACE>.*</XML_NAMESPACE>\n\t\t\t\t\t\t\t</AND>\n\t\t\t\t\t\t</match>\n\t\t\t\t\t\t<order>BY_NAME</order>\n\t\t\t\t\t</rule>\n\t\t\t\t</section>\n\t\t\t</rules>\n\t\t</arrangement>\n\t</codeStyleSettings>\n\t<Objective-C>\n\t\t<option name=\"INDENT_NAMESPACE_MEMBERS\" value=\"0\"/>\n\t\t<option name=\"INDENT_C_STRUCT_MEMBERS\" value=\"2\"/>\n\t\t<option name=\"INDENT_CLASS_MEMBERS\" value=\"2\"/>\n\t\t<option name=\"INDENT_VISIBILITY_KEYWORDS\" value=\"1\"/>\n\t\t<option name=\"INDENT_INSIDE_CODE_BLOCK\" value=\"2\"/>\n\t\t<option name=\"KEEP_STRUCTURES_IN_ONE_LINE\" value=\"true\"/>\n\t\t<option name=\"FUNCTION_PARAMETERS_WRAP\" value=\"5\"/>\n\t\t<option name=\"FUNCTION_CALL_ARGUMENTS_WRAP\" value=\"5\"/>\n\t\t<option name=\"TEMPLATE_CALL_ARGUMENTS_WRAP\" value=\"5\"/>\n\t\t<option name=\"TEMPLATE_CALL_ARGUMENTS_ALIGN_MULTILINE\" value=\"true\"/>\n\t\t<option name=\"ALIGN_INIT_LIST_IN_COLUMNS\" value=\"false\"/>\n\t\t<option name=\"SPACE_BEFORE_SUPERCLASS_COLON\" value=\"false\"/>\n\t</Objective-C>\n\t<Objective-C-extensions>\n\t\t<option name=\"GENERATE_INSTANCE_VARIABLES_FOR_PROPERTIES\" value=\"ASK\"/>\n\t\t<option name=\"RELEASE_STYLE\" value=\"IVAR\"/>\n\t\t<option name=\"TYPE_QUALIFIERS_PLACEMENT\" value=\"BEFORE\"/>\n\t\t<file>\n\t\t\t<option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Import\"/>\n\t\t\t<option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Macro\"/>\n\t\t\t<option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Typedef\"/>\n\t\t\t<option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Enum\"/>\n\t\t\t<option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Constant\"/>\n\t\t\t<option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Global\"/>\n\t\t\t<option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Struct\"/>\n\t\t\t<option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"FunctionPredecl\"/>\n\t\t\t<option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Function\"/>\n\t\t</file>\n\t\t<class>\n\t\t\t<option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Property\"/>\n\t\t\t<option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Synthesize\"/>\n\t\t\t<option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"InitMethod\"/>\n\t\t\t<option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"StaticMethod\"/>\n\t\t\t<option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"InstanceMethod\"/>\n\t\t\t<option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"DeallocMethod\"/>\n\t\t</class>\n\t\t<extensions>\n\t\t\t<pair header=\"h\" source=\"cc\"/>\n\t\t\t<pair header=\"h\" source=\"c\"/>\n\t\t</extensions>\n\t</Objective-C-extensions>\n\t<codeStyleSettings language=\"ObjectiveC\">\n\t\t<option name=\"RIGHT_MARGIN\" value=\"80\"/>\n\t\t<option name=\"KEEP_BLANK_LINES_BEFORE_RBRACE\" value=\"1\"/>\n\t\t<option name=\"BLANK_LINES_BEFORE_IMPORTS\" value=\"0\"/>\n\t\t<option name=\"BLANK_LINES_AFTER_IMPORTS\" value=\"0\"/>\n\t\t<option name=\"BLANK_LINES_AROUND_CLASS\" value=\"0\"/>\n\t\t<option name=\"BLANK_LINES_AROUND_METHOD\" value=\"0\"/>\n\t\t<option name=\"BLANK_LINES_AROUND_METHOD_IN_INTERFACE\" value=\"0\"/>\n\t\t<option name=\"ALIGN_MULTILINE_BINARY_OPERATION\" value=\"false\"/>\n\t\t<option name=\"BINARY_OPERATION_SIGN_ON_NEXT_LINE\" value=\"true\"/>\n\t\t<option name=\"FOR_STATEMENT_WRAP\" value=\"1\"/>\n\t\t<option name=\"ASSIGNMENT_WRAP\" value=\"1\"/>\n\t\t<indentOptions>\n\t\t\t<option name=\"INDENT_SIZE\" value=\"2\"/>\n\t\t\t<option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\"/>\n\t\t</indentOptions>\n\t</codeStyleSettings>\n</code_scheme>"
  },
  {
    "path": "easy-retry-common/pom.xml",
    "content": "<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:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<parent>\n\t\t<groupId>com.alibaba</groupId>\n\t\t<artifactId>easy-retry</artifactId>\n\t\t<version>${revision}</version>\n\t\t<relativePath>../pom.xml</relativePath>\n\t</parent>\n\t<artifactId>easy-retry-common</artifactId>\n\t<name>easy-retry-common</name>\n\t<description>easy-retry-common</description>\n\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>org.projectlombok</groupId>\n\t\t\t<artifactId>lombok</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.apache.commons</groupId>\n\t\t\t<artifactId>commons-lang3</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>com.google.guava</groupId>\n\t\t\t<artifactId>guava</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.slf4j</groupId>\n\t\t\t<artifactId>slf4j-api</artifactId>\n\t\t</dependency>\n\t</dependencies>\n\n</project>"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/AbstractResultPredicate.java",
    "content": "package com.alibaba.easyretry.common;\n\n/**\n * @author Created by wuhao on 2021/3/26.\n */\npublic abstract class AbstractResultPredicate<T> implements EasyRetryPredicate<T, Boolean> {\n\n\t@Override\n\tpublic abstract Boolean apply(T result);\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/AbstractRetrySyncExecutor.java",
    "content": "package com.alibaba.easyretry.common;\n\nimport com.alibaba.easyretry.common.retryer.RetryerInfo;\n\n/**\n * @author zhangchi20\n * Created on 2023-07-17\n */\npublic abstract class AbstractRetrySyncExecutor<V> implements RetrySyncExecutor<V> {\n\n\tprivate RetryerInfo<V> retryerInfo;\n\n\t@Override\n\tpublic void setRetryerInfo(RetryerInfo<V> retryerInfo) {\n\t\tthis.retryerInfo = retryerInfo;\n\t}\n\n\tpublic RetryerInfo<V> getRetryerInfo() {\n\t\treturn retryerInfo;\n\t}\n\n\n\t@Override\n\tpublic abstract V call(SCallable<V> callable) throws Throwable;\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/EasyRetryPredicate.java",
    "content": "package com.alibaba.easyretry.common;\n\nimport java.io.Serializable;\n\n/**\n * @author Created by wuhao on 2021/3/18.\n */\npublic interface EasyRetryPredicate<T, R> extends Serializable {\n\n\tR apply(T result);\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/Invocation.java",
    "content": "package com.alibaba.easyretry.common;\n\n/**\n * @author Created by wuhao on 2021/3/29.\n */\npublic interface Invocation {\n\n\tObject invoke() throws Throwable;\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryConfiguration.java",
    "content": "package com.alibaba.easyretry.common;\n\nimport com.alibaba.easyretry.common.access.RetrySerializerAccess;\nimport com.alibaba.easyretry.common.access.RetryStrategyAccess;\nimport com.alibaba.easyretry.common.access.RetryTaskAccess;\nimport com.alibaba.easyretry.common.event.RetryEventMulticaster;\nimport com.alibaba.easyretry.common.resolve.ExecutorSolver;\nimport com.alibaba.easyretry.common.serializer.ResultPredicateSerializer;\n\n/**\n * @author Created by wuhao on 2020/11/5.\n */\npublic interface RetryConfiguration {\n\n\tRetryTaskAccess getRetryTaskAccess();\n\n\tRetrySerializerAccess getRetrySerializerAccess();\n\n\tRetryStrategyAccess getRetryStrategyAccess();\n\n\tExecutorSolver getExecutorSolver();\n\n\tResultPredicateSerializer getResultPredicateSerializer();\n\n\tInteger getMaxRetryTimes();\n\n\tRetryEventMulticaster getRetryEventMulticaster();\n\n\tdefault AbstractRetrySyncExecutor getRetrySyncExecutor() {\n\t\treturn null;\n\t}\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryContainer.java",
    "content": "package com.alibaba.easyretry.common;\n\n/**\n * @author Created by wuhao on 2020/11/5.\n */\npublic interface RetryContainer extends RetryLifecycle {\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryContext.java",
    "content": "package com.alibaba.easyretry.common;\n\npublic interface RetryContext extends RetryLifecycle {\n\n\tvoid setAttribute(String key, String value);\n\n\tString getAttribute(String key);\n\n\t/**\n\t * 获取唯一标识\n\t */\n\tString getId();\n\n\tInvocation getInvocation();\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryExecutor.java",
    "content": "package com.alibaba.easyretry.common;\n\nimport com.alibaba.easyretry.common.constant.enums.HandleResultEnum;\n\n/**\n * @author Created by wuhao on 2021/3/2.\n */\npublic interface RetryExecutor {\n\n\tHandleResultEnum doExecute(RetryContext context);\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryIdentify.java",
    "content": "package com.alibaba.easyretry.common;\n\nimport java.util.Objects;\n\n/**\n * @author Created by wuhao on 2021/2/20.\n */\npublic class RetryIdentify {\n\n\tprivate static final ThreadLocal<String> RETRY_CONTEXT_THREAD_LOCAL = new ThreadLocal<>();\n\n\tprivate static final String RETRY_FLAG = \"RETRY_FLAG\";\n\n\tpublic static void start() {\n\t\tRETRY_CONTEXT_THREAD_LOCAL.set(RETRY_FLAG);\n\t}\n\n\tpublic static void stop() {\n\t\tRETRY_CONTEXT_THREAD_LOCAL.set(null);\n\t}\n\n\tpublic static boolean isOnRetry() {\n\t\treturn Objects.nonNull(RETRY_CONTEXT_THREAD_LOCAL.get());\n\t}\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryLifecycle.java",
    "content": "package com.alibaba.easyretry.common;\n\n/**\n * @author Created by wuhao on 2020/11/2.\n */\npublic interface RetryLifecycle {\n\n\tvoid start();\n\n\tvoid stop();\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetrySyncExecutor.java",
    "content": "package com.alibaba.easyretry.common;\n\nimport com.alibaba.easyretry.common.retryer.RetryerInfo;\n\n/**\n * @author zhangchi20\n * Created on 2023-07-17\n */\npublic interface RetrySyncExecutor<V> {\n\n\tV call(SCallable<V> callable) throws Throwable;\n\n\tvoid setRetryerInfo(RetryerInfo<V> retryerInfo);\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/SCallable.java",
    "content": "package com.alibaba.easyretry.common;\n\nimport java.io.Serializable;\n\n/**\n * @author Created by wuhao on 2020/11/5.\n */\n@FunctionalInterface\npublic interface SCallable<V> extends Serializable {\n\n\tV call() throws Throwable;\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/SimpleMethodInvocation.java",
    "content": "package com.alibaba.easyretry.common;\n\nimport java.lang.reflect.Method;\nimport java.util.Arrays;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Setter;\n\n/**\n * @author Created by wuhao on 2021/3/29.\n */\n@AllArgsConstructor\npublic class SimpleMethodInvocation implements Invocation {\n\n\t@Setter\n\tprivate Object executor;\n\n\t@Setter\n\tprivate Method method;\n\n\t@Setter\n\tprivate Object[] args;\n\n\t@Override\n\tpublic Object invoke() throws Throwable {\n\t\treturn method.invoke(executor, args);\n\t}\n\n\t@Override\n\tpublic String toString() {\n\t\treturn \"[Invocation] executor is \" + executor.getClass().getName() + \" method is \" + method\n\t\t\t.getName() + \" args is \" + Arrays.toString(args);\n\n\t}\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/access/RetrySerializerAccess.java",
    "content": "package com.alibaba.easyretry.common.access;\n\nimport com.alibaba.easyretry.common.serializer.RetryArgSerializer;\n\n/**\n * 重试信息序列化器获取 如果方法上有指定序列化器，则使用getRetrySerializer 否则使用全局序列化器getCurrentGlobalRetrySerializer\n *\n * @author Created by wuhao on 2020/11/6.\n */\npublic interface RetrySerializerAccess {\n\n\t/**\n\t * 获取全局序列化器\n\t */\n\tRetryArgSerializer getCurrentGlobalRetrySerializer();\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/access/RetryStrategyAccess.java",
    "content": "package com.alibaba.easyretry.common.access;\n\nimport com.alibaba.easyretry.common.strategy.StopStrategy;\nimport com.alibaba.easyretry.common.strategy.WaitStrategy;\n\n/**\n * 重试策略获取 如果方法上有指定则用指定Strategy 否则使用Global\n *\n * @author Created by wuhao on 2020/11/6.\n */\npublic interface RetryStrategyAccess {\n\n\t/**\n\t * 获取全局重试任务停止策略\n\t */\n\tStopStrategy getCurrentGlobalStopStrategy();\n\n\t/**\n\t * 获取全局等待策略\n\t */\n\tWaitStrategy getCurrentGlobalWaitStrategy();\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/access/RetryTaskAccess.java",
    "content": "package com.alibaba.easyretry.common.access;\n\nimport java.util.List;\n\nimport com.alibaba.easyretry.common.entity.RetryTask;\n\n/**\n * 重试任务获取器\n */\npublic interface RetryTaskAccess {\n\n\t/**\n\t * 保存重试任务\n\t */\n\tboolean saveRetryTask(RetryTask retryTask);\n\n\t/**\n\t * 更改重试任务为处理中\n\t */\n\tboolean handlingRetryTask(RetryTask retryTask);\n\n\t/**\n\t * 完结重试任务\n\t */\n\tboolean finishRetryTask(RetryTask retryTask);\n\n\t/**\n\t * 停止重试任务\n\t */\n\tboolean stopRetryTask(RetryTask retryTask);\n\n\t/**\n\t * 批量查询重试任务\n\t */\n\tList<RetryTask> listAvailableTasks(Long lastId);\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/constant/enums/HandleResultEnum.java",
    "content": "package com.alibaba.easyretry.common.constant.enums;\n\n/**\n * 重试任务重试结果\n *\n * @author Created by wuhao on 2020/11/1.\n */\npublic enum HandleResultEnum {\n\n\t/**\n\t * 处理成功\n\t */\n\tSUCCESS,\n\n\t/**\n\t * 处理失败\n\t */\n\tFAILURE,\n\n\t/**\n\t * 等待策略返回该case还在等待队列中\n\t */\n\tWAITING,\n\n\t/**\n\t * 根据停止策略该笔case停止重试\n\t */\n\tSTOP,\n\n\tERROR;\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/constant/enums/RetryTaskStatusEnum.java",
    "content": "package com.alibaba.easyretry.common.constant.enums;\n\nimport java.util.Map;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\n\nimport lombok.Getter;\n\n/**\n * 重试任务状态\n *\n * @author Created by wuhao on 2020/10/31.\n */\npublic enum RetryTaskStatusEnum {\n\n\t/**\n\t * 初始化状态\n\t */\n\tINIT(0, \"初始化\"),\n\n\t/**\n\t * 任务处理中\n\t */\n\tHANDLING(1, \"处理中\"),\n\n\t/**\n\t * 任务处理异常\n\t */\n\tERROR(2, \"异常\"),\n\n\t/**\n\t * 任务完结\n\t */\n\tFINISH(3, \"完结\");\n\n\tprivate static final Map<Integer, RetryTaskStatusEnum> MAP =\n\t\tStream.of(values())\n\t\t\t.collect(Collectors.toMap(RetryTaskStatusEnum::getCode, (value) -> value));\n\t@Getter\n\tprivate int code;\n\t@Getter\n\tprivate String desc;\n\n\tRetryTaskStatusEnum(int code, String desc) {\n\t\tthis.code = code;\n\t\tthis.desc = desc;\n\t}\n\n\tpublic static RetryTaskStatusEnum fromCode(int code) {\n\t\treturn MAP.get(code);\n\t}\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/constant/enums/RetryTypeEnum.java",
    "content": "package com.alibaba.easyretry.common.constant.enums;\n\n/**\n * 重试种类\n *\n * @author Created by zhangchi on 2023-07-12\n */\npublic enum RetryTypeEnum {\n\n\t/**\n\t * 同步\n\t */\n\tSYNC,\n\n\t/**\n\t * 异步\n\t */\n\tASYNC,\n\t;\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/constant/package-info.java",
    "content": "/**\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",
    "content": "package com.alibaba.easyretry.common.entity;\n\nimport java.util.Date;\nimport java.util.Map;\n\nimport com.alibaba.easyretry.common.constant.enums.RetryTaskStatusEnum;\n\nimport lombok.Data;\n\n/**\n * 重试任务实体\n *\n * @author wuhao\n */\n@Data\npublic class RetryTask {\n\n\t/**\n\t * 主键id\n\t */\n\tprivate Long id;\n\n\t/**\n\t * 业务信息\n\t */\n\tprivate String bizId;\n\n\t/**\n\t * 执行者名称\n\t */\n\tprivate String executorName;\n\n\t/**\n\t * 执行者方法\n\t */\n\tprivate String executorMethodName;\n\n\t/**\n\t * 当重试失败时候执行的方法\n\t */\n\tprivate String onFailureMethod;\n\n\t/**\n\t * 重试任务状态\n\t */\n\tprivate RetryTaskStatusEnum status;\n\n\t/**\n\t * 任务上的扩展字段\n\t */\n\tprivate Map<String, String> extAttrs;\n\n\t/**\n\t * 重试执行者方法参数\n\t */\n\tprivate String argsStr;\n\n\tprivate Date gmtCreate;\n\n\tprivate Date gmtModified;\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/RetryEvent.java",
    "content": "package com.alibaba.easyretry.common.event;\n\n/**\n * @author Created by wuhao on 2021/3/25.\n */\npublic interface RetryEvent {\n\n\tString getName();\n\n\tboolean isOnRetry();\n\n\tvoid setAttribute(String key, String vule);\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/RetryEventMulticaster.java",
    "content": "package com.alibaba.easyretry.common.event;\n\n/**\n * @author Created by wuhao on 2021/3/26.\n */\npublic interface RetryEventMulticaster {\n\n\tvoid register(RetryListener listener);\n\n\tvoid multicast(RetryEvent retryEvent);\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/RetryListener.java",
    "content": "package com.alibaba.easyretry.common.event;\n\n/**\n * @author Created by wuhao on 2021/3/25.\n */\npublic interface RetryListener<T extends RetryEvent> {\n\n\tvoid onRetryEvent(T event);\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/before/AfterSaveBeforeRetryEvent.java",
    "content": "package com.alibaba.easyretry.common.event.before;\n\nimport com.alibaba.easyretry.common.entity.RetryTask;\n\n/**\n * @author Created by wuhao on 2021/3/25.\n */\npublic class AfterSaveBeforeRetryEvent extends BeforeRetryEvent {\n\n\tpublic AfterSaveBeforeRetryEvent(RetryTask retryTask) {\n\t\tsuper(retryTask);\n\t}\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/before/BeforeRetryEvent.java",
    "content": "package com.alibaba.easyretry.common.event.before;\n\nimport java.util.Map;\nimport java.util.Objects;\n\nimport com.alibaba.easyretry.common.entity.RetryTask;\nimport com.alibaba.easyretry.common.event.RetryEvent;\n\nimport com.google.common.collect.Maps;\n\n/**\n * @author Created by wuhao on 2021/3/25.\n */\npublic abstract class BeforeRetryEvent implements RetryEvent {\n\n\tprivate RetryTask retryTask;\n\n\tpublic BeforeRetryEvent(RetryTask retryTask) {\n\t\tthis.retryTask = retryTask;\n\t}\n\n\t@Override\n\tpublic boolean isOnRetry() {\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic void setAttribute(String key, String value) {\n\t\tMap<String, String> extAttrs = retryTask.getExtAttrs();\n\t\tif (Objects.isNull(extAttrs)) {\n\t\t\textAttrs = Maps.newHashMap();\n\t\t}\n\t\textAttrs.put(key, value);\n\t}\n\n\t@Override\n\tpublic String getName() {\n\t\treturn this.getClass().getSimpleName();\n\t}\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/before/PrepSaveBeforeRetryEvent.java",
    "content": "package com.alibaba.easyretry.common.event.before;\n\nimport com.alibaba.easyretry.common.entity.RetryTask;\n\n/**\n * @author Created by wuhao on 2021/3/25.\n */\npublic class PrepSaveBeforeRetryEvent extends BeforeRetryEvent {\n\n\tpublic PrepSaveBeforeRetryEvent(RetryTask retryTask) {\n\t\tsuper(retryTask);\n\t}\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/on/FailureOnRetryEvent.java",
    "content": "package com.alibaba.easyretry.common.event.on;\n\nimport com.alibaba.easyretry.common.RetryContext;\n\n/**\n * @author Created by wuhao on 2021/3/25.\n */\npublic class FailureOnRetryEvent extends OnRetryEvent {\n\n\tpublic FailureOnRetryEvent(RetryContext retryContext) {\n\t\tsuper(retryContext);\n\t}\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/on/OnRetryEvent.java",
    "content": "package com.alibaba.easyretry.common.event.on;\n\nimport com.alibaba.easyretry.common.RetryContext;\nimport com.alibaba.easyretry.common.event.RetryEvent;\n\n/**\n * @author Created by wuhao on 2021/3/25.\n */\npublic abstract class OnRetryEvent implements RetryEvent {\n\n\tfinal private RetryContext retryContext;\n\n\tpublic OnRetryEvent(RetryContext retryContext) {\n\t\tthis.retryContext = retryContext;\n\t}\n\n\t@Override\n\tpublic void setAttribute(String key, String value) {\n\t\tretryContext.setAttribute(key, value);\n\t}\n\n\tpublic String getAttribute(String key) {\n\t\treturn retryContext.getAttribute(key);\n\t}\n\n\t@Override\n\tpublic boolean isOnRetry() {\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic String getName() {\n\t\treturn this.getClass().getSimpleName();\n\t}\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/on/StopOnRetryEvent.java",
    "content": "package com.alibaba.easyretry.common.event.on;\n\nimport com.alibaba.easyretry.common.RetryContext;\n\n/**\n * @author Created by wuhao on 2021/3/25.\n */\npublic class StopOnRetryEvent extends OnRetryEvent {\n\n\tpublic StopOnRetryEvent(RetryContext retryContext) {\n\t\tsuper(retryContext);\n\t}\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/on/SuccessOnRetryEvent.java",
    "content": "package com.alibaba.easyretry.common.event.on;\n\nimport com.alibaba.easyretry.common.RetryContext;\n\n/**\n * @author Created by wuhao on 2021/3/25.\n */\npublic class SuccessOnRetryEvent extends OnRetryEvent {\n\n\tpublic SuccessOnRetryEvent(RetryContext retryContext) {\n\t\tsuper(retryContext);\n\t}\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/AbstractRetryFilter.java",
    "content": "package com.alibaba.easyretry.common.filter;\n\n/**\n * @author Created by wuhao on 2021/3/22.\n */\npublic abstract class AbstractRetryFilter implements RetryFilter {\n\n\tprotected RetryFilter next;\n\n\t@Override\n\tpublic void setNext(RetryFilter next) {\n\t\tthis.next = next;\n\t}\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilter.java",
    "content": "package com.alibaba.easyretry.common.filter;\n\nimport com.alibaba.easyretry.common.RetryContext;\n\n/**\n * @author Created by wuhao on 2021/3/22.\n */\npublic interface RetryFilter {\n\n\tRetryFilterResponse doFilter(RetryContext retryContext) throws Throwable;\n\n\tvoid setNext(RetryFilter next);\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterDiscover.java",
    "content": "package com.alibaba.easyretry.common.filter;\n\nimport java.util.List;\n\n/**\n * @author Created by wuhao on 2021/4/9.\n */\npublic interface RetryFilterDiscover {\n\n\tList<RetryFilter> discoverAll();\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterInvocation.java",
    "content": "package com.alibaba.easyretry.common.filter;\n\nimport com.alibaba.easyretry.common.RetryContext;\n\n/**\n * @author Created by wuhao on 2021/4/10.\n */\npublic interface RetryFilterInvocation {\n\n\tRetryFilterResponse invoke(RetryContext retryContext) throws Throwable;\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterInvocationHandler.java",
    "content": "package com.alibaba.easyretry.common.filter;\n\n/**\n * @author Created by wuhao on 2021/3/19.\n */\npublic interface RetryFilterInvocationHandler {\n\tvoid handle();\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterRegister.java",
    "content": "package com.alibaba.easyretry.common.filter;\n\nimport java.util.List;\n\n/**\n * @author Created by wuhao on 2021/3/22.\n */\npublic interface RetryFilterRegister {\n\n\tvoid register(RetryFilter retryFilter);\n\n\tList<RetryFilter> export();\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterRegisterHandler.java",
    "content": "package com.alibaba.easyretry.common.filter;\n\n/**\n * @author Created by wuhao on 2021/4/9.\n */\npublic interface RetryFilterRegisterHandler {\n\n\tvoid handle();\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterResponse.java",
    "content": "package com.alibaba.easyretry.common.filter;\n\nimport lombok.Data;\n\n/**\n * @author Created by wuhao on 2021/3/22.\n */\n@Data\npublic class RetryFilterResponse {\n\n\tprivate Object response;\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/processor/AsyncPersistenceProcessor.java",
    "content": "package com.alibaba.easyretry.common.processor;\n\n/**\n * @author Created by wuhao on 2021/3/19.\n */\npublic interface AsyncPersistenceProcessor<R> extends RetryProcessor {\n\n\t@Override\n\tvoid process();\n\n\tboolean needRetry();\n\n\tR getResult() throws Throwable;\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/processor/RetryProcessor.java",
    "content": "package com.alibaba.easyretry.common.processor;\n\n/**\n * @author Created by wuhao on 2021/3/19.\n */\npublic interface RetryProcessor {\n\n\tvoid process();\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/processor/SyncProcessor.java",
    "content": "package com.alibaba.easyretry.common.processor;\n\n/**\n * @author Created by zhangchi on 2023-07-12\n */\npublic interface SyncProcessor<R> extends RetryProcessor {\n\n\tR getResult() throws Throwable;\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/resolve/ExecutorSolver.java",
    "content": "package com.alibaba.easyretry.common.resolve;\n\n/**\n * @author Created by wuhao on 2020/11/8.\n */\npublic interface ExecutorSolver {\n\n\tObject resolver(String executorName);\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/retryer/Retryer.java",
    "content": "package com.alibaba.easyretry.common.retryer;\n\nimport com.alibaba.easyretry.common.SCallable;\n\n/**\n * @author Created by wuhao on 2020/11/5.\n */\npublic interface Retryer<V> {\n\n\tV call(SCallable<V> callable) throws Throwable;\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/retryer/RetryerInfo.java",
    "content": "package com.alibaba.easyretry.common.retryer;\n\nimport com.alibaba.easyretry.common.AbstractResultPredicate;\nimport com.alibaba.easyretry.common.RetryConfiguration;\n\nimport lombok.Data;\nimport lombok.experimental.Accessors;\n\n/**\n * @author Created by wuhao on 2021/3/19.\n */\n@Data\n@Accessors(chain = true)\npublic class RetryerInfo<T> {\n\n\t/**\n\t * 执行者名称\n\t */\n\tprivate String executorName;\n\n\t/**\n\t * 执行者方法\n\t */\n\tprivate String executorMethodName;\n\n\tprivate String onFailureMethod;\n\n\t/**\n\t * 业务id，外部可以自定义存储一些信息\n\t */\n\tprivate String bizId;\n\n\tprivate Object[] args;\n\n\tprivate Class<? extends Throwable> onException;\n\n\tprivate RetryConfiguration retryConfiguration;\n\n\tprivate String namespace;\n\n\tprivate boolean reThrowException;\n\n\tprivate AbstractResultPredicate<T> resultPredicate;\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/ArgDeSerializerInfo.java",
    "content": "package com.alibaba.easyretry.common.serializer;\n\nimport lombok.Data;\n\n/**\n * @author Created by wuhao on 2020/11/1.\n */\n@Data\npublic class ArgDeSerializerInfo {\n\n\tprivate String argsStr;\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/ArgSerializerInfo.java",
    "content": "package com.alibaba.easyretry.common.serializer;\n\nimport lombok.Data;\n\n/**\n * @author Created by wuhao on 2020/11/1.\n */\n@Data\npublic class ArgSerializerInfo {\n\n\t/**\n\t * 执行者名称\n\t */\n\tprivate String executorName;\n\n\tprivate String executorClassName;\n\n\t/**\n\t * 执行者方法\n\t */\n\tprivate String executorMethodName;\n\n\tprivate Object[] args;\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/EasyRetrySerializer.java",
    "content": "package com.alibaba.easyretry.common.serializer;\n\n/**\n * @author Created by wuhao on 2021/3/18.\n */\npublic interface EasyRetrySerializer<T> {\n\n\tString serialize(T serializeInfo);\n\n\tT deSerialize(String infoStr);\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/ResultPredicateSerializer.java",
    "content": "package com.alibaba.easyretry.common.serializer;\n\nimport com.alibaba.easyretry.common.AbstractResultPredicate;\n\n/**\n * @author Created by wuhao on 2021/3/18.\n */\npublic interface ResultPredicateSerializer extends EasyRetrySerializer<AbstractResultPredicate> {\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/RetryArgSerializer.java",
    "content": "package com.alibaba.easyretry.common.serializer;\n\n/**\n * Retry 序列化器\n */\npublic interface RetryArgSerializer extends EasyRetrySerializer<ArgSerializerInfo> {\n\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/strategy/RetryStrategy.java",
    "content": "package com.alibaba.easyretry.common.strategy;\n\nimport com.alibaba.easyretry.common.RetryContext;\n\n/**\n * @author Created by wuhao on 2020/11/2.\n */\npublic interface RetryStrategy {\n\n\tvoid clear(RetryContext context);\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/strategy/StopStrategy.java",
    "content": "package com.alibaba.easyretry.common.strategy;\n\nimport com.alibaba.easyretry.common.RetryContext;\n\n/**\n * @author Created by wuhao on 2020/11/1.\n */\npublic interface StopStrategy extends RetryStrategy {\n\n\tboolean shouldStop(RetryContext context);\n}\n"
  },
  {
    "path": "easy-retry-common/src/main/java/com/alibaba/easyretry/common/strategy/WaitStrategy.java",
    "content": "package com.alibaba.easyretry.common.strategy;\n\nimport com.alibaba.easyretry.common.RetryContext;\n\n/**\n * @author Created by wuhao on 2020/11/1.\n */\npublic interface WaitStrategy extends RetryStrategy {\n\n\tboolean shouldWait(RetryContext context);\n\n\tvoid backOff(RetryContext context);\n}\n"
  },
  {
    "path": "easy-retry-core/pom.xml",
    "content": "<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:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<parent>\n\t\t<groupId>com.alibaba</groupId>\n\t\t<artifactId>easy-retry</artifactId>\n\t\t<version>${revision}</version>\n\t\t<relativePath>../pom.xml</relativePath>\n\t</parent>\n\t<artifactId>easy-retry-core</artifactId>\n\n\t<name>easy-retry-core</name>\n\t<description>easy-retry-core</description>\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>${project.groupId}</groupId>\n\t\t\t<artifactId>easy-retry-common</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>org.apache.commons</groupId>\n\t\t\t<artifactId>commons-lang3</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>com.google.guava</groupId>\n\t\t\t<artifactId>guava</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>com.caucho</groupId>\n\t\t\t<artifactId>hessian</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>org.slf4j</groupId>\n\t\t\t<artifactId>slf4j-api</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>com.alibaba</groupId>\n\t\t\t<artifactId>fastjson</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>org.apache.commons</groupId>\n\t\t\t<artifactId>commons-collections4</artifactId>\n\t\t</dependency>\n\t</dependencies>\n</project>\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/DegradeAbleRetryExecutor.java",
    "content": "package com.alibaba.easyretry.core;\n\nimport com.alibaba.easyretry.common.RetryContext;\nimport com.alibaba.easyretry.common.RetryExecutor;\nimport com.alibaba.easyretry.common.constant.enums.HandleResultEnum;\nimport com.alibaba.easyretry.core.degrade.EasyRetryDegradeHelper;\nimport lombok.Setter;\nimport lombok.extern.slf4j.Slf4j;\n\n/**\n * @author Created by gejinfeng on 2021/4/29.\n */\n@Slf4j\npublic class DegradeAbleRetryExecutor implements RetryExecutor {\n\n\t@Setter\n\tprivate RetryExecutor retryExecutor;\n\n\t@Setter\n\tprivate EasyRetryDegradeHelper easyRetryDegradeHelper;\n\n\t@Override\n\tpublic HandleResultEnum doExecute(RetryContext context) {\n\t\tif (easyRetryDegradeHelper.degrade(context)) {\n\t\t\treturn HandleResultEnum.STOP;\n\t\t}\n\t\treturn retryExecutor.doExecute(context);\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/PersistenceRetryExecutor.java",
    "content": "package com.alibaba.easyretry.core;\n\nimport java.lang.reflect.InvocationTargetException;\n\nimport com.alibaba.easyretry.common.RetryConfiguration;\nimport com.alibaba.easyretry.common.RetryContext;\nimport com.alibaba.easyretry.common.RetryExecutor;\nimport com.alibaba.easyretry.common.access.RetryTaskAccess;\nimport com.alibaba.easyretry.common.constant.enums.HandleResultEnum;\nimport com.alibaba.easyretry.common.entity.RetryTask;\nimport com.alibaba.easyretry.common.event.RetryEvent;\nimport com.alibaba.easyretry.common.event.on.FailureOnRetryEvent;\nimport com.alibaba.easyretry.common.event.on.StopOnRetryEvent;\nimport com.alibaba.easyretry.common.event.on.SuccessOnRetryEvent;\nimport com.alibaba.easyretry.common.filter.RetryFilterInvocation;\nimport com.alibaba.easyretry.common.filter.RetryFilterResponse;\nimport com.alibaba.easyretry.core.context.MaxAttemptsPersistenceRetryContext;\nimport com.alibaba.easyretry.core.process.async.on.AbstractAsyncPersistenceOnRetryProcessor;\nimport com.alibaba.easyretry.core.process.async.on.ExceptionPersistenceAsynOnRetryProcessor;\nimport com.alibaba.easyretry.core.process.async.on.ResultAsynPersistenceOnRetryProcessor;\nimport com.alibaba.easyretry.core.utils.LogUtils;\nimport com.alibaba.easyretry.core.utils.PrintUtils;\n\nimport lombok.Setter;\nimport lombok.extern.slf4j.Slf4j;\n\n/**\n * @author Created by wuhao on 2021/3/2.\n */\n@Slf4j\npublic class PersistenceRetryExecutor implements RetryExecutor {\n\n\t@Setter\n\tprivate RetryConfiguration retryConfiguration;\n\n\t@Setter\n\tprivate RetryFilterInvocation retryFilterInvocation;\n\n\t@Override\n\tpublic HandleResultEnum doExecute(RetryContext context) {\n\t\ttry {\n\t\t\tPrintUtils.monitorInfo(\"begin deal\", context);\n\t\t\treturn handle(context);\n\t\t} catch (Throwable e) {\n\t\t\tlog.error(\"Retry invoke failed\", e);\n\t\t\treturn HandleResultEnum.ERROR;\n\t\t}\n\t}\n\n\tprivate HandleResultEnum handle(RetryContext context) {\n\t\tMaxAttemptsPersistenceRetryContext maxAttemptsPersistenceRetryContext\n\t\t\t= (MaxAttemptsPersistenceRetryContext)context;\n\t\tif (maxAttemptsPersistenceRetryContext.getWaitStrategy().shouldWait(context)) {\n\t\t\tPrintUtils.monitorInfo(\"shouldWait\", context);\n\t\t\treturn HandleResultEnum.WAITING;\n\t\t}\n\t\tPrintUtils.monitorInfo(\"handlingRetryTask\", context);\n\t\tretryConfiguration.getRetryTaskAccess()\n\t\t\t.handlingRetryTask(maxAttemptsPersistenceRetryContext.getRetryTask());\n\t\tAbstractAsyncPersistenceOnRetryProcessor<Object> abstractAsynPersistenceOnRetryProcessor;\n\t\ttry {\n\t\t\tPrintUtils.monitorInfo(\"beigin excuteMethod\", context);\n\t\t\tRetryFilterResponse retryFilterResponse = retryFilterInvocation.invoke(context);\n\t\t\tabstractAsynPersistenceOnRetryProcessor = new ResultAsynPersistenceOnRetryProcessor<>(\n\t\t\t\tretryFilterResponse.getResponse(),\n\t\t\t\tmaxAttemptsPersistenceRetryContext);\n\t\t\tPrintUtils.monitorInfo(\"excuteMethod success \", context);\n\t\t} catch (Throwable t) {\n\t\t\tif (t instanceof InvocationTargetException) {\n\t\t\t\tt = t.getCause();\n\t\t\t}\n\t\t\tlog.error(\"excuteMethod failed task arg is {} task id is {}\", context.getInvocation(),\n\t\t\t\tcontext.getId(), t);\n\t\t\tabstractAsynPersistenceOnRetryProcessor = new ExceptionPersistenceAsynOnRetryProcessor<>(\n\t\t\t\tt,\n\t\t\t\tmaxAttemptsPersistenceRetryContext);\n\t\t}\n\t\tabstractAsynPersistenceOnRetryProcessor.process();\n\t\tHandleResultEnum handleResult = abstractAsynPersistenceOnRetryProcessor.getRetryResult();\n\t\tPrintUtils.monitorInfo(\"handleResult \", context, \"handleResult is \" + handleResult);\n\t\tRetryEvent onRetryEvent = null;\n\t\tswitch (handleResult) {\n\t\t\tcase SUCCESS:\n\t\t\t\tfinish(context);\n\t\t\t\tonRetryEvent = new SuccessOnRetryEvent(context);\n\t\t\t\tbreak;\n\t\t\tcase STOP:\n\t\t\t\tstop(context);\n\t\t\t\tonRetryEvent = new StopOnRetryEvent(context);\n\t\t\t\tbreak;\n\t\t\tcase FAILURE:\n\t\t\t\tonRetryEvent = new FailureOnRetryEvent(context);\n\t\t}\n\t\tretryConfiguration.getRetryEventMulticaster().multicast(onRetryEvent);\n\t\treturn handleResult;\n\t}\n\n\tprivate void finish(RetryContext context) {\n\t\tMaxAttemptsPersistenceRetryContext maxAttemptsPersistenceRetryContext\n\t\t\t= (MaxAttemptsPersistenceRetryContext)context;\n\t\tRetryTask retryTask = maxAttemptsPersistenceRetryContext.getRetryTask();\n\t\ttry {\n\t\t\tRetryTaskAccess retryTaskAccess = retryConfiguration.getRetryTaskAccess();\n\t\t\tretryTaskAccess.finishRetryTask(retryTask);\n\t\t\tcontext.stop();\n\t\t} catch (Throwable t) {\n\t\t\tLogUtils.CONSISTENCY_LOGGER\n\t\t\t\t.error(\"finishRetryTask error \" + context.getInvocation() + \" please check\", t);\n\t\t}\n\t}\n\n\tprivate void stop(RetryContext context) {\n\t\ttry {\n\t\t\tMaxAttemptsPersistenceRetryContext maxAttemptsPersistenceRetryContext\n\t\t\t\t= (MaxAttemptsPersistenceRetryContext)context;\n\t\t\tRetryTaskAccess retryTaskAccess = retryConfiguration.getRetryTaskAccess();\n\t\t\tretryTaskAccess.stopRetryTask(maxAttemptsPersistenceRetryContext.getRetryTask());\n\t\t\t//executeOnFailureMethod(context);\n\t\t\tcontext.stop();\n\t\t} catch (Throwable t) {\n\t\t\tLogUtils.CONSISTENCY_LOGGER\n\t\t\t\t.error(\"stopRetryTask error \" + context.getInvocation() + \" please check\", t);\n\t\t}\n\t}\n\n\t//private void executeOnFailureMethod(RetryContext context) {\n\t//\n\t//\tMaxRetryTimesRetryContext maxRetryTimesRetryContext = (MaxRetryTimesRetryContext)context;\n\t//\tString methodName = maxRetryTimesRetryContext.getOnFailureMethod();\n\t//\tif (StringUtils.isEmpty(methodName)) {\n\t//\t\treturn;\n\t//\t}\n\t//\tObject executor = context.getExecutor();\n\t//\tMethod onFailure = BeanUtils.getMethod(methodName, executor.getClass());\n\t//\tif (Objects.isNull(onFailure)) {\n\t//\t\treturn;\n\t//\t}\n\t//\ttry {\n\t//\t\tonFailure.invoke(executor, context);\n\t//\t} catch (Throwable t) {\n\t//\t\tLogUtils.CONSISTENCY_LOGGER.error(\n\t//\t\t\t\"executeOnFailureMethod failed onFailureMethod = {}\"\n\t//\t\t\t\t+ PrintUtils.printCommonMethodInfo(context)\n\t//\t\t\t\t+ \" please check\",\n\t//\t\t\tmethodName,\n\t//\t\t\tt);\n\t//\t}\n\t//}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/PersistenceRetryer.java",
    "content": "package com.alibaba.easyretry.core;\n\nimport com.alibaba.easyretry.common.SCallable;\nimport com.alibaba.easyretry.common.processor.AsyncPersistenceProcessor;\nimport com.alibaba.easyretry.common.retryer.Retryer;\nimport com.alibaba.easyretry.common.retryer.RetryerInfo;\nimport com.alibaba.easyretry.core.process.async.before.ExceptionPersistenceAsyncBeforeRetryProcessor;\nimport com.alibaba.easyretry.core.process.async.before.ResultAsynPersistenceBeforeRetryProcessor;\nimport lombok.Data;\nimport lombok.extern.slf4j.Slf4j;\n\n/**\n * @author Created by wuhao on 2020/11/1.\n */\n@Slf4j\n@Data\npublic class PersistenceRetryer<V> implements Retryer<V> {\n\n\tprivate RetryerInfo<V> retryerInfo;\n\n\tpublic PersistenceRetryer(RetryerInfo<V> retryerInfo) {\n\t\tthis.retryerInfo = retryerInfo;\n\t}\n\n\t@Override\n\tpublic V call(SCallable<V> callable) throws Throwable {\n\t\tAsyncPersistenceProcessor<V> asynPersistenceProcessor;\n\t\ttry {\n\t\t\tV result = callable.call();\n\t\t\tasynPersistenceProcessor = new ResultAsynPersistenceBeforeRetryProcessor<>(result,\n\t\t\t\tretryerInfo);\n\t\t} catch (Throwable e) {\n\t\t\tlog.error(\n\t\t\t\t\"call method error executorMethodName is {} executorName name is {} args is {}\",\n\t\t\t\tretryerInfo.getExecutorMethodName(),\n\t\t\t\tretryerInfo.getExecutorName(),\n\t\t\t\tretryerInfo.getArgs(),\n\t\t\t\te);\n\t\t\tasynPersistenceProcessor = new ExceptionPersistenceAsyncBeforeRetryProcessor<>(e,\n\t\t\t\tretryerInfo);\n\t\t}\n\t\tasynPersistenceProcessor.process();\n\t\treturn asynPersistenceProcessor.getResult();\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/PersistenceRetryerBuilder.java",
    "content": "package com.alibaba.easyretry.core;\n\nimport com.alibaba.easyretry.common.AbstractResultPredicate;\nimport com.alibaba.easyretry.common.RetryConfiguration;\nimport com.alibaba.easyretry.common.retryer.RetryerInfo;\n\n/**\n * @author Created by wuhao on 2020/11/1.\n */\npublic class PersistenceRetryerBuilder<T> {\n\n\tprivate PersistenceRetryer<T> persistenceRetryer;\n\n\tpublic PersistenceRetryerBuilder(RetryConfiguration retryConfiguration) {\n\t\tRetryerInfo<T> retryerInfo = new RetryerInfo<>();\n\t\tpersistenceRetryer = new PersistenceRetryer<T>(retryerInfo);\n\t}\n\n\tpublic static <T> PersistenceRetryerBuilder<T> of(RetryConfiguration retryConfiguration) {\n\t\treturn new PersistenceRetryerBuilder<>(retryConfiguration);\n\t}\n\n\tpublic PersistenceRetryerBuilder<T> withExecutorName(String executorName) {\n\t\tpersistenceRetryer.getRetryerInfo().setExecutorName(executorName);\n\t\treturn this;\n\t}\n\n\tpublic PersistenceRetryerBuilder<T> withExecutorMethodName(String executorMethodName) {\n\t\tpersistenceRetryer.getRetryerInfo().setExecutorMethodName(executorMethodName);\n\t\treturn this;\n\t}\n\n\tpublic PersistenceRetryerBuilder<T> withBizId(String bizId) {\n\t\tpersistenceRetryer.getRetryerInfo().setBizId(bizId);\n\t\treturn this;\n\t}\n\n\tpublic PersistenceRetryerBuilder<T> withArgs(Object[] args) {\n\t\tpersistenceRetryer.getRetryerInfo().setArgs(args);\n\t\treturn this;\n\t}\n\n\tpublic PersistenceRetryerBuilder<T> withOnException(Class<? extends Throwable> onException) {\n\t\tpersistenceRetryer.getRetryerInfo().setOnException(onException);\n\t\treturn this;\n\t}\n\n\tpublic PersistenceRetryerBuilder<T> withOnFailureMethod(String onFailureMethod) {\n\t\tpersistenceRetryer.getRetryerInfo().setOnFailureMethod(onFailureMethod);\n\t\treturn this;\n\t}\n\n\tpublic PersistenceRetryerBuilder<T> withReThrowException(boolean reThrowException) {\n\t\tpersistenceRetryer.getRetryerInfo().setReThrowException(reThrowException);\n\t\treturn this;\n\t}\n\n\tpublic PersistenceRetryerBuilder<T> withNamespace(String namespace) {\n\t\tpersistenceRetryer.getRetryerInfo().setNamespace(namespace);\n\t\treturn this;\n\t}\n\n\tpublic PersistenceRetryerBuilder<T> withConfiguration(RetryConfiguration retryConfiguration) {\n\t\tpersistenceRetryer.getRetryerInfo().setRetryConfiguration(retryConfiguration);\n\t\treturn this;\n\t}\n\n\tpublic PersistenceRetryerBuilder<T> withResultPredicate(AbstractResultPredicate<T> abstractResultPredicate) {\n\t\tpersistenceRetryer.getRetryerInfo().setResultPredicate(abstractResultPredicate);\n\t\treturn this;\n\t}\n\n\tpublic PersistenceRetryer<T> build() {\n\t\treturn persistenceRetryer;\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/RetryerBuilder.java",
    "content": "package com.alibaba.easyretry.core;\n\nimport com.alibaba.easyretry.common.AbstractResultPredicate;\nimport com.alibaba.easyretry.common.RetryConfiguration;\nimport com.alibaba.easyretry.common.constant.enums.RetryTypeEnum;\nimport com.alibaba.easyretry.common.retryer.Retryer;\n\n/**\n * @author Created by zhangchi on 2023-07-13\n */\npublic class RetryerBuilder<T> {\n\n\t/**\n\t * 执行者名称\n\t */\n\tprivate String executorNameContext;\n\n\t/**\n\t * 执行者方法\n\t */\n\tprivate String executorMethodNameContext;\n\n\tprivate String onFailureMethodContext;\n\n\t/**\n\t * 业务id，外部可以自定义存储一些信息\n\t */\n\tprivate String bizIdContext;\n\n\tprivate Object[] argsContext;\n\n\tprivate Class<? extends Throwable> onExceptionContext;\n\n\tprivate RetryConfiguration retryConfigurationContext;\n\n\tprivate String namespaceContext;\n\n\tprivate boolean reThrowExceptionContext;\n\n\tprivate AbstractResultPredicate<T> resultPredicateContext;\n\n\n\tpublic RetryerBuilder<T> withExecutorName(String executorName) {\n\t\texecutorNameContext = executorName;\n\t\treturn this;\n\t}\n\n\tpublic RetryerBuilder<T> withExecutorMethodName(String executorMethodName) {\n\t\texecutorMethodNameContext = executorMethodName;\n\t\treturn this;\n\t}\n\n\tpublic RetryerBuilder<T> withBizId(String bizId) {\n\t\tbizIdContext = bizId;\n\t\treturn this;\n\t}\n\n\tpublic RetryerBuilder<T> withArgs(Object[] args) {\n\t\targsContext = args;\n\t\treturn this;\n\t}\n\n\tpublic RetryerBuilder<T> withOnException(Class<? extends Throwable> onException) {\n\t\tonExceptionContext = onException;\n\t\treturn this;\n\t}\n\n\tpublic RetryerBuilder<T> withOnFailureMethod(String onFailureMethod) {\n\t\tonFailureMethodContext = onFailureMethod;\n\t\treturn this;\n\t}\n\n\tpublic RetryerBuilder<T> withReThrowException(boolean reThrowException) {\n\t\treThrowExceptionContext = reThrowException;\n\t\treturn this;\n\t}\n\n\tpublic RetryerBuilder<T> withNamespace(String namespace) {\n\t\tnamespaceContext = namespace;\n\t\treturn this;\n\t}\n\n\tpublic RetryerBuilder<T> withConfiguration(RetryConfiguration retryConfiguration) {\n\t\tretryConfigurationContext = retryConfiguration;\n\t\treturn this;\n\t}\n\n\tpublic RetryerBuilder<T> withResultPredicate(AbstractResultPredicate<T> abstractResultPredicate) {\n\t\tresultPredicateContext = abstractResultPredicate;\n\t\treturn this;\n\t}\n\n\tpublic Retryer<T> build(RetryTypeEnum retryTypeEnum) {\n\t\tif (RetryTypeEnum.SYNC == retryTypeEnum) {\n\t\t\treturn buildSyncRetryer();\n\t\t} else {\n\t\t\treturn buildAsyncRetryer();\n\t\t}\n\t}\n\n\tprivate SyncRetryer<T> buildSyncRetryer() {\n\t\tSyncRetryerBuilder<T> builder = SyncRetryerBuilder.<T>of(retryConfigurationContext)\n\t\t\t\t.withConfiguration(retryConfigurationContext);\n\t\treturn builder.build();\n\t}\n\n\tprivate PersistenceRetryer<T> buildAsyncRetryer() {\n\t\tPersistenceRetryerBuilder<T> builder = PersistenceRetryerBuilder.<T>of(retryConfigurationContext)\n\t\t\t.withExecutorName(executorNameContext)\n\t\t\t.withExecutorMethodName(executorMethodNameContext)\n\t\t\t.withArgs(argsContext)\n\t\t\t.withConfiguration(retryConfigurationContext)\n\t\t\t//\t\t\t.withOnFailureMethod(retryable.onFailureMethod())\n\t\t\t//\t\t\t.withNamespace(namespace)\n\t\t\t.withReThrowException(reThrowExceptionContext)\n\t\t\t.withResultPredicate(resultPredicateContext);\n\t\treturn builder.build();\n\t}\n\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/SyncRetryer.java",
    "content": "package com.alibaba.easyretry.core;\n\n\nimport com.alibaba.easyretry.common.AbstractRetrySyncExecutor;\nimport com.alibaba.easyretry.common.SCallable;\nimport com.alibaba.easyretry.common.retryer.Retryer;\nimport com.alibaba.easyretry.common.retryer.RetryerInfo;\n\nimport lombok.Data;\nimport lombok.extern.slf4j.Slf4j;\n\n/**\n * @author Created by zhangchi Created on 2023-07-12\n */\n@Slf4j\n@Data\npublic class SyncRetryer<V> implements Retryer<V> {\n\n\tprivate RetryerInfo<V> retryerInfo;\n\n\tpublic SyncRetryer(RetryerInfo<V> retryerInfo) {\n\t\tthis.retryerInfo = retryerInfo;\n\t}\n\n\t@Override\n\tpublic V call(SCallable<V> callable) throws Throwable {\n\t\tAbstractRetrySyncExecutor retrySyncExecutor = retryerInfo.getRetryConfiguration().getRetrySyncExecutor();\n\t\tretrySyncExecutor.setRetryerInfo(retryerInfo);\n\t\treturn (V) retrySyncExecutor.call(callable);\n\t}\n\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/SyncRetryerBuilder.java",
    "content": "package com.alibaba.easyretry.core;\n\nimport java.util.Objects;\n\nimport com.alibaba.easyretry.common.RetryConfiguration;\nimport com.alibaba.easyretry.common.retryer.RetryerInfo;\n\n/**\n * @author Created by zhangchi on 2023-07-12\n */\npublic class SyncRetryerBuilder<T> {\n\n\tprivate SyncRetryer<T> syncRetryer;\n\n\tpublic SyncRetryerBuilder(RetryConfiguration retryConfiguration) {\n\t\tRetryerInfo<T> retryerInfo = new RetryerInfo<>();\n\t\tsyncRetryer = new SyncRetryer<>(retryerInfo);\n\t}\n\n\tpublic static <T> SyncRetryerBuilder<T> of(RetryConfiguration retryConfiguration) {\n\t\treturn new SyncRetryerBuilder<>(retryConfiguration);\n\t}\n\n\tpublic SyncRetryerBuilder<T> withConfiguration(RetryConfiguration retryConfiguration) {\n\t\tsyncRetryer.getRetryerInfo().setRetryConfiguration(retryConfiguration);\n\t\treturn this;\n\t}\n\n\n\tpublic SyncRetryer<T> build() {\n\t\treturn syncRetryer;\n\t}\n\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/access/DefaultRetrySerializerAccess.java",
    "content": "package com.alibaba.easyretry.core.access;\n\nimport com.alibaba.easyretry.common.access.RetrySerializerAccess;\nimport com.alibaba.easyretry.common.serializer.RetryArgSerializer;\nimport com.alibaba.easyretry.core.serializer.HessianRetryArgSerializer;\n\n/**\n * @author Created by wuhao on 2020/11/6.\n */\npublic class DefaultRetrySerializerAccess implements RetrySerializerAccess {\n\n\t@Override\n\tpublic RetryArgSerializer getCurrentGlobalRetrySerializer() {\n\t\treturn new HessianRetryArgSerializer();\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/access/MemoryRetryTaskAccess.java",
    "content": "package com.alibaba.easyretry.core.access;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.atomic.AtomicLong;\nimport java.util.stream.Collectors;\n\nimport com.alibaba.easyretry.common.access.RetryTaskAccess;\nimport com.alibaba.easyretry.common.constant.enums.RetryTaskStatusEnum;\nimport com.alibaba.easyretry.common.entity.RetryTask;\n\nimport com.google.common.collect.Maps;\n\n/**\n * @author Created by wuhao on 2020/11/5.\n */\npublic class MemoryRetryTaskAccess implements RetryTaskAccess {\n\n\tprivate static final Map<Long, RetryTask> retryTaskMap = Maps.newConcurrentMap();\n\n\tprivate static final AtomicLong atomicLong = new AtomicLong();\n\n\t@Override\n\tpublic boolean saveRetryTask(RetryTask retryTask) {\n\t\tlong id = atomicLong.getAndIncrement();\n\t\tretryTask.setId(id);\n\t\tretryTaskMap.putIfAbsent(id, retryTask);\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic boolean handlingRetryTask(RetryTask retryTask) {\n\t\tretryTask.setStatus(RetryTaskStatusEnum.HANDLING);\n\t\tretryTaskMap.putIfAbsent(retryTask.getId(), retryTask);\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic boolean finishRetryTask(RetryTask retryTask) {\n\t\tretryTaskMap.remove(retryTask.getId());\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic boolean stopRetryTask(RetryTask retryTask) {\n\t\tretryTask.setStatus(RetryTaskStatusEnum.ERROR);\n\t\tretryTaskMap.putIfAbsent(retryTask.getId(), retryTask);\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic List<RetryTask> listAvailableTasks(Long lastId) {\n\t\treturn retryTaskMap.values().stream()\n\t\t\t.filter((retryTask) -> retryTask.getStatus() == RetryTaskStatusEnum.INIT)\n\t\t\t.filter((retryTask) -> retryTask.getId() > lastId)\n\t\t\t.sorted((o1, o2) -> o1.getId() > o2.getId() ? 1 : -1)\n\t\t\t.collect(Collectors.toList());\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/container/SimpleRetryContainer.java",
    "content": "package com.alibaba.easyretry.core.container;\n\nimport java.util.List;\nimport java.util.concurrent.BlockingQueue;\nimport java.util.concurrent.LinkedBlockingQueue;\nimport java.util.concurrent.PriorityBlockingQueue;\nimport java.util.concurrent.ThreadPoolExecutor;\nimport java.util.concurrent.TimeUnit;\n\nimport com.alibaba.easyretry.common.RetryConfiguration;\nimport com.alibaba.easyretry.common.RetryContainer;\nimport com.alibaba.easyretry.common.RetryContext;\nimport com.alibaba.easyretry.common.RetryExecutor;\nimport com.alibaba.easyretry.common.constant.enums.HandleResultEnum;\nimport com.alibaba.easyretry.common.entity.RetryTask;\nimport com.alibaba.easyretry.core.context.MaxAttemptsPersistenceRetryContext.RetryContextBuilder;\n\nimport lombok.extern.slf4j.Slf4j;\nimport org.apache.commons.collections4.CollectionUtils;\n\n/**\n * @author Created by wuhao on 2020/11/5.\n */\n@Slf4j\npublic class SimpleRetryContainer implements RetryContainer {\n\n\tprivate static final Integer MAX_QUEUE_SIZE = 2000;\n\n\tprivate RetryConfiguration retryConfiguration;\n\n\tprivate RetryExecutor retryExecutor;\n\n\tpublic SimpleRetryContainer() {\n\t}\n\n\tpublic SimpleRetryContainer(\n\t\tRetryConfiguration retryConfiguration, RetryExecutor retryExecutor) {\n\t\tthis.retryConfiguration = retryConfiguration;\n\t\tthis.retryExecutor = retryExecutor;\n\t}\n\n\t@Override\n\tpublic void start() {\n\t\tBlockingQueue<RetryContext> queue = new PriorityBlockingQueue<>(MAX_QUEUE_SIZE);\n\t\tThreadPoolExecutor retryExecutor =\n\t\t\tnew ThreadPoolExecutor(\n\t\t\t\t1,\n\t\t\t\t1,\n\t\t\t\t0L,\n\t\t\t\tTimeUnit.MILLISECONDS,\n\t\t\t\tnew LinkedBlockingQueue<>(),\n\t\t\t\tr -> new Thread(r, \"retryExecutor-Thread\"));\n\t\tretryExecutor.execute(new TaskConsumer(queue));\n\t\tThreadPoolExecutor retrySelector =\n\t\t\tnew ThreadPoolExecutor(\n\t\t\t\t1,\n\t\t\t\t1,\n\t\t\t\t0L,\n\t\t\t\tTimeUnit.MILLISECONDS,\n\t\t\t\tnew LinkedBlockingQueue<>(),\n\t\t\t\tr -> new Thread(r, \"retrySelector-Thread\"));\n\t\tretrySelector.execute(new TaskProducer(queue));\n\t}\n\n\t@Override\n\tpublic void stop() {\n\t}\n\n\tpublic class TaskConsumer implements Runnable {\n\n\t\tprivate static final long MAX_SLEEP_TIME_MILLISECONDS = 10 * 1000L;\n\t\tprivate static final long SLEEP_BASE_TIME_MILLISECONDS = 1000L;\n\t\tprivate final BlockingQueue<RetryContext> queue;\n\t\tprivate long sleepTimes = 0L;\n\n\t\tprivate TaskConsumer(BlockingQueue<RetryContext> queue) {\n\t\t\tthis.queue = queue;\n\t\t}\n\n\t\t@Override\n\t\tpublic void run() {\n\t\t\twhile (!Thread.currentThread().isInterrupted()) {\n\t\t\t\tdoExecute();\n\t\t\t\tlong totalTime = sleepTimes * SLEEP_BASE_TIME_MILLISECONDS;\n\t\t\t\ttry {\n\t\t\t\t\tTimeUnit.MILLISECONDS.sleep(Math.min(totalTime, MAX_SLEEP_TIME_MILLISECONDS));\n\t\t\t\t} catch (InterruptedException e) {\n\t\t\t\t\tlog.error(\"taskConsumer interruptedException error\", e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate void doExecute() {\n\t\t\ttry {\n\t\t\t\tRetryContext context = queue.take();\n\t\t\t\tHandleResultEnum result = retryExecutor.doExecute(context);\n\t\t\t\tif (HandleResultEnum.SUCCESS == result) {\n\t\t\t\t\tsleepTimes = 0L;\n\t\t\t\t} else if (HandleResultEnum.FAILURE == result) {\n\t\t\t\t\tsleepTimes = 0L;\n\t\t\t\t\tqueue.add(context);\n\t\t\t\t} else if (HandleResultEnum.STOP == result) {\n\t\t\t\t\tsleepTimes = 0L;\n\t\t\t\t} else if (HandleResultEnum.ERROR == result) {\n\t\t\t\t\tsleepTimes = 0L;\n\t\t\t\t\t// do nothing\n\t\t\t\t} else {\n\t\t\t\t\tsleepTimes++;\n\t\t\t\t\tqueue.add(context);\n\t\t\t\t}\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\tlog.error(\"Retry execute failed when getting retry task\", e);\n\t\t\t} catch (Throwable e) {\n\t\t\t\tlog.error(\"Retry invoke failed\", e);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic class TaskProducer implements Runnable {\n\n\t\tprivate static final long MAX_SLEEP_TIME_MILLISECONDS = 10 * 1000L;\n\t\tprivate static final long SLEEP_BASE_TIME_MILLISECONDS = 1000L;\n\n\t\tprivate final BlockingQueue<RetryContext> queue;\n\n\t\tprivate long sleepTimes = 0L;\n\n\t\tprivate volatile Long lastId = -1L;\n\n\t\tpublic TaskProducer(BlockingQueue<RetryContext> queue) {\n\t\t\tthis.queue = queue;\n\t\t}\n\n\t\t@Override\n\t\tpublic void run() {\n\t\t\twhile (!Thread.currentThread().isInterrupted()) {\n\t\t\t\tdoSelect();\n\t\t\t\tlong totalTime =\n\t\t\t\t\tsleepTimes * SLEEP_BASE_TIME_MILLISECONDS + SLEEP_BASE_TIME_MILLISECONDS;\n\t\t\t\ttry {\n\t\t\t\t\tTimeUnit.MILLISECONDS.sleep(Math.min(totalTime, MAX_SLEEP_TIME_MILLISECONDS));\n\t\t\t\t} catch (InterruptedException e) {\n\t\t\t\t\tlog.error(\"taskConsumer interruptedException error\", e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate void doSelect() {\n\t\t\tif (queue.size() >= MAX_QUEUE_SIZE) {\n\t\t\t\tsleepTimes++;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tList<RetryTask> tasks =\n\t\t\t\tretryConfiguration.getRetryTaskAccess().listAvailableTasks(lastId);\n\t\t\tif (CollectionUtils.isEmpty(tasks)) {\n\t\t\t\tsleepTimes++;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (queue.size() >= MAX_QUEUE_SIZE) {\n\t\t\t\tsleepTimes++;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (queue.size() + tasks.size() >= MAX_QUEUE_SIZE) {\n\t\t\t\tsleepTimes++;\n\t\t\t} else {\n\t\t\t\tsleepTimes = 0L;\n\t\t\t}\n\t\t\tfor (RetryTask task : tasks) {\n\t\t\t\ttry {\n\t\t\t\t\tlastId = task.getId();\n\t\t\t\t\tRetryContext retryContext =\n\t\t\t\t\t\tnew RetryContextBuilder(retryConfiguration, task)\n\t\t\t\t\t\t\t.buildInvocation()\n\t\t\t\t\t\t\t.buildRetryArgSerializer()\n\t\t\t\t\t\t\t.buildStopStrategy()\n\t\t\t\t\t\t\t.buildWaitStrategy()\n\t\t\t\t\t\t\t.buildRetryTask()\n\t\t\t\t\t\t\t.buildMaxRetryTimes()\n\t\t\t\t\t\t\t.buildOnFailureMethod()\n\t\t\t\t\t\t\t.buildPriority(0L)\n\t\t\t\t\t\t\t.buildResultPredicateSerializer()\n\t\t\t\t\t\t\t.build();\n\t\t\t\t\tretryContext.start();\n\n\t\t\t\t\tqueue.put(retryContext);\n\t\t\t\t\tlog.warn(\"add retry task to queue, task:{}\",\n\t\t\t\t\t\ttask.getId());\n\t\t\t\t} catch (Throwable e) {\n\t\t\t\t\tlog.error(\"add retry task to queue , task:{}\",\n\t\t\t\t\t\ttask.getId(), e);\n\t\t\t\t\t// 出现异常task将放不进queue中，就不会再重试了\n\t\t\t\t\t// 是否需要更新task的状态，并且加上失败的原因？\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/context/MaxAttemptsPersistenceRetryContext.java",
    "content": "package com.alibaba.easyretry.core.context;\n\nimport java.lang.reflect.Method;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.concurrent.TimeUnit;\nimport java.util.stream.Stream;\n\nimport com.alibaba.easyretry.common.Invocation;\nimport com.alibaba.easyretry.common.RetryConfiguration;\nimport com.alibaba.easyretry.common.RetryContext;\nimport com.alibaba.easyretry.common.RetryLifecycle;\nimport com.alibaba.easyretry.common.SimpleMethodInvocation;\nimport com.alibaba.easyretry.common.entity.RetryTask;\nimport com.alibaba.easyretry.common.serializer.ResultPredicateSerializer;\nimport com.alibaba.easyretry.common.serializer.RetryArgSerializer;\nimport com.alibaba.easyretry.common.strategy.StopStrategy;\nimport com.alibaba.easyretry.common.strategy.WaitStrategy;\n\nimport com.google.common.collect.Maps;\nimport lombok.Data;\nimport lombok.ToString;\nimport org.apache.commons.lang3.reflect.MethodUtils;\n\n@Data\n@ToString(callSuper = true)\npublic class MaxAttemptsPersistenceRetryContext implements RetryContext, RetryLifecycle,\n\tComparable<MaxAttemptsPersistenceRetryContext> {\n\n\tprivate RetryTask retryTask;\n\n\tprivate RetryArgSerializer retryArgSerializer;\n\n\tprivate ResultPredicateSerializer resultPredicateSerializer;\n\n\tprivate Long priority;\n\n\tprivate StopStrategy stopStrategy;\n\n\tprivate WaitStrategy waitStrategy;\n\n\tprivate int maxRetryTimes;\n\n\tprivate String onFailureMethod;\n\n\tprivate Invocation invocation;\n\n\t@Override\n\tpublic int compareTo(MaxAttemptsPersistenceRetryContext o) {\n\t\treturn this.priority > o.getPriority() ? 1 : -1;\n\t}\n\n\t@Override\n\tpublic void start() {\n\t}\n\n\t@Override\n\tpublic void stop() {\n\t\tstopStrategy.clear(this);\n\t\twaitStrategy.clear(this);\n\t}\n\n\t@Override\n\tpublic void setAttribute(String key, String value) {\n\t\tMap<String, String> extAttrs = retryTask.getExtAttrs();\n\t\tif (Objects.isNull(extAttrs)) {\n\t\t\textAttrs = Maps.newHashMap();\n\t\t}\n\t\textAttrs.put(key, value);\n\t}\n\n\t@Override\n\tpublic String getAttribute(String key) {\n\t\tMap<String, String> extAttrs = retryTask.getExtAttrs();\n\t\tif (Objects.isNull(extAttrs)) {\n\t\t\treturn null;\n\t\t} else {\n\t\t\treturn extAttrs.get(key);\n\t\t}\n\t}\n\n\tpublic Long getNextRetryTime(TimeUnit unit) {\n\t\treturn unit.convert(priority, TimeUnit.MILLISECONDS);\n\t}\n\n\tpublic void setNextRetryTime(Long nexRetryTime, TimeUnit unit) {\n\t\tpriority = unit.toMillis(nexRetryTime);\n\t}\n\n\t@Override\n\tpublic String getId() {\n\t\treturn retryTask.getId() + \"\";\n\t}\n\n\tpublic static class RetryContextBuilder {\n\n\t\tprivate MaxAttemptsPersistenceRetryContext retryContext;\n\n\t\tprivate RetryConfiguration retryConfiguration;\n\n\t\tprivate RetryTask retryTask;\n\n\t\tpublic RetryContextBuilder(RetryConfiguration retryConfiguration, RetryTask retryTask) {\n\t\t\tretryContext = new MaxAttemptsPersistenceRetryContext();\n\t\t\tthis.retryConfiguration = retryConfiguration;\n\t\t\tthis.retryTask = retryTask;\n\t\t}\n\n\t\tpublic RetryContextBuilder buildInvocation() {\n\t\t\tRetryArgSerializer retryArgSerializer = retryConfiguration.getRetrySerializerAccess()\n\t\t\t\t.getCurrentGlobalRetrySerializer();\n\t\t\tObject[] args = retryArgSerializer.deSerialize(retryTask.getArgsStr()).getArgs();\n\t\t\tObject executor = retryConfiguration.getExecutorSolver()\n\t\t\t\t.resolver(retryTask.getExecutorName());\n\t\t\tClass<?>[] classes = Stream.of(args).map(Object::getClass).toArray(Class[]::new);\n\t\t\tMethod method = MethodUtils\n\t\t\t\t.getMatchingMethod(executor.getClass(), retryTask.getExecutorMethodName(), classes);\n\t\t\tSimpleMethodInvocation simpleMethodInvocation = new SimpleMethodInvocation(executor,\n\t\t\t\tmethod, args);\n\t\t\tretryContext.setInvocation(simpleMethodInvocation);\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic RetryContextBuilder buildRetryArgSerializer() {\n\t\t\tretryContext.setRetryArgSerializer(\n\t\t\t\tretryConfiguration.getRetrySerializerAccess().getCurrentGlobalRetrySerializer());\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic RetryContextBuilder buildStopStrategy() {\n\t\t\tretryContext.setStopStrategy(\n\t\t\t\tretryConfiguration.getRetryStrategyAccess().getCurrentGlobalStopStrategy());\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic RetryContextBuilder buildWaitStrategy() {\n\t\t\tretryContext.setWaitStrategy(\n\t\t\t\tretryConfiguration.getRetryStrategyAccess().getCurrentGlobalWaitStrategy());\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic RetryContextBuilder buildRetryTask() {\n\t\t\tretryContext.setRetryTask(retryTask);\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic RetryContextBuilder buildMaxRetryTimes() {\n\t\t\tretryContext.setMaxRetryTimes(retryConfiguration.getMaxRetryTimes());\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic RetryContextBuilder buildOnFailureMethod() {\n\t\t\tretryContext.setOnFailureMethod(retryTask.getOnFailureMethod());\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic RetryContextBuilder buildResultPredicateSerializer() {\n\t\t\tretryContext\n\t\t\t\t.setResultPredicateSerializer(retryConfiguration.getResultPredicateSerializer());\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic RetryContextBuilder buildPriority(Long priority) {\n\t\t\tretryContext.setPriority(priority);\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic MaxAttemptsPersistenceRetryContext build() {\n\t\t\treturn retryContext;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/degrade/EasyRetryDegradeHelper.java",
    "content": "package com.alibaba.easyretry.core.degrade;\n\nimport com.alibaba.easyretry.common.RetryContext;\n\n/**\n * @author Created by gejinfeng on 2021/4/29.\n */\npublic interface EasyRetryDegradeHelper {\n\n\t/**\n\t * 是否降级\n\t *\n\t * @param retryContext retryContext\n\t * @return degrade\n\t */\n\tboolean degrade(RetryContext retryContext);\n\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/event/SimpleRetryEventMulticaster.java",
    "content": "package com.alibaba.easyretry.core.event;\n\nimport java.util.List;\nimport java.util.Objects;\n\nimport com.alibaba.easyretry.common.event.RetryEvent;\nimport com.alibaba.easyretry.common.event.RetryEventMulticaster;\nimport com.alibaba.easyretry.common.event.RetryListener;\n\nimport com.google.common.collect.Lists;\nimport lombok.Setter;\n\n/**\n * @author Created by wuhao on 2021/3/26.\n */\npublic class SimpleRetryEventMulticaster implements RetryEventMulticaster {\n\n\t@Setter\n\tprivate List<RetryListener> listenerCaches = Lists.newArrayList();\n\n\t@Override\n\tpublic void register(RetryListener listener) {\n\t\tlistenerCaches.add(listener);\n\t}\n\n\t@Override\n\tpublic void multicast(RetryEvent retryEvent) {\n\t\tif (Objects.isNull(retryEvent)) {\n\t\t\treturn;\n\t\t}\n\t\tlistenerCaches.forEach((retryListener) -> retryListener.onRetryEvent(retryEvent));\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/DefaultRetryFilterInvocationHandler.java",
    "content": "package com.alibaba.easyretry.core.filter;\n\nimport java.util.List;\n\nimport com.alibaba.easyretry.common.RetryContext;\nimport com.alibaba.easyretry.common.filter.RetryFilter;\nimport com.alibaba.easyretry.common.filter.RetryFilterInvocation;\nimport com.alibaba.easyretry.common.filter.RetryFilterInvocationHandler;\nimport com.alibaba.easyretry.common.filter.RetryFilterRegister;\nimport com.alibaba.easyretry.common.filter.RetryFilterResponse;\n\nimport lombok.Setter;\nimport org.apache.commons.collections4.CollectionUtils;\n\n/**\n * @author Created by wuhao on 2021/3/22.\n */\npublic class DefaultRetryFilterInvocationHandler implements RetryFilterInvocationHandler, RetryFilterInvocation {\n\n\tprivate RetryFilter firstFilter;\n\n\t@Setter\n\tprivate RetryFilterRegister retryFilterRegister;\n\n\t@Override\n\tpublic RetryFilterResponse invoke(RetryContext retryContext) throws Throwable {\n\t\treturn firstFilter.doFilter(retryContext);\n\t}\n\n\t@Override\n\tpublic void handle() {\n\t\tList<RetryFilter> retryFilters = retryFilterRegister.export();\n\t\tfirstFilter = new NOOPRetryFilter();\n\t\tRetryFilter lastRetryFilter = firstFilter;\n\n\t\tfor (RetryFilter retryFilter : CollectionUtils.emptyIfNull(retryFilters)) {\n\t\t\tlastRetryFilter.setNext(retryFilter);\n\t\t\tlastRetryFilter = retryFilter;\n\t\t}\n\n\t\tIdentifyRetryFilter identifyRetryFilter = new IdentifyRetryFilter();\n\t\tlastRetryFilter.setNext(identifyRetryFilter);\n\t\tlastRetryFilter = identifyRetryFilter;\n\n\t\tMethodExcuteRetryFilter methodExcuteRetryFilter = new MethodExcuteRetryFilter();\n\t\tlastRetryFilter.setNext(methodExcuteRetryFilter);\n\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/DefaultRetryFilterRegisterHandler.java",
    "content": "package com.alibaba.easyretry.core.filter;\n\nimport java.util.List;\n\nimport com.alibaba.easyretry.common.filter.RetryFilter;\nimport com.alibaba.easyretry.common.filter.RetryFilterDiscover;\nimport com.alibaba.easyretry.common.filter.RetryFilterRegister;\nimport com.alibaba.easyretry.common.filter.RetryFilterRegisterHandler;\n\nimport lombok.Setter;\nimport org.apache.commons.collections4.CollectionUtils;\n\n/**\n * @author Created by wuhao on 2021/4/9.\n */\npublic class DefaultRetryFilterRegisterHandler implements RetryFilterRegisterHandler {\n\n\t@Setter\n\tprivate RetryFilterDiscover retryFilterDiscover;\n\n\t@Setter\n\tprivate RetryFilterRegister retryFilterRegister;\n\n\t@Override\n\tpublic void handle() {\n\t\tList<RetryFilter> retryFilters = retryFilterDiscover.discoverAll();\n\t\tfor (RetryFilter retryFilter : CollectionUtils.emptyIfNull(retryFilters)) {\n\t\t\tretryFilterRegister.register(retryFilter);\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/IdentifyRetryFilter.java",
    "content": "package com.alibaba.easyretry.core.filter;\n\nimport com.alibaba.easyretry.common.RetryContext;\nimport com.alibaba.easyretry.common.RetryIdentify;\nimport com.alibaba.easyretry.common.filter.AbstractRetryFilter;\nimport com.alibaba.easyretry.common.filter.RetryFilterResponse;\n\n/**\n * @author Created by wuhao on 2021/3/22.\n */\npublic class IdentifyRetryFilter extends AbstractRetryFilter {\n\n\t@Override\n\tpublic RetryFilterResponse doFilter(RetryContext retryContext) throws Throwable {\n\t\ttry {\n\t\t\tRetryIdentify.start();\n\t\t\treturn next.doFilter(retryContext);\n\t\t} finally {\n\t\t\tRetryIdentify.stop();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/MethodExcuteRetryFilter.java",
    "content": "package com.alibaba.easyretry.core.filter;\n\nimport com.alibaba.easyretry.common.RetryContext;\nimport com.alibaba.easyretry.common.filter.RetryFilter;\nimport com.alibaba.easyretry.common.filter.RetryFilterResponse;\n\n/**\n * @author Created by wuhao on 2021/3/22.\n */\npublic class MethodExcuteRetryFilter implements RetryFilter {\n\n\t@Override\n\tpublic RetryFilterResponse doFilter(RetryContext retryContext) throws Throwable {\n\t\tRetryFilterResponse retryFilterResponse = new RetryFilterResponse();\n\t\tretryFilterResponse.setResponse(retryContext.getInvocation().invoke());\n\t\treturn retryFilterResponse;\n\t}\n\n\t@Override\n\tpublic void setNext(RetryFilter next) {\n\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/NOOPRetryFilter.java",
    "content": "package com.alibaba.easyretry.core.filter;\n\nimport com.alibaba.easyretry.common.RetryContext;\nimport com.alibaba.easyretry.common.filter.AbstractRetryFilter;\nimport com.alibaba.easyretry.common.filter.RetryFilterResponse;\n\n/**\n * @author Created by wuhao on 2021/3/22.\n */\npublic class NOOPRetryFilter extends AbstractRetryFilter {\n\n\t@Override\n\tpublic RetryFilterResponse doFilter(RetryContext retryContext) throws Throwable {\n\t\treturn next.doFilter(retryContext);\n\t}\n\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/SPIRetryFilterDiscover.java",
    "content": "package com.alibaba.easyretry.core.filter;\n\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.ServiceLoader;\n\nimport com.alibaba.easyretry.common.filter.RetryFilter;\nimport com.alibaba.easyretry.common.filter.RetryFilterDiscover;\n\nimport com.google.common.collect.Lists;\n\n/**\n * @author Created by wuhao on 2021/4/9.\n */\npublic class SPIRetryFilterDiscover implements RetryFilterDiscover {\n\n\t@Override\n\tpublic List<RetryFilter> discoverAll() {\n\t\tServiceLoader<RetryFilter> retryFilters = ServiceLoader.load(RetryFilter.class);\n\t\tIterator<RetryFilter> iterator = retryFilters.iterator();\n\t\treturn Lists.newArrayList(iterator);\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/filter/SimpleRetryFilterRegister.java",
    "content": "package com.alibaba.easyretry.core.filter;\n\nimport java.util.List;\n\nimport com.alibaba.easyretry.common.filter.RetryFilter;\nimport com.alibaba.easyretry.common.filter.RetryFilterRegister;\n\nimport com.google.common.collect.Lists;\n\n/**\n * @author Created by wuhao on 2021/4/9.\n */\npublic class SimpleRetryFilterRegister implements RetryFilterRegister {\n\n\tprivate List<RetryFilter> retryFiltersCache = Lists.newArrayList();\n\n\t@Override\n\tpublic void register(RetryFilter retryFilter) {\n\t\tretryFiltersCache.add(retryFilter);\n\t}\n\n\t@Override\n\tpublic List<RetryFilter> export() {\n\t\treturn retryFiltersCache;\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/AbstractAsyncPersistenceProcessor.java",
    "content": "package com.alibaba.easyretry.core.process.async;\n\nimport com.alibaba.easyretry.common.processor.AsyncPersistenceProcessor;\nimport lombok.extern.slf4j.Slf4j;\n\n/**\n * @author Created by wuhao on 2021/3/19.\n */\n@Slf4j\npublic abstract class AbstractAsyncPersistenceProcessor<R> implements AsyncPersistenceProcessor<R> {\n\n\t@Override\n\tpublic void process() {\n\t\tif (!needRetry()) {\n\t\t\treturn;\n\t\t}\n\t\tdoProcess();\n\t}\n\n\tprotected abstract void doProcess();\n\n\t@Override\n\tpublic abstract boolean needRetry();\n\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/before/AbstractAsyncPersistenceBeforeRetryProcessor.java",
    "content": "package com.alibaba.easyretry.core.process.async.before;\n\nimport java.util.Date;\nimport java.util.Map;\nimport java.util.Objects;\n\nimport com.alibaba.easyretry.common.RetryConfiguration;\nimport com.alibaba.easyretry.common.constant.enums.RetryTaskStatusEnum;\nimport com.alibaba.easyretry.common.entity.RetryTask;\nimport com.alibaba.easyretry.common.event.before.AfterSaveBeforeRetryEvent;\nimport com.alibaba.easyretry.common.event.before.PrepSaveBeforeRetryEvent;\nimport com.alibaba.easyretry.common.retryer.RetryerInfo;\nimport com.alibaba.easyretry.common.serializer.ArgSerializerInfo;\nimport com.alibaba.easyretry.core.process.async.AbstractAsyncPersistenceProcessor;\nimport com.google.common.collect.Maps;\nimport lombok.extern.slf4j.Slf4j;\n\n/**\n * @author Created by wuhao on 2021/3/19.\n */\n@Slf4j\npublic abstract class AbstractAsyncPersistenceBeforeRetryProcessor<R> extends\n\tAbstractAsyncPersistenceProcessor<R> {\n\n\tprotected RetryerInfo<R> retryerInfo;\n\n//\tprivate RetryConfiguration retryConfiguration;\n\n\tpublic AbstractAsyncPersistenceBeforeRetryProcessor(\n\t\tRetryerInfo<R> retryerInfo) {\n\t\tthis.retryerInfo = retryerInfo;\n//\t\tthis.retryConfiguration = retryConfiguration;\n\t}\n\n\t@Override\n\tpublic void doProcess() {\n\t\tRetryConfiguration retryConfiguration = retryerInfo.getRetryConfiguration();\n\t\tArgSerializerInfo argSerializerInfo = new ArgSerializerInfo();\n\t\targSerializerInfo.setArgs(retryerInfo.getArgs());\n\t\targSerializerInfo.setExecutorMethodName(retryerInfo.getExecutorMethodName());\n\t\targSerializerInfo.setExecutorName(retryerInfo.getExecutorName());\n\t\tString argsStr = retryConfiguration.getRetrySerializerAccess()\n\t\t\t.getCurrentGlobalRetrySerializer().serialize(argSerializerInfo);\n\n\t\tRetryTask retryTask = new RetryTask();\n\t\tretryTask.setBizId(retryerInfo.getBizId());\n\t\tretryTask.setArgsStr(argsStr);\n\t\tretryTask.setStatus(RetryTaskStatusEnum.INIT);\n\t\tretryTask.setExecutorMethodName(retryerInfo.getExecutorMethodName());\n\t\tretryTask.setExecutorName(retryerInfo.getExecutorName());\n\t\tretryTask.setOnFailureMethod(retryerInfo.getOnFailureMethod());\n\t\tretryTask.setGmtCreate(new Date());\n\t\tretryTask.setGmtModified(new Date());\n\n\t\tMap<String, String> extAttrs = Maps.newHashMap();\n\t\tif (Objects.nonNull(retryerInfo.getResultPredicate())) {\n\t\t\textAttrs.put(\"resultPredicateSerializer\",\n\t\t\t\tretryConfiguration.getResultPredicateSerializer()\n\t\t\t\t\t.serialize(retryerInfo.getResultPredicate()));\n\t\t}\n\t\tretryTask.setExtAttrs(extAttrs);\n\n\t\tPrepSaveBeforeRetryEvent prepSaveBeforeRetryEvent = new PrepSaveBeforeRetryEvent(retryTask);\n\t\tretryConfiguration.getRetryEventMulticaster().multicast(prepSaveBeforeRetryEvent);\n\n\t\tretryConfiguration.getRetryTaskAccess().saveRetryTask(retryTask);\n\n\t\tAfterSaveBeforeRetryEvent afterSaveBeforeRetryEvent = new AfterSaveBeforeRetryEvent(\n\t\t\tretryTask);\n\t\tretryConfiguration.getRetryEventMulticaster().multicast(afterSaveBeforeRetryEvent);\n\t}\n\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/before/ExceptionPersistenceAsyncBeforeRetryProcessor.java",
    "content": "package com.alibaba.easyretry.core.process.async.before;\n\nimport java.util.Objects;\n\nimport com.alibaba.easyretry.common.RetryConfiguration;\nimport com.alibaba.easyretry.common.retryer.RetryerInfo;\n\nimport org.apache.commons.lang3.ClassUtils;\n\n/**\n * @author Created by wuhao on 2021/3/19.\n */\npublic class ExceptionPersistenceAsyncBeforeRetryProcessor<R> extends\n\tAbstractAsyncPersistenceBeforeRetryProcessor<R> {\n\n\tprivate Throwable throwable;\n\n\tpublic ExceptionPersistenceAsyncBeforeRetryProcessor(Throwable throwable,\n\t\tRetryerInfo<R> retryerInfo) {\n\t\tsuper(retryerInfo);\n\t\tthis.throwable = throwable;\n\t}\n\n\t@Override\n\tpublic boolean needRetry() {\n\t\tClass<? extends Throwable> onException = retryerInfo.getOnException();\n\t\tif (Objects.isNull(onException)) {\n\t\t\treturn true;\n\t\t}\n\t\treturn ClassUtils.isAssignable(retryerInfo.getOnException(), throwable.getClass());\n\t}\n\n\t@Override\n\tpublic R getResult() throws Throwable {\n\t\tif (retryerInfo.isReThrowException()) {\n\t\t\tthrow throwable;\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/before/ResultAsynPersistenceBeforeRetryProcessor.java",
    "content": "package com.alibaba.easyretry.core.process.async.before;\n\nimport java.util.Objects;\n\nimport com.alibaba.easyretry.common.AbstractResultPredicate;\nimport com.alibaba.easyretry.common.retryer.RetryerInfo;\n\n/**\n * @author Created by wuhao on 2021/3/19.\n */\npublic class ResultAsynPersistenceBeforeRetryProcessor<R> extends\n    AbstractAsyncPersistenceBeforeRetryProcessor<R> {\n\n\tprivate final R result;\n\n\tpublic ResultAsynPersistenceBeforeRetryProcessor(R result, RetryerInfo<R> retryerInfo) {\n\t\tsuper(retryerInfo);\n\t\tthis.result = result;\n\t}\n\n\t@Override\n\tpublic boolean needRetry() {\n\t\tAbstractResultPredicate<R> easyRetryPredicate = retryerInfo.getResultPredicate();\n\t\tif (Objects.nonNull(easyRetryPredicate)) {\n\t\t\treturn easyRetryPredicate.apply(result);\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t@Override\n\tpublic R getResult() {\n\t\treturn result;\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/on/AbstractAsyncPersistenceOnRetryProcessor.java",
    "content": "package com.alibaba.easyretry.core.process.async.on;\n\nimport com.alibaba.easyretry.common.constant.enums.HandleResultEnum;\nimport com.alibaba.easyretry.core.context.MaxAttemptsPersistenceRetryContext;\nimport com.alibaba.easyretry.core.process.async.AbstractAsyncPersistenceProcessor;\nimport lombok.extern.slf4j.Slf4j;\n\n/**\n * @author Created by wuhao on 2021/3/19.\n */\n@Slf4j\npublic abstract class AbstractAsyncPersistenceOnRetryProcessor<R> extends\n\tAbstractAsyncPersistenceProcessor<R> {\n\n\tprotected MaxAttemptsPersistenceRetryContext context;\n\n\tprivate HandleResultEnum retryResult;\n\n\n\tpublic AbstractAsyncPersistenceOnRetryProcessor(MaxAttemptsPersistenceRetryContext context) {\n\t\tthis.context = context;\n\t}\n\n\t@Override\n\tpublic void process() {\n\t\tif (!needRetry()) {\n\t\t\tretryResult = HandleResultEnum.SUCCESS;\n\t\t\treturn;\n\t\t}\n\t\tdoProcess();\n\t}\n\n\t@Override\n\tpublic void doProcess() {\n\t\tif (context.getStopStrategy().shouldStop(context)) {\n\t\t\tlog.error(context.getInvocation() + \" will stop\");\n\t\t\tretryResult = HandleResultEnum.STOP;\n\t\t} else {\n\t\t\tlog.error(context.getInvocation() + \" will try later\");\n\t\t\tcontext.getWaitStrategy().backOff(context);\n\t\t\tretryResult = HandleResultEnum.FAILURE;\n\t\t}\n\t}\n\n\tpublic HandleResultEnum getRetryResult() {\n\t\treturn retryResult;\n\t}\n\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/on/ExceptionPersistenceAsynOnRetryProcessor.java",
    "content": "package com.alibaba.easyretry.core.process.async.on;\n\nimport com.alibaba.easyretry.core.context.MaxAttemptsPersistenceRetryContext;\n\n/**\n * @author Created by wuhao on 2021/3/19.\n */\npublic class ExceptionPersistenceAsynOnRetryProcessor<R> extends\n\tAbstractAsyncPersistenceOnRetryProcessor<R> {\n\n\tprivate final Throwable throwable;\n\n\tpublic ExceptionPersistenceAsynOnRetryProcessor(Throwable throwable,\n\t\t\t\t\t\t\t\t\t\t\t\t\tMaxAttemptsPersistenceRetryContext context) {\n\t\tsuper(context);\n\t\tthis.throwable = throwable;\n\t}\n\n\t@Override\n\tpublic boolean needRetry() {\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic R getResult() {\n\t\treturn null;\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/async/on/ResultAsynPersistenceOnRetryProcessor.java",
    "content": "package com.alibaba.easyretry.core.process.async.on;\n\nimport com.alibaba.easyretry.common.AbstractResultPredicate;\nimport com.alibaba.easyretry.core.context.MaxAttemptsPersistenceRetryContext;\n\nimport org.apache.commons.lang3.StringUtils;\n\n/**\n * @author Created by wuhao on 2021/3/19.\n */\npublic class ResultAsynPersistenceOnRetryProcessor<R> extends\n    AbstractAsyncPersistenceOnRetryProcessor<R> {\n\n\tprivate R result;\n\n\tpublic ResultAsynPersistenceOnRetryProcessor(R result,\n\t\t\t\t\t\t\t\t\t\t\t\t MaxAttemptsPersistenceRetryContext context) {\n\t\tsuper(context);\n\t\tthis.result = result;\n\t}\n\n\t@Override\n\tpublic boolean needRetry() {\n\t\tString resultPredicateSerializerStr = context.getAttribute(\"resultPredicateSerializer\");\n\t\tif (StringUtils.isBlank(resultPredicateSerializerStr)) {\n\t\t\treturn false;\n\t\t}\n\t\tAbstractResultPredicate resultPredicate = context.getResultPredicateSerializer()\n\t\t\t.deSerialize(resultPredicateSerializerStr);\n\t\treturn resultPredicate.apply(result);\n\t}\n\n\t@Override\n\tpublic R getResult() {\n\t\treturn result;\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/process/package-info.java",
    "content": "/**\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",
    "content": "package com.alibaba.easyretry.core.serializer;\n\nimport java.util.stream.Stream;\n\nimport com.alibaba.easyretry.common.serializer.ArgSerializerInfo;\nimport com.alibaba.easyretry.common.serializer.RetryArgSerializer;\nimport com.alibaba.fastjson.JSON;\n\nimport org.apache.commons.lang3.ClassUtils;\nimport org.apache.commons.lang3.StringUtils;\n\n/**\n *\n */\npublic class FastJsonRetryArgSerializer implements RetryArgSerializer {\n\n\tpublic static final String SPLIT = \"||\";\n\n\tpublic static final String INNER_SPLIT = \"&&\";\n\n\t@Override\n\tpublic String serialize(ArgSerializerInfo argSerializerInfo) {\n\t\tStringBuilder sb = new StringBuilder();\n\t\tStream.of(argSerializerInfo.getArgs()).forEach(\n\t\t\t(arg) -> sb.append(JSON.toJSONString(arg)).append(INNER_SPLIT)\n\t\t\t\t.append(arg.getClass().getName()).append(SPLIT));\n\t\tif (sb.length() >= SPLIT.length()) {\n\t\t\treturn sb.subSequence(0, sb.length() - SPLIT.length()).toString();\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t@Override\n\tpublic ArgSerializerInfo deSerialize(String argsStr) {\n\t\tString[] strs = StringUtils.split(argsStr, SPLIT);\n\t\tObject[] arg = Stream.of(strs)\n\t\t\t.map((str) -> {\n\t\t\t\tString[] inner = str.split(INNER_SPLIT);\n\t\t\t\ttry {\n\t\t\t\t\treturn JSON.parseObject(inner[0], ClassUtils.getClass(inner[1]));\n\t\t\t\t} catch (ClassNotFoundException e) {\n\t\t\t\t\tthrow new RuntimeException(e);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.toArray();\n\t\tArgSerializerInfo argSerializerInfo = new ArgSerializerInfo();\n\t\targSerializerInfo.setArgs(arg);\n\t\treturn argSerializerInfo;\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/serializer/HessianResultPredicateSerializer.java",
    "content": "package com.alibaba.easyretry.core.serializer;\n\nimport com.alibaba.easyretry.common.AbstractResultPredicate;\nimport com.alibaba.easyretry.common.serializer.ResultPredicateSerializer;\nimport com.alibaba.easyretry.core.utils.HessianSerializerUtils;\n\n/**\n * @author Created by wuhao on 2021/3/18.\n */\npublic class HessianResultPredicateSerializer implements ResultPredicateSerializer {\n\n\t@Override\n\tpublic String serialize(AbstractResultPredicate serializeInfo) {\n\t\treturn HessianSerializerUtils.serialize(serializeInfo);\n\t}\n\n\t@Override\n\tpublic AbstractResultPredicate deSerialize(String infoStr) {\n\t\treturn HessianSerializerUtils.deSerialize(infoStr, AbstractResultPredicate.class);\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/serializer/HessianRetryArgSerializer.java",
    "content": "package com.alibaba.easyretry.core.serializer;\n\n/**\n * @author Created by wuhao on 2021/2/22.\n */\n\nimport com.alibaba.easyretry.common.serializer.ArgSerializerInfo;\nimport com.alibaba.easyretry.common.serializer.RetryArgSerializer;\nimport com.alibaba.easyretry.core.utils.HessianSerializerUtils;\n\nimport lombok.extern.slf4j.Slf4j;\n\n@Slf4j\npublic class HessianRetryArgSerializer implements RetryArgSerializer {\n\n\t@Override\n\tpublic String serialize(ArgSerializerInfo argSerializerInfo) {\n\t\tObject[] args = argSerializerInfo.getArgs();\n\t\tif (args.length == 0) {\n\t\t\tthrow new IllegalStateException(\"No args found\");\n\t\t}\n\t\treturn HessianSerializerUtils.serialize(args);\n\t}\n\n\t@Override\n\tpublic ArgSerializerInfo deSerialize(String argStr) {\n\t\tObject[] result = HessianSerializerUtils.deSerialize(argStr, Object[].class);\n\t\tArgSerializerInfo argSerializerInfo = new ArgSerializerInfo();\n\t\targSerializerInfo.setArgs(result);\n\t\treturn argSerializerInfo;\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/strategy/DefaultRetryStrategy.java",
    "content": "package com.alibaba.easyretry.core.strategy;\n\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.concurrent.TimeUnit;\n\nimport com.alibaba.easyretry.common.RetryContext;\nimport com.alibaba.easyretry.common.strategy.StopStrategy;\nimport com.alibaba.easyretry.common.strategy.WaitStrategy;\nimport com.alibaba.easyretry.core.context.MaxAttemptsPersistenceRetryContext;\n\nimport com.google.common.collect.Maps;\nimport lombok.extern.slf4j.Slf4j;\n\n@Slf4j\npublic class DefaultRetryStrategy implements StopStrategy, WaitStrategy {\n\n\tprivate static final Long MAX_INTERNAL_TIME = 15 * 60 * 1000L;\n\tprivate static final Long BASE_INTERNAL_TIME = 5000L;\n\tprivate final Map<String, Long> internalTimeMap = Maps.newConcurrentMap();\n\tprivate final Map<String, Integer> retryTimeMap = Maps.newConcurrentMap();\n\n\t@Override\n\tpublic boolean shouldStop(RetryContext context) {\n\t\tMaxAttemptsPersistenceRetryContext maxAttemptsPersistenceRetryContext\n\t\t\t= (MaxAttemptsPersistenceRetryContext)context;\n\t\tInteger retryTimes = retryTimeMap.get(context.getId());\n\t\tif (Objects.isNull(retryTimes)) {\n\t\t\tretryTimes = 1;\n\t\t}\n\t\tlog.warn(\n\t\t\t\"shouldStop retryTime is {} id is {} maxRetryTime is {}\",\n\t\t\tretryTimes,\n\t\t\tcontext.getId(),\n\t\t\tmaxAttemptsPersistenceRetryContext.getMaxRetryTimes());\n\t\treturn retryTimes >= maxAttemptsPersistenceRetryContext.getMaxRetryTimes();\n\t}\n\n\t@Override\n\tpublic boolean shouldWait(RetryContext context) {\n\t\tMaxAttemptsPersistenceRetryContext maxAttemptsPersistenceRetryContext\n\t\t\t= (MaxAttemptsPersistenceRetryContext)context;\n\t\tinternalTimeMap.putIfAbsent(context.getId(), 0L);\n\t\tLong priority = maxAttemptsPersistenceRetryContext.getNextRetryTime(TimeUnit.MILLISECONDS);\n\t\tif (Objects.isNull(priority)) {\n\t\t\tpriority = 0L;\n\t\t}\n\t\treturn System.currentTimeMillis() < priority;\n\t}\n\n\t@Override\n\tpublic void backOff(RetryContext context) {\n\t\tMaxAttemptsPersistenceRetryContext maxAttemptsPersistenceRetryContext\n\t\t\t= (MaxAttemptsPersistenceRetryContext)context;\n\n\t\tInteger retryTime = retryTimeMap.get(context.getId());\n\t\tLong lastInternalTime = internalTimeMap.get(context.getId());\n\t\tif (Objects.isNull(retryTime)) {\n\t\t\tretryTime = 1;\n\t\t}\n\t\tif (Objects.isNull(lastInternalTime)) {\n\t\t\tlastInternalTime = 0L;\n\t\t}\n\t\tlong nextInternalTime = retryTime * (lastInternalTime + BASE_INTERNAL_TIME);\n\t\tnextInternalTime = Math.min(nextInternalTime, MAX_INTERNAL_TIME);\n\n\t\tinternalTimeMap.put(context.getId(), nextInternalTime);\n\n\t\tretryTime++;\n\t\tretryTimeMap.put(context.getId(), retryTime);\n\t\tmaxAttemptsPersistenceRetryContext\n\t\t\t.setNextRetryTime(System.currentTimeMillis() + nextInternalTime, TimeUnit.MILLISECONDS);\n\t\tlog.warn(\n\t\t\t\"backOff nextInternalTime is {} id is {} retryTime is {}\",\n\t\t\tnextInternalTime,\n\t\t\tcontext.getId(),\n\t\t\tretryTime);\n\t}\n\n\t@Override\n\tpublic void clear(RetryContext context) {\n\t\tinternalTimeMap.remove(context.getId());\n\t\tretryTimeMap.remove(context.getId());\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/utils/HessianSerializerUtils.java",
    "content": "package com.alibaba.easyretry.core.utils;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.util.Base64;\n\nimport com.caucho.hessian.io.HessianInput;\nimport com.caucho.hessian.io.HessianOutput;\n\n/**\n * @author Created by wuhao on 2021/3/18.\n */\npublic class HessianSerializerUtils {\n\n\tpublic static <T> String serialize(T t) {\n\t\ttry (ByteArrayOutputStream os = new ByteArrayOutputStream()) {\n\t\t\tHessianOutput ho = new HessianOutput(os);\n\t\t\tho.writeObject(t);\n\t\t\treturn Base64.getEncoder().encodeToString(os.toByteArray());\n\t\t} catch (IOException e) {\n\t\t\tthrow new IllegalStateException(\"HessianSerializationConverter.serialize failed.\", e);\n\t\t}\n\t}\n\n\tpublic static <T> T deSerialize(String str, Class<T> tClass) {\n\t\tbyte[] convertBytes = Base64.getDecoder().decode(str);\n\t\ttry (ByteArrayInputStream is = new ByteArrayInputStream(convertBytes)) {\n\t\t\tHessianInput hi = new HessianInput(is);\n\t\t\treturn (T)hi.readObject(tClass);\n\t\t} catch (IOException e) {\n\t\t\tthrow new IllegalStateException(\"HessianSerializationConverter.deSerialize failed.\", e);\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/utils/LogUtils.java",
    "content": "package com.alibaba.easyretry.core.utils;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * @author Created by wuhao on 2020/11/13.\n */\npublic class LogUtils {\n\n\tpublic static final Logger CONSISTENCY_LOGGER = LoggerFactory.getLogger(\"aRetryConsistency\");\n}\n"
  },
  {
    "path": "easy-retry-core/src/main/java/com/alibaba/easyretry/core/utils/PrintUtils.java",
    "content": "package com.alibaba.easyretry.core.utils;\n\nimport com.alibaba.easyretry.common.RetryContext;\n\nimport lombok.extern.slf4j.Slf4j;\n\n/**\n * @author Created by wuhao on 2020/11/14.\n */\n@Slf4j\npublic class PrintUtils {\n\n\tpublic static void monitorInfo(String action, RetryContext context) {\n\t\tmonitorInfo(action, context, \"\");\n\t}\n\n\tpublic static void monitorInfo(String action, RetryContext context, String extraInfo) {\n\t\tlog.info(action + \" arg is {} task id is {} \" + extraInfo, context.getInvocation(),\n\t\t\tcontext.getId());\n\t}\n}\n"
  },
  {
    "path": "easy-retry-core/src/test/java/com/alibaba/easyretry/core/utils/TestClass.java",
    "content": "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",
    "content": "<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:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<parent>\n\t\t<groupId>com.alibaba</groupId>\n\t\t<artifactId>easy-retry-extensions</artifactId>\n\t\t<version>${revision}</version>\n\t\t<relativePath>../pom.xml</relativePath>\n\t</parent>\n\n\t<artifactId>easy-retry-guava-extension</artifactId>\n\n\t<name>easy-retry-guava-extension</name>\n\t<description>easy-retry-guava-extension</description>\n\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>${project.groupId}</groupId>\n\t\t\t<artifactId>easy-retry-common</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>${project.groupId}</groupId>\n\t\t\t<artifactId>easy-retry-core</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>com.google.guava</groupId>\n\t\t\t<artifactId>guava</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>com.github.rholder</groupId>\n\t\t\t<artifactId>guava-retrying</artifactId>\n\t\t\t<version>2.0.0</version>\n\t\t</dependency>\n\t</dependencies>\n</project>\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-guava-extension/src/main/java/com/alibaba/easyretry/extension/guava/GuavaRetrySyncExecutor.java",
    "content": "package com.alibaba.easyretry.extension.guava;\n\nimport java.util.Objects;\nimport java.util.concurrent.TimeUnit;\n\nimport com.alibaba.easyretry.common.AbstractResultPredicate;\nimport com.alibaba.easyretry.common.AbstractRetrySyncExecutor;\nimport com.alibaba.easyretry.common.SCallable;\nimport com.alibaba.easyretry.common.retryer.RetryerInfo;\nimport com.github.rholder.retry.Retryer;\nimport com.github.rholder.retry.RetryerBuilder;\nimport com.github.rholder.retry.StopStrategies;\nimport com.github.rholder.retry.WaitStrategies;\n\npublic class GuavaRetrySyncExecutor<V> extends AbstractRetrySyncExecutor<V> {\n\n\tprivate static final long WAIT_TIME = 1000L;\n\n\t@Override\n\tpublic V call(SCallable<V> callable) throws Throwable {\n\n\t\tRetryerInfo<V> retryerInfo = getRetryerInfo();\n\t\tClass<? extends Throwable> onException = Throwable.class;\n\t\tif (Objects.nonNull(retryerInfo.getOnException())) {\n\t\t\tonException = retryerInfo.getOnException();\n\t\t}\n\n\t\tRetryerBuilder<V> retryerBuilder = RetryerBuilder.<V>newBuilder()\n\t\t\t.retryIfExceptionOfType(onException)\n\t\t\t.withStopStrategy(StopStrategies.stopAfterAttempt(retryerInfo.getRetryConfiguration().getMaxRetryTimes()))\n\t\t\t.withWaitStrategy(WaitStrategies.fixedWait(WAIT_TIME, TimeUnit.MILLISECONDS));\n\n\t\tAbstractResultPredicate<V> resultPredicate = retryerInfo.getResultPredicate();\n\t\tif (Objects.nonNull(resultPredicate)) {\n\t\t\tretryerBuilder.retryIfResult(resultPredicate::apply);\n\t\t}\n\n\t\tRetryer<V> retryer = retryerBuilder.build();\n\t\treturn retryer.call(() -> {\n\t\t\ttry {\n\t\t\t\treturn callable.call();\n\t\t\t} catch (Throwable t) {\n\t\t\t\tthrow new Exception(t);\n\t\t\t}\n\t\t});\n\t}\n}\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-guava-extension/src/main/java/com/alibaba/easyretry/extension/guava/package-info.java",
    "content": "package com.alibaba.easyretry.extension.guava;\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/pom.xml",
    "content": "<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:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<parent>\n\t\t<groupId>com.alibaba</groupId>\n\t\t<artifactId>easy-retry-extensions</artifactId>\n\t\t<version>${revision}</version>\n\t\t<relativePath>../pom.xml</relativePath>\n\t</parent>\n\n\t<artifactId>easy-retry-mybatis-extension</artifactId>\n\t<name>easy-retry-mybatis-extension</name>\n\t<description>easy-retry-mybatis-extension</description>\n\t<properties>\n\t\t<mybatis.version>3.5.6</mybatis.version>\n\t\t<h2.version>1.4.200</h2.version>\n\t</properties>\n\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>com.alibaba</groupId>\n\t\t\t<artifactId>easy-retry-common</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>org.mybatis</groupId>\n\t\t\t<artifactId>mybatis</artifactId>\n\t\t\t<version>${mybatis.version}</version>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>com.google.guava</groupId>\n\t\t\t<artifactId>guava</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>com.alibaba</groupId>\n\t\t\t<artifactId>fastjson</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>com.h2database</groupId>\n\t\t\t<artifactId>h2</artifactId>\n\t\t\t<version>${h2.version}</version>\n\t\t\t<scope>test</scope>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>com.zaxxer</groupId>\n\t\t\t<artifactId>HikariCP</artifactId>\n\t\t\t<version>4.0.3</version>\n\t\t\t<scope>test</scope>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>org.slf4j</groupId>\n\t\t\t<artifactId>slf4j-api</artifactId>\n\t\t\t<scope>test</scope>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>ch.qos.logback</groupId>\n\t\t\t<artifactId>logback-classic</artifactId>\n\t\t\t<version>1.2.3</version>\n\t\t\t<scope>test</scope>\n\t\t</dependency>\n\n    </dependencies>\n</project>"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/access/MybatisRetryTaskAccess.java",
    "content": "package com.alibaba.easyretry.extension.mybatis.access;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.stream.Collectors;\n\nimport com.alibaba.easyretry.common.access.RetryTaskAccess;\nimport com.alibaba.easyretry.common.constant.enums.RetryTaskStatusEnum;\nimport com.alibaba.easyretry.common.entity.RetryTask;\nimport com.alibaba.easyretry.extension.mybatis.common.utils.HostUtils;\nimport com.alibaba.easyretry.extension.mybatis.dao.RetryTaskDAO;\nimport com.alibaba.easyretry.extension.mybatis.po.RetryTaskPO;\nimport com.alibaba.easyretry.extension.mybatis.query.RetryTaskQuery;\nimport com.alibaba.fastjson.JSON;\nimport com.alibaba.fastjson.TypeReference;\n\nimport com.google.common.collect.Lists;\nimport com.google.common.collect.Maps;\nimport lombok.AllArgsConstructor;\n\n/**\n * @author Created by wuhao on 2020/11/8.\n */\n@AllArgsConstructor\npublic class MybatisRetryTaskAccess implements RetryTaskAccess {\n\n\tprivate final RetryTaskDAO retryTaskDAO;\n\n\t@Override\n\tpublic boolean saveRetryTask(RetryTask retryTask) {\n\t\tRetryTaskPO retryTaskPO = covert(retryTask);\n\t\treturn retryTaskDAO.saveRetryTask(retryTaskPO);\n\t}\n\n\t@Override\n\tpublic boolean handlingRetryTask(RetryTask retryTask) {\n\t\treturn updateRetryTaskStatus(retryTask, RetryTaskStatusEnum.HANDLING);\n\t}\n\n\t@Override\n\tpublic boolean finishRetryTask(RetryTask retryTask) {\n\t\tRetryTaskPO retryTaskPO = new RetryTaskPO().setId(retryTask.getId());\n\t\treturn retryTaskDAO.deleteRetryTask(retryTaskPO);\n//\t\treturn updateRetryTaskStatus(retryTask, RetryTaskStatusEnum.FINISH);\n\t}\n\n\t@Override\n\tpublic boolean stopRetryTask(RetryTask retryTask) {\n\t\treturn updateRetryTaskStatus(retryTask, RetryTaskStatusEnum.ERROR);\n\t}\n\n\tprivate boolean updateRetryTaskStatus(RetryTask retryTask, RetryTaskStatusEnum status) {\n\t\tRetryTaskPO retryTaskPO = new RetryTaskPO();\n\t\tretryTaskPO.setId(retryTask.getId());\n\t\tretryTaskPO.setRetryStatus(status.getCode());\n\t\treturn retryTaskDAO.updateRetryTask(retryTaskPO);\n\t}\n\n\t@Override\n\tpublic List<RetryTask> listAvailableTasks(Long lastId) {\n\t\tRetryTaskQuery retryTaskQuery = new RetryTaskQuery();\n\t\tretryTaskQuery.setRetryStatus(\n\t\t\tLists.newArrayList(\n\t\t\t\tRetryTaskStatusEnum.INIT.getCode(), RetryTaskStatusEnum.HANDLING.getCode()));\n\t\tretryTaskQuery.setLastId(lastId);\n\t\tretryTaskQuery.setSharding(HostUtils.getHostIP());\n\t\tList<RetryTaskPO> retryTasks = retryTaskDAO.listRetryTask(retryTaskQuery);\n\t\treturn convert(retryTasks);\n\t}\n\n\tprivate List<RetryTask> convert(List<RetryTaskPO> retryTasks) {\n\t\treturn retryTasks.stream().map(this::convert).collect(Collectors.toList());\n\t}\n\n\tprivate RetryTask convert(RetryTaskPO retryTaskPO) {\n\t\tRetryTask retryTask = new RetryTask();\n\t\tretryTask.setId(retryTaskPO.getId());\n\t\tretryTask.setStatus(RetryTaskStatusEnum.fromCode(retryTaskPO.getRetryStatus()));\n\t\tretryTask.setArgsStr(retryTaskPO.getArgsStr());\n\t\tretryTask.setGmtCreate(retryTaskPO.getGmtCreate());\n\t\tretryTask.setGmtModified(retryTaskPO.getGmtModified());\n\t\tretryTask.setExecutorName(retryTaskPO.getExecutorName());\n\t\tretryTask.setExecutorMethodName(retryTaskPO.getExecutorMethodName());\n\t\tretryTask.setBizId(retryTaskPO.getBizId());\n\t\tretryTask.setExtAttrs(JSON.parseObject(retryTaskPO.getExtAttrs(),\n\t\t\tnew TypeReference<Map<String, String>>() {}));\n\t\treturn retryTask;\n\t}\n\n\tprivate RetryTaskPO covert(RetryTask retryTask) {\n\t\tRetryTaskPO retryTaskPO = new RetryTaskPO();\n\t\tretryTaskPO.setId(retryTask.getId());\n\t\tretryTaskPO.setSharding(HostUtils.getHostIP());\n\t\tretryTaskPO.setBizId(retryTask.getBizId());\n\t\tretryTaskPO.setExecutorName(retryTask.getExecutorName());\n\t\tretryTaskPO.setExecutorMethodName(retryTask.getExecutorMethodName());\n\n\t\tMap<String, String> extAttrs = retryTask.getExtAttrs();\n\t\tif (Objects.isNull(extAttrs)) {\n\t\t\textAttrs = Maps.newHashMap();\n\t\t}\n\t\textAttrs.put(\"onFailureMethod\", retryTask.getOnFailureMethod());\n\t\tretryTaskPO.setExtAttrs(JSON.toJSONString(extAttrs));\n\t\tretryTaskPO.setRetryStatus(retryTask.getStatus().getCode());\n\t\tretryTaskPO.setArgsStr(retryTask.getArgsStr());\n\t\tretryTaskPO.setGmtCreate(retryTask.getGmtCreate());\n\t\tretryTaskPO.setGmtModified(retryTask.getGmtModified());\n\t\treturn retryTaskPO;\n\t}\n\n}\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/common/utils/HostUtils.java",
    "content": "package com.alibaba.easyretry.extension.mybatis.common.utils;\n\nimport java.net.InetAddress;\nimport java.net.UnknownHostException;\nimport java.util.Objects;\n\npublic class HostUtils {\n\n\tprivate static final String IP;\n\n\tstatic {\n\t\tInetAddress address = null;\n\t\ttry {\n\t\t\taddress = InetAddress.getLocalHost();\n\t\t} catch (UnknownHostException e) {\n\t\t\t// do noting\n\t\t}\n\t\tif (Objects.isNull(address)) {\n\t\t\tIP = \"UNKNOW-IP\";\n\t\t} else {\n\t\t\tIP = address.getHostAddress();\n\t\t}\n\t}\n\n\tpublic static String getHostIP() {\n\t\treturn IP;\n\t}\n}\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/dao/BaseDAOSupport.java",
    "content": "package com.alibaba.easyretry.extension.mybatis.dao;\n\nimport java.util.Objects;\nimport java.util.function.Function;\n\nimport org.apache.ibatis.session.SqlSession;\nimport org.apache.ibatis.session.SqlSessionFactory;\n\n/**\n * @author wuhao\n */\npublic abstract class BaseDAOSupport {\n\n\tprivate final SqlSessionFactory sqlSessionFactory;\n\n\tpublic BaseDAOSupport(SqlSessionFactory sqlSessionFactory) {\n\t\tthis.sqlSessionFactory = sqlSessionFactory;\n\t}\n\n\tprotected <T> T execute(Function<SqlSession, T> function) {\n\t\tObjects.requireNonNull(sqlSessionFactory, \"require sqlSessionFactory non null\");\n\t\ttry (final SqlSession session = sqlSessionFactory.openSession(false)) {\n\t\t\treturn function.apply(session);\n\t\t}\n\t}\n\n\tprotected <T> T execute(Function<SqlSession, T> function, boolean autoCommit) {\n\t\tObjects.requireNonNull(sqlSessionFactory, \"require sqlSessionFactory non null\");\n\t\ttry (final SqlSession session = sqlSessionFactory.openSession(autoCommit)) {\n\t\t\treturn function.apply(session);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/dao/RetryTaskDAO.java",
    "content": "package com.alibaba.easyretry.extension.mybatis.dao;\n\nimport java.util.List;\n\nimport com.alibaba.easyretry.extension.mybatis.po.RetryTaskPO;\nimport com.alibaba.easyretry.extension.mybatis.query.RetryTaskQuery;\n\n/**\n * @author Created by wuhao on 2020/11/8.\n */\npublic interface RetryTaskDAO {\n\n\tboolean saveRetryTask(RetryTaskPO retryTaskPO);\n\n\tList<RetryTaskPO> listRetryTask(RetryTaskQuery retryTaskQuery);\n\n\tboolean updateRetryTask(RetryTaskPO retryTaskPO);\n\n\tboolean deleteRetryTask(RetryTaskPO retryTaskPO);\n}\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/dao/RetryTaskDAOImpl.java",
    "content": "package com.alibaba.easyretry.extension.mybatis.dao;\n\nimport java.util.List;\n\nimport com.alibaba.easyretry.extension.mybatis.po.RetryTaskPO;\nimport com.alibaba.easyretry.extension.mybatis.query.RetryTaskQuery;\n\nimport java.util.List;\n\nimport org.apache.ibatis.session.SqlSessionFactory;\n\n/**\n * @author Created by wuhao on 2020/11/8.\n */\npublic class RetryTaskDAOImpl extends BaseDAOSupport implements RetryTaskDAO {\n\n\tpublic RetryTaskDAOImpl(SqlSessionFactory sqlSessionFactory) {\n\t\tsuper(sqlSessionFactory);\n\t}\n\n\t@Override\n\tpublic boolean saveRetryTask(RetryTaskPO retryTaskPO) {\n\t\treturn execute(\n\t\t\tsqlSession ->\n\t\t\t\tsqlSession.insert(\"com.alibaba.easyretry.extension.mybatis.dao.RetryTaskDAO.saveRetryTask\", retryTaskPO) > 0\n\t\t\t, true);\n\t}\n\n\t@Override\n\tpublic List<RetryTaskPO> listRetryTask(RetryTaskQuery retryTaskQuery) {\n\t\treturn execute(sqlSession ->\n\t\t\tsqlSession.selectList(\n\t\t\t\t\"com.alibaba.easyretry.extension.mybatis.dao.RetryTaskDAO.listRetryTask\",\n\t\t\t\tretryTaskQuery)\n\t\t);\n\t}\n\n\t@Override\n\tpublic boolean updateRetryTask(RetryTaskPO retryTaskPO) {\n\t\treturn execute(sqlSession ->\n\t\t\t\tsqlSession.update(\n\t\t\t\t\t\"com.alibaba.easyretry.extension.mybatis.dao.RetryTaskDAO.updateRetryTask\",\n\t\t\t\t\tretryTaskPO)\n\t\t\t\t\t> 0\n\t\t\t, true);\n\t}\n\n\t@Override\n\tpublic boolean deleteRetryTask(RetryTaskPO retryTaskPO) {\n\t\treturn execute(sqlSession ->\n\t\t\t\tsqlSession.delete(\n\t\t\t\t\t\"com.alibaba.easyretry.extension.mybatis.dao.RetryTaskDAO.deleteRetryTask\",\n\t\t\t\t\tretryTaskPO)\n\t\t\t\t\t> 0\n\t\t\t, true);\n\t}\n}\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/po/RetryTaskPO.java",
    "content": "package com.alibaba.easyretry.extension.mybatis.po;\n\nimport java.util.Date;\n\nimport com.alibaba.easyretry.common.constant.enums.RetryTaskStatusEnum;\n\nimport lombok.Data;\nimport lombok.experimental.Accessors;\n\n/**\n * @author Created by wuhao on 2020/11/8.\n */\n@Data\n@Accessors(chain = true)\npublic class RetryTaskPO {\n\n\t/**\n\t * 主键id\n\t */\n\tprivate Long id;\n\n\t/**\n\t * 分片id\n\t */\n\tprivate String sharding;\n\n\t/**\n\t * 业务信息\n\t */\n\tprivate String bizId;\n\n\t/**\n\t * 执行者名称\n\t */\n\tprivate String executorName;\n\n\t/**\n\t * 执行者方法\n\t */\n\tprivate String executorMethodName;\n\n\t/**\n\t * @see RetryTaskStatusEnum\n\t */\n\tprivate Integer retryStatus;\n\n\tprivate String argsStr;\n\n\tprivate Date gmtCreate;\n\n\tprivate Date gmtModified;\n\n\tprivate String extAttrs;\n}\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/main/java/com/alibaba/easyretry/extension/mybatis/query/RetryTaskQuery.java",
    "content": "package com.alibaba.easyretry.extension.mybatis.query;\n\nimport java.util.List;\n\nimport lombok.Data;\nimport lombok.experimental.Accessors;\n\n/**\n * @author Created by wuhao on 2020/11/8.\n */\n@Data\n@Accessors(chain = true)\npublic class RetryTaskQuery {\n\n\tprivate Long lastId;\n\n\tprivate List<Integer> retryStatus;\n\n\tprivate String sharding;\n}\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/main/resources/dal/easyretry/easy-mybatis-config.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE configuration\n\tPUBLIC \"-//mybatis.org//DTD Config 3.0//EN\"\n\t\"http://mybatis.org/dtd/mybatis-3-config.dtd\">\n<configuration>\n\n\t<settings>\n\t\t<setting name=\"cacheEnabled\" value=\"true\"/>\n\t\t<setting name=\"defaultStatementTimeout\" value=\"3000\"/>\n\t\t<setting name=\"mapUnderscoreToCamelCase\" value=\"true\"/>\n\t\t<setting name=\"useGeneratedKeys\" value=\"true\"/>\n\t</settings>\n\n\t<typeAliases>\n\t</typeAliases>\n\n\t<typeHandlers>\n\t</typeHandlers>\n\n\t<mappers>\n\t\t<mapper resource=\"dal/easyretry/mapper/easy-retry-task-mapper.xml\"/>\n\t</mappers>\n\n\n</configuration>\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/main/resources/dal/easyretry/mapper/easy-retry-task-mapper.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\"\n\t\"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n<mapper namespace=\"com.alibaba.easyretry.extension.mybatis.dao.RetryTaskDAO\">\n\n\t<resultMap id=\"RetryTaskMAP\" type=\"com.alibaba.easyretry.extension.mybatis.po.RetryTaskPO\">\n\t\t<result column=\"id\" property=\"id\"/>\n\t\t<result column=\"sharding\" property=\"sharding\"/>\n\t\t<result column=\"biz_id\" property=\"bizId\"/>\n\t\t<result column=\"executor_name\" property=\"executorName\"/>\n\t\t<result column=\"executor_method_name\" property=\"executorMethodName\"/>\n\t\t<result column=\"retry_status\" property=\"retryStatus\"/>\n\t\t<result column=\"args_str\" property=\"argsStr\"/>\n\t\t<result column=\"gmt_create\" property=\"gmtCreate\"/>\n\t\t<result column=\"gmt_modified\" property=\"gmtModified\"/>\n\t\t<result column=\"ext_attrs\" property=\"extAttrs\"/>\n\t</resultMap>\n\n\t<sql id=\"all_column\">\n\t\t`id`\n\t\t,\n\t\t`sharding`,\n\t\t`biz_id`,\n\t\t`executor_name`,\n\t\t`executor_method_name`,\n\t\t`retry_status`,\n\t\t`args_str`,\n\t\t`gmt_create`,\n\t\t`gmt_modified`,\n\t\t`ext_attrs`\n\t</sql>\n\n\t<insert id=\"saveRetryTask\">\n\t\tINSERT INTO easy_retry_task (`id`,\n\t\t\t\t\t\t\t\t\t `sharding`,\n\t\t\t\t\t\t\t\t\t `biz_id`,\n\t\t\t\t\t\t\t\t\t `executor_name`,\n\t\t\t\t\t\t\t\t\t `executor_method_name`,\n\t\t\t\t\t\t\t\t\t `retry_status`,\n\t\t\t\t\t\t\t\t\t `args_str`,\n\t\t\t\t\t\t\t\t\t `gmt_create`,\n\t\t\t\t\t\t\t\t\t `gmt_modified`,\n\t\t\t\t\t\t\t\t\t `ext_attrs`)\n\t\tVALUES (#{id},\n\t\t\t\t#{sharding},\n\t\t\t\t#{bizId},\n\t\t\t\t#{executorName},\n\t\t\t\t#{executorMethodName},\n\t\t\t\t#{retryStatus},\n\t\t\t\t#{argsStr},\n\t\t\t\t#{gmtCreate},\n\t\t\t\t#{gmtModified},\n\t\t\t\t#{extAttrs})\n\t</insert>\n\n\t<select id=\"listRetryTask\"\n\t\t\tparameterType=\"com.alibaba.easyretry.extension.mybatis.query.RetryTaskQuery\"\n\t\t\tresultMap=\"RetryTaskMAP\">\n\t\tSELECT * FROM easy_retry_task\n\t\t<where>\n\t\t\t<if test=\"sharding != null\">\n\t\t\t\tsharding = #{sharding}\n\t\t\t</if>\n\n\t\t\t<if test=\"retryStatus != null\">\n\t\t\t\tAND retry_status IN\n\t\t\t\t<foreach close=\")\" collection=\"retryStatus\" item=\"item\" open=\"(\" separator=\",\">\n\t\t\t\t\t#{item}\n\t\t\t\t</foreach>\n\t\t\t</if>\n\n\t\t\t<if test=\"lastId != null\">\n\t\t\t\tAND id > #{lastId}\n\t\t\t</if>\n\t\t</where>\n\t\torder by id Asc limit 500\n\t</select>\n\n\t<update id=\"updateRetryTask\"\n\t\t\tparameterType=\"com.alibaba.easyretry.extension.mybatis.po.RetryTaskPO\">\n\t\tUPDATE easy_retry_task\n\t\tSET\n\t\tgmt_modified = now()\n\t\t<if test=\"retryStatus != null\">\n\t\t\t,retry_status = #{retryStatus}\n\t\t</if>\n\t\tWHERE\n\t\tid=#{id}\n\t</update>\n\n\t<delete id=\"deleteRetryTask\"\n\t\t\tparameterType=\"com.alibaba.easyretry.extension.mybatis.po.RetryTaskPO\">\n\t\tDELETE\n\t\tFROM easy_retry_task\n\t\tWHERE id = #{id}\n\t</delete>\n\n</mapper>"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/test/java/com/alibaba/easyretry/extension/mybatis/DbConfig.java",
    "content": "package com.alibaba.easyretry.extension.mybatis;\n\nimport javax.sql.DataSource;\n\nimport com.zaxxer.hikari.HikariConfig;\nimport com.zaxxer.hikari.HikariDataSource;\nimport lombok.Getter;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic final class DbConfig {\n\n\t@Getter\n\tprivate static final DataSource dataSource;\n\n\tstatic {\n\t\tString url = \"jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;INIT=runscript from 'classpath:/task.sql'\";\n\t\tHikariConfig config = new HikariConfig();\n\t\tconfig.setJdbcUrl(url);\n\t\tconfig.setUsername(\"sa\");\n\t\tconfig.setDriverClassName(\"org.h2.Driver\");\n\t\tconfig.setPassword(\"sa\");\n\t\tconfig.addDataSourceProperty(\"cachePrepStmts\", \"true\");\n\t\tconfig.addDataSourceProperty(\"prepStmtCacheSize\", \"250\");\n\t\tconfig.addDataSourceProperty(\"prepStmtCacheSqlLimit\", \"2048\");\n\t\tdataSource = new HikariDataSource(config);\n\t}\n\n\t@Test\n\tvoid test() {\n\t\tAssertions.assertNotNull(DbConfig.getDataSource());\n\t}\n}\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/test/java/com/alibaba/easyretry/extension/mybatis/MyBatisConfig.java",
    "content": "package com.alibaba.easyretry.extension.mybatis;\n\nimport java.io.IOException;\n\nimport lombok.Getter;\nimport org.apache.ibatis.builder.xml.XMLConfigBuilder;\nimport org.apache.ibatis.io.Resources;\nimport org.apache.ibatis.logging.slf4j.Slf4jImpl;\nimport org.apache.ibatis.mapping.Environment;\nimport org.apache.ibatis.session.Configuration;\nimport org.apache.ibatis.session.SqlSessionFactory;\nimport org.apache.ibatis.session.SqlSessionFactoryBuilder;\nimport org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic final class MyBatisConfig {\n\n\t@Getter\n\tprivate static final SqlSessionFactory factory;\n\n\tstatic {\n\t\tString resource = \"dal/easyretry/easy-mybatis-config.xml\";\n\t\tConfiguration parse;\n\t\ttry {\n\t\t\tXMLConfigBuilder parser = new XMLConfigBuilder(Resources.getResourceAsStream(resource),\n\t\t\t\tnull, null);\n\t\t\tparse = parser.parse();\n\t\t} catch (IOException e) {\n\t\t\tthrow new RuntimeException(e);\n\t\t}\n\t\tfinal Environment development = new Environment(\"development\",\n\t\t\tnew JdbcTransactionFactory(), DbConfig.getDataSource());\n\t\tparse.setEnvironment(development);\n\t\tparse.setLogImpl(Slf4jImpl.class);\n\t\tfactory = new SqlSessionFactoryBuilder().build(parse);\n\t}\n\n\t@Test\n\tvoid testNotNull() {\n\t\tAssertions.assertNotNull(MyBatisConfig.getFactory());\n\t}\n}\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/test/java/com/alibaba/easyretry/extension/mybatis/access/MybatisRetryTaskAccessTest.java",
    "content": "package com.alibaba.easyretry.extension.mybatis.access;\n\nimport java.util.Date;\nimport java.util.List;\nimport java.util.Objects;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.MethodOrderer;\nimport org.junit.jupiter.api.Order;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.TestMethodOrder;\n\nimport com.alibaba.easyretry.common.constant.enums.RetryTaskStatusEnum;\nimport com.alibaba.easyretry.common.entity.RetryTask;\nimport com.alibaba.easyretry.extension.mybatis.MyBatisConfig;\nimport com.alibaba.easyretry.extension.mybatis.dao.RetryTaskDAOImpl;\n\n@TestMethodOrder(MethodOrderer.OrderAnnotation.class)\nclass MybatisRetryTaskAccessTest {\n\n\tprivate static final MybatisRetryTaskAccess ACCESS = new MybatisRetryTaskAccess(\n\t\tnew RetryTaskDAOImpl(\n\t\t\tMyBatisConfig.getFactory()));\n\n\tprivate static RetryTask task;\n\n\t@BeforeAll\n\tstatic void prepare() {\n\t\tRetryTask retryTask = new RetryTask();\n\t\tretryTask.setId(2L);\n\t\tretryTask.setGmtCreate(new Date());\n\t\tretryTask.setGmtModified(new Date());\n\t\tretryTask.setBizId(\"2\");\n\t\tretryTask.setStatus(RetryTaskStatusEnum.INIT);\n\t\ttask = retryTask;\n\t}\n\n\t@Test\n\t@Order(1)\n\tvoid saveTask() {\n\t\tAssertions.assertTrue(ACCESS.saveRetryTask(task));\n\t}\n\n\t@Test\n\t@Order(2)\n\tvoid handle() {\n//\t\tACCESS.saveRetryTask(task);\n\t\tAssertions.assertTrue(ACCESS.handlingRetryTask(task));\n\t\tList<RetryTask> retryTasks = ACCESS.listAvailableTasks(1L);\n\t\tAssertions.assertTrue(Objects.nonNull(retryTasks) && !retryTasks.isEmpty());\n\t\tAssertions.assertEquals(retryTasks.get(0).getStatus(), RetryTaskStatusEnum.HANDLING);\n\t}\n\n\t@Test\n\t@Order(3)\n\tvoid stop() {\n//\t\tACCESS.saveRetryTask(task);\n\t\tboolean b = ACCESS.stopRetryTask(task);\n\t\tAssertions.assertTrue(b);\n\t\tList<RetryTask> retryTasks = ACCESS.listAvailableTasks(1L);\n\t\tAssertions.assertTrue(Objects.isNull(retryTasks) || retryTasks.isEmpty());\n\t}\n\n\t@Test\n\t@Order(4)\n\tvoid finish(){\n//\t\tACCESS.saveRetryTask(task);\n\t\tAssertions.assertTrue(ACCESS.finishRetryTask(task));\n\t\tList<RetryTask> retryTasks = ACCESS.listAvailableTasks(1L);\n\t\tAssertions.assertTrue(Objects.isNull(retryTasks) || retryTasks.isEmpty());\n\t}\n}\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/test/java/com/alibaba/easyretry/extension/mybatis/common/utils/HostUtilsTest.java",
    "content": "package com.alibaba.easyretry.extension.mybatis.common.utils;\n\nimport org.junit.jupiter.api.Test;\n\nimport static org.junit.jupiter.api.Assertions.assertNotNull;\n\nclass HostUtilsTest {\n\n\t@Test\n\tvoid getHostIP() {\n\t\tString hostIP = HostUtils.getHostIP();\n\t\tassertNotNull(hostIP);\n\t}\n}\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/test/java/com/alibaba/easyretry/extension/mybatis/dao/RetryTaskDAOImplTest.java",
    "content": "package com.alibaba.easyretry.extension.mybatis.dao;\n\nimport java.util.Collections;\nimport java.util.Date;\nimport java.util.List;\nimport java.util.Objects;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Order;\nimport org.junit.jupiter.api.Test;\n\nimport com.alibaba.easyretry.common.constant.enums.RetryTaskStatusEnum;\nimport com.alibaba.easyretry.extension.mybatis.MyBatisConfig;\nimport com.alibaba.easyretry.extension.mybatis.po.RetryTaskPO;\nimport com.alibaba.easyretry.extension.mybatis.query.RetryTaskQuery;\n\nclass RetryTaskDAOImplTest {\n\n\tprivate static RetryTaskDAO retryTaskDAO;\n\n\t@BeforeAll\n\tstatic void prepare() {\n\t\tretryTaskDAO = new RetryTaskDAOImpl(MyBatisConfig.getFactory());\n\t}\n\n\t@Test\n\t@Order(1)\n\tvoid saveTask() {\n\t\tfinal RetryTaskPO retryTaskPO = new RetryTaskPO()\n\t\t\t.setId(1L)\n\t\t\t.setGmtCreate(new Date())\n\t\t\t.setBizId(\"1\")\n\t\t\t.setRetryStatus(RetryTaskStatusEnum.HANDLING.getCode())\n\t\t\t.setGmtModified(new Date());\n\n\t\tfinal boolean result = retryTaskDAO.saveRetryTask(retryTaskPO);\n\t\tAssertions.assertTrue(result);\n\t}\n\n\t@Test\n\t@Order(2)\n\tvoid listRetryTask() {\n\t\tfinal RetryTaskPO retryTaskPO = new RetryTaskPO()\n\t\t\t.setId(2L)\n\t\t\t.setGmtCreate(new Date())\n\t\t\t.setBizId(\"2\")\n\t\t\t.setRetryStatus(RetryTaskStatusEnum.HANDLING.getCode())\n\t\t\t.setGmtModified(new Date());\n\n\t\tretryTaskDAO.saveRetryTask(retryTaskPO);\n\t\tfinal RetryTaskQuery retryTaskQuery = new RetryTaskQuery()\n\t\t\t.setRetryStatus(Collections.singletonList(RetryTaskStatusEnum.HANDLING.getCode()));\n\t\tList<RetryTaskPO> retryTaskPOS = retryTaskDAO.listRetryTask(retryTaskQuery);\n\t\tSystem.out.println(retryTaskPOS);\n\t\tAssertions.assertTrue(!retryTaskPOS.isEmpty());\n\t\tAssertions.assertTrue(Objects.nonNull(retryTaskPOS));\n\t\t// Assertions.assertTrue(Objects.nonNull(retryTaskPOS) && !retryTaskPOS.isEmpty());\n\t}\n\n\t@Test\n\t@Order(3)\n\tvoid updateRetryTask() {\n\t\t//final RetryTaskPO retryTaskPO = new RetryTaskPO()\n\t\t//\t.setId(1L)\n\t\t//\t.setBizId(\"1\")\n\t\t//\t.setRetryStatus(RetryTaskStatusEnum.FINISH.getCode())\n\t\t//\t.setGmtModified(new Date());\n\t\t//\n\t\t//boolean b = retryTaskDAO.updateRetryTask(retryTaskPO);\n\t\t//Assertions.assertTrue(b);\n\t\t//\n\t\t//final RetryTaskQuery retryTaskQuery = new RetryTaskQuery()\n\t\t//\t.setRetryStatus(Collections.singletonList(RetryTaskStatusEnum.FINISH.getCode()));\n\t\t//List<RetryTaskPO> retryTaskPOS = retryTaskDAO.listRetryTask(retryTaskQuery);\n\t\t//System.out.println(retryTaskPOS);\n\t\t//Assertions.assertTrue(Objects.nonNull(retryTaskPOS) && !retryTaskPOS.isEmpty());\n\t}\n\n\t@Test\n\t@Order(4)\n\tvoid deleteRetryTask() {\n\t\tfinal RetryTaskPO retryTaskPO = new RetryTaskPO()\n\t\t\t.setId(3L)\n\t\t\t.setGmtCreate(new Date())\n\t\t\t.setBizId(\"3\")\n\t\t\t.setRetryStatus(RetryTaskStatusEnum.HANDLING.getCode())\n\t\t\t.setGmtModified(new Date());\n\n\t\tretryTaskDAO.saveRetryTask(retryTaskPO);\n\t\tboolean b = retryTaskDAO.deleteRetryTask(retryTaskPO);\n\t\tAssertions.assertTrue(b);\n\n\t\tfinal RetryTaskQuery retryTaskQuery = new RetryTaskQuery()\n\t\t\t.setRetryStatus(Collections.singletonList(RetryTaskStatusEnum.FINISH.getCode()));\n\t\tList<RetryTaskPO> retryTaskPOS = retryTaskDAO.listRetryTask(retryTaskQuery);\n\t\tSystem.out.println(retryTaskPOS);\n\t\tAssertions.assertTrue(Objects.isNull(retryTaskPOS) || retryTaskPOS.isEmpty());\n\t}\n\n}\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/test/resources/logback.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration>\n\n\t<appender name=\"CONSOLE\" class=\"ch.qos.logback.core.ConsoleAppender\">\n\t\t<encoder>\n\t\t\t<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>\n\t\t</encoder>\n\t</appender>\n\n\t<root level=\"DEBUG\">\n\t\t<appender-ref ref=\"CONSOLE\" />\n\t</root>\n</configuration>\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-mybatis-extension/src/test/resources/task.sql",
    "content": "CREATE TABLE IF NOT EXISTS easy_retry_task (\n    id bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键' PRIMARY KEY,\n    gmt_create datetime NOT NULL COMMENT '创建时间',\n    gmt_modified datetime NOT NULL COMMENT '修改时间',\n    sharding varchar(64) NULL COMMENT '数据库分片字段',\n    biz_id varchar(64) NULL COMMENT '业务id',\n    executor_name varchar(512) NULL COMMENT '执行名称',\n    executor_method_name varchar(512) NULL COMMENT '执行方法名称',\n    retry_status tinyint NOT NULL COMMENT '重试状态',\n    args_str varchar(3000) NULL COMMENT '执行方法参数',\n    ext_attrs varchar(3000) NULL COMMENT '扩展字段'\n);\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-spring-extension/pom.xml",
    "content": "<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:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<parent>\n\t\t<groupId>com.alibaba</groupId>\n\t\t<artifactId>easy-retry-extensions</artifactId>\n\t\t<version>${revision}</version>\n\t\t<relativePath>../pom.xml</relativePath>\n\t</parent>\n\n\t<artifactId>easy-retry-spring-extension</artifactId>\n\n\t<name>easy-retry-spring-extension</name>\n\t<description>easy-retry-spring-extension</description>\n\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>${project.groupId}</groupId>\n\t\t\t<artifactId>easy-retry-common</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>${project.groupId}</groupId>\n\t\t\t<artifactId>easy-retry-core</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>com.google.guava</groupId>\n\t\t\t<artifactId>guava</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>org.springframework</groupId>\n\t\t\t<artifactId>spring-context</artifactId>\n\t\t\t<version>5.1.12.RELEASE</version>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>org.springframework</groupId>\n\t\t\t<artifactId>spring-core</artifactId>\n\t\t\t<version>5.1.12.RELEASE</version>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>org.aspectj</groupId>\n\t\t\t<artifactId>aspectjweaver</artifactId>\n\t\t\t<version>1.9.5</version>\n\t\t</dependency>\n\t</dependencies>\n</project>\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/RetryListenerInitialize.java",
    "content": "package com.alibaba.easyretry.extension.spring;\n\nimport java.util.Map;\n\nimport com.alibaba.easyretry.common.event.RetryEventMulticaster;\nimport com.alibaba.easyretry.common.event.RetryListener;\n\nimport lombok.Setter;\nimport org.apache.commons.collections4.MapUtils;\nimport org.springframework.beans.BeansException;\nimport org.springframework.beans.factory.SmartInitializingSingleton;\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.ApplicationContextAware;\n\n/**\n * @author Created by wuhao on 2021/4/9.\n */\npublic class RetryListenerInitialize implements SmartInitializingSingleton, ApplicationContextAware {\n\n\t@Setter\n\tprivate RetryEventMulticaster retryEventMulticaster;\n\n\tprivate ApplicationContext applicationContext;\n\n\t@Override\n\tpublic void afterSingletonsInstantiated() {\n\t\tMap<String, RetryListener> retryListenerMap = applicationContext.getBeansOfType(RetryListener.class);\n\t\tMapUtils.emptyIfNull(retryListenerMap).values().forEach(\n\t\t\t(retryListener) -> retryEventMulticaster.register(retryListener));\n\t}\n\n\t@Override\n\tpublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {\n\t\tthis.applicationContext = applicationContext;\n\t}\n\n}\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/SPELParamPredicate.java",
    "content": "package com.alibaba.easyretry.extension.spring;\n\nimport java.lang.reflect.Method;\n\nimport com.alibaba.easyretry.common.EasyRetryPredicate;\n\nimport lombok.Data;\nimport org.apache.commons.lang3.ArrayUtils;\nimport org.springframework.core.DefaultParameterNameDiscoverer;\nimport org.springframework.expression.ExpressionParser;\nimport org.springframework.expression.spel.standard.SpelExpressionParser;\nimport org.springframework.expression.spel.support.StandardEvaluationContext;\n\n/**\n * @author Created by wuhao on 2021/3/18.\n */\n@Data\npublic class SPELParamPredicate implements EasyRetryPredicate<Object[], String> {\n\n\tprivate static DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();\n\n\tprivate String bizIdCondition;\n\n\tprivate Method method;\n\n\tpublic SPELParamPredicate(String bizIdCondition, Method method) {\n\t\tthis.bizIdCondition = bizIdCondition;\n\t\tthis.method = method;\n\t}\n\n\tpublic SPELParamPredicate() {\n\t}\n\n\t@Override\n\tpublic String apply(Object[] params) {\n\t\tExpressionParser parser = new SpelExpressionParser();\n\t\tStandardEvaluationContext context = new StandardEvaluationContext();\n\t\tString[] paramNameArr = discoverer.getParameterNames(method);\n\t\tif (ArrayUtils.isEmpty(paramNameArr)) {\n\t\t\treturn null;\n\t\t}\n\t\tfor (int i = 0; i < paramNameArr.length; i++) {\n\t\t\tcontext.setVariable(paramNameArr[i], params[i]);\n\t\t}\n\t\treturn parser.parseExpression(bizIdCondition).getValue(context, String.class);\n\t}\n}\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/SPELResultPredicate.java",
    "content": "package com.alibaba.easyretry.extension.spring;\n\nimport com.alibaba.easyretry.common.AbstractResultPredicate;\n\nimport lombok.Data;\nimport org.springframework.expression.ExpressionParser;\nimport org.springframework.expression.spel.standard.SpelExpressionParser;\nimport org.springframework.expression.spel.support.StandardEvaluationContext;\n\n/**\n * @author Created by wuhao on 2021/3/18.\n */\n@Data\npublic class SPELResultPredicate<T> extends AbstractResultPredicate<T> {\n\n\tprivate String resultCondition;\n\n\tpublic SPELResultPredicate(String resultCondition) {\n\t\tthis.resultCondition = resultCondition;\n\t}\n\n\tpublic SPELResultPredicate() {\n\t}\n\n\t@Override\n\tpublic Boolean apply(T result) {\n\t\tExpressionParser parser = new SpelExpressionParser();\n\t\tStandardEvaluationContext context = new StandardEvaluationContext();\n\t\tcontext.setVariable(\"result\", result);\n\t\treturn parser.parseExpression(resultCondition).getValue(context, Boolean.class);\n\t}\n}\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/SpringEventApplicationListener.java",
    "content": "package com.alibaba.easyretry.extension.spring;\n\nimport org.springframework.beans.factory.SmartInitializingSingleton;\n\nimport com.alibaba.easyretry.common.filter.RetryFilterInvocationHandler;\nimport com.alibaba.easyretry.common.filter.RetryFilterRegisterHandler;\n\nimport lombok.Setter;\n\n/**\n * @author Created by wuhao on 2021/4/9.\n */\npublic class SpringEventApplicationListener implements SmartInitializingSingleton {\n\n\t@Setter\n\tprivate RetryFilterInvocationHandler retryFilterInvocationHandler;\n\n\t@Setter\n\tprivate RetryFilterRegisterHandler retryFilterRegisterHandler;\n\n\n\t@Override\n\tpublic void afterSingletonsInstantiated() {\n\t\tretryFilterRegisterHandler.handle();\n\t\tretryFilterInvocationHandler.handle();\n\t}\n}\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/SpringRetryFilterDiscover.java",
    "content": "package com.alibaba.easyretry.extension.spring;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport com.alibaba.easyretry.common.filter.RetryFilter;\nimport com.alibaba.easyretry.common.filter.RetryFilterDiscover;\n\nimport com.google.common.collect.Lists;\nimport org.springframework.beans.BeansException;\nimport org.springframework.beans.factory.SmartInitializingSingleton;\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.ApplicationContextAware;\n\n/**\n * @author Created by wuhao on 2021/4/9.\n */\npublic class SpringRetryFilterDiscover implements RetryFilterDiscover, SmartInitializingSingleton,\n\tApplicationContextAware {\n\n\tprivate List<RetryFilter> retryFilters;\n\n\tprivate ApplicationContext applicationContext;\n\n\t@Override\n\tpublic List<RetryFilter> discoverAll() {\n\t\treturn retryFilters;\n\t}\n\n\t@Override\n\tpublic void afterSingletonsInstantiated() {\n\t\tMap<String, RetryFilter> retryFilterMap = applicationContext.getBeansOfType(RetryFilter.class);\n\t\tretryFilters = Lists.newArrayList(retryFilterMap.values());\n\t}\n\n\t@Override\n\tpublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {\n\t\tthis.applicationContext = applicationContext;\n\t}\n}\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/aop/EasyRetryable.java",
    "content": "package com.alibaba.easyretry.extension.spring.aop;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\nimport com.alibaba.easyretry.common.constant.enums.RetryTypeEnum;\n\n@Target({ElementType.METHOD})\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface EasyRetryable {\n\n\t/**\n\t * 处理完成以后是否需要把异常重新抛出\n\t *\n\t * @return 是否需要抛出异\n\t */\n\tboolean reThrowException() default false;\n\n\t/**\n\t * 通过结果判断是否重试\n\t */\n\tString resultCondition() default \"\";\n\n\t/**\n\t * 重试种类\n\t */\n\tRetryTypeEnum retryType() default RetryTypeEnum.ASYNC;\n\n}\n"
  },
  {
    "path": "easy-retry-extensions/easy-retry-spring-extension/src/main/java/com/alibaba/easyretry/extension/spring/aop/RetryInterceptor.java",
    "content": "package com.alibaba.easyretry.extension.spring.aop;\n\nimport java.lang.reflect.Method;\nimport java.util.Objects;\n\nimport com.alibaba.easyretry.common.RetryConfiguration;\nimport com.alibaba.easyretry.common.RetryIdentify;\nimport com.alibaba.easyretry.common.retryer.Retryer;\nimport com.alibaba.easyretry.core.RetryerBuilder;\nimport com.alibaba.easyretry.extension.spring.SPELResultPredicate;\n\nimport lombok.Setter;\nimport org.apache.commons.lang3.StringUtils;\nimport org.aspectj.lang.ProceedingJoinPoint;\nimport org.aspectj.lang.annotation.Around;\nimport org.aspectj.lang.annotation.Aspect;\nimport org.aspectj.lang.reflect.MethodSignature;\nimport org.springframework.context.ApplicationContext;\n\n@Aspect\npublic class RetryInterceptor {\n\n\t@Setter\n\tprivate RetryConfiguration retryConfiguration;\n\n\t@Setter\n\tprivate ApplicationContext applicationContext;\n\n\t@Around(\"@annotation(retryable)\")\n\tpublic Object around(ProceedingJoinPoint invocation, EasyRetryable retryable) throws Throwable {\n\t\tif (RetryIdentify.isOnRetry()) {\n\t\t\treturn invocation.proceed();\n\t\t}\n\n\t\tRetryer<Object> retryer = determineTargetRetryer(invocation, retryable);\n\t\treturn retryer.call(invocation::proceed);\n\t}\n\n\tprivate String getBeanId(Class<?> type) {\n\t\tString[] names = applicationContext.getBeanNamesForType(type);\n\t\treturn names.length > 0 ? names[0] : null;\n\t}\n\n\tprivate Retryer<Object> determineTargetRetryer(ProceedingJoinPoint invocation, EasyRetryable retryable) {\n\t\tMethodSignature signature = (MethodSignature)invocation.getSignature();\n\t\tRetryerBuilder<Object> retryerBuilder = new RetryerBuilder<Object>()\n\t\t\t.withExecutorName(getBeanId(signature.getDeclaringType()))\n\t\t\t.withExecutorMethodName(signature.getMethod().getName())\n\t\t\t.withArgs(invocation.getArgs())\n\t\t\t.withConfiguration(retryConfiguration)\n\t\t\t.withReThrowException(retryable.reThrowException());\n\t\tif (StringUtils.isNotBlank(retryable.resultCondition())) {\n\t\t\tretryerBuilder.withResultPredicate(new SPELResultPredicate<>(retryable.resultCondition()));\n\t\t}\n\n\t\treturn retryerBuilder.build(retryable.retryType());\n\t}\n}\n"
  },
  {
    "path": "easy-retry-extensions/pom.xml",
    "content": "<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:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<parent>\n\t\t<groupId>com.alibaba</groupId>\n\t\t<artifactId>easy-retry</artifactId>\n\t\t<version>${revision}</version>\n\t\t<relativePath>../pom.xml</relativePath>\n\t</parent>\n\n\t<artifactId>easy-retry-extensions</artifactId>\n\t<packaging>pom</packaging>\n\n\t<name>easy-retry-extensions</name>\n\t<description>easy-retry-extensions</description>\n\n\t<modules>\n\t\t<module>easy-retry-spring-extension</module>\n\t\t<module>easy-retry-mybatis-extension</module>\n\t\t<module>easy-retry-guava-extension</module>\n\t</modules>\n\n\t<dependencies>\n\t</dependencies>\n</project>\n\n"
  },
  {
    "path": "easy-retry-starters/easy-retry-memory-starter/pom.xml",
    "content": "<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:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<parent>\n\t\t<groupId>com.alibaba</groupId>\n\t\t<artifactId>easy-retry-starters</artifactId>\n\t\t<version>${revision}</version>\n\t\t<relativePath>../pom.xml</relativePath>\n\t</parent>\n\n\t<artifactId>easy-retry-memory-starter</artifactId>\n\t<name>easy-retry-memory-starter</name>\n\t<description>easy-retry-memory-starter</description>\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t<artifactId>spring-boot-autoconfigure</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>${project.groupId}</groupId>\n\t\t\t<artifactId>easy-retry-spring-extension</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>${project.groupId}</groupId>\n\t\t\t<artifactId>easy-retry-core</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>${project.groupId}</groupId>\n\t\t\t<artifactId>easy-retry-starter-common</artifactId>\n\t\t</dependency>\n\t</dependencies>\n</project>"
  },
  {
    "path": "easy-retry-starters/easy-retry-memory-starter/src/main/java/com/alibaba/easyretry/memory/MemoryAutoConfiguration.java",
    "content": "package com.alibaba.easyretry.memory;\n\nimport com.alibaba.easyretry.common.RetryConfiguration;\nimport com.alibaba.easyretry.common.RetryContainer;\nimport com.alibaba.easyretry.common.RetryExecutor;\nimport com.alibaba.easyretry.core.access.MemoryRetryTaskAccess;\nimport com.alibaba.easyretry.core.container.SimpleRetryContainer;\nimport com.alibaba.easyretry.memory.config.EasyRetryMemoryCompatibleProperties;\nimport com.alibaba.easyretry.starter.common.CommonAutoConfiguration;\nimport lombok.extern.slf4j.Slf4j;\nimport org.springframework.beans.BeansException;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;\nimport org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;\nimport org.springframework.boot.context.properties.EnableConfigurationProperties;\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n/**\n * @author Created by wuhao on 2021/2/19.\n */\n@Configuration\n@Slf4j\n@EnableConfigurationProperties(EasyRetryMemoryCompatibleProperties.class)\n@ConditionalOnProperty(name = \"spring.easyretry.memory.enabled\", havingValue = \"true\")\npublic class MemoryAutoConfiguration extends CommonAutoConfiguration {\n\n\t@Autowired\n\tprivate EasyRetryMemoryCompatibleProperties easyRetryMemoryCompatibleProperties;\n\n\t@Bean\n\t@ConditionalOnMissingBean(MemoryRetryTaskAccess.class)\n\tpublic MemoryRetryTaskAccess retryTaskAccess() {\n\t\treturn new MemoryRetryTaskAccess();\n\t}\n\n\t@Bean(initMethod = \"start\")\n\tpublic RetryContainer retryContainer(\n\t\tRetryConfiguration configuration, RetryExecutor defaultRetryExecutor) {\n\t\tlog.warn(\"RetryConfiguration start\");\n\t\treturn new SimpleRetryContainer(\n\t\t\tconfiguration,\n\t\t\tdefaultRetryExecutor);\n\t}\n\n\t@Override\n\tpublic Integer getMaxRetryTimes() {\n\t\treturn easyRetryMemoryCompatibleProperties.getMaxRetryTimes();\n\t}\n}\n"
  },
  {
    "path": "easy-retry-starters/easy-retry-memory-starter/src/main/java/com/alibaba/easyretry/memory/config/EasyRetryMemoryCompatibleProperties.java",
    "content": "package com.alibaba.easyretry.memory.config;\n\nimport lombok.Data;\nimport org.springframework.boot.context.properties.ConfigurationProperties;\n\n/**\n * @author Created by wuhao on 2021/2/21.\n */\n@ConfigurationProperties(prefix = \"spring.easyretry.memory\")\n@Data\npublic class EasyRetryMemoryCompatibleProperties {\n\n\tprivate Integer maxRetryTimes = 5;\n\n\tprivate String namespace = \"easy-retry\";\n}\n"
  },
  {
    "path": "easy-retry-starters/easy-retry-memory-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json",
    "content": "{\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\": \"enable AmoebaCompatible or not.\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"spring.easyretry.memory.maxRetryTimes\",\n\t\t\t\"type\": \"java.lang.Integer\",\n\t\t\t\"description\": \"definition the maxRetryTimes\"\n\t\t}\n\t]\n}"
  },
  {
    "path": "easy-retry-starters/easy-retry-memory-starter/src/main/resources/META-INF/spring.factories",
    "content": "org.springframework.boot.autoconfigure.EnableAutoConfiguration=\\\ncom.alibaba.easyretry.memory.MemoryAutoConfiguration"
  },
  {
    "path": "easy-retry-starters/easy-retry-mybatis-starter/pom.xml",
    "content": "<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:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<parent>\n\t\t<groupId>com.alibaba</groupId>\n\t\t<artifactId>easy-retry-starters</artifactId>\n\t\t<version>${revision}</version>\n\t\t<relativePath>../pom.xml</relativePath>\n\t</parent>\n\n\t<artifactId>easy-retry-mybatis-starter</artifactId>\n\t<name>easy-retry-mybatis-starter</name>\n\t<description>easy-retry-mybatis-starter</description>\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t<artifactId>spring-boot-autoconfigure</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>com.alibaba</groupId>\n\t\t\t<artifactId>easy-retry-spring-extension</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>${project.groupId}</groupId>\n\t\t\t<artifactId>easy-retry-core</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>${project.groupId}</groupId>\n\t\t\t<artifactId>easy-retry-mybatis-extension</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>org.mybatis</groupId>\n\t\t\t<artifactId>mybatis-spring</artifactId>\n\t\t\t<version>2.0.6</version>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>org.springframework</groupId>\n\t\t\t<artifactId>spring-tx</artifactId>\n\t\t\t<version>5.1.12.RELEASE</version>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>${project.groupId}</groupId>\n\t\t\t<artifactId>easy-retry-starter-common</artifactId>\n\t\t</dependency>\n\n\t</dependencies>\n\n</project>"
  },
  {
    "path": "easy-retry-starters/easy-retry-mybatis-starter/src/main/java/com/alibaba/easyretry/mybatis/MybatisAutoConfiguration.java",
    "content": "package com.alibaba.easyretry.mybatis;\n\nimport com.alibaba.easyretry.common.RetryConfiguration;\nimport com.alibaba.easyretry.common.RetryContainer;\nimport com.alibaba.easyretry.common.RetryExecutor;\nimport com.alibaba.easyretry.common.access.RetryTaskAccess;\nimport com.alibaba.easyretry.core.container.SimpleRetryContainer;\nimport com.alibaba.easyretry.extension.mybatis.access.MybatisRetryTaskAccess;\nimport com.alibaba.easyretry.extension.mybatis.dao.RetryTaskDAO;\nimport com.alibaba.easyretry.extension.mybatis.dao.RetryTaskDAOImpl;\nimport com.alibaba.easyretry.mybatis.conifg.EasyRetryMybatisProperties;\nimport com.alibaba.easyretry.starter.common.CommonAutoConfiguration;\nimport lombok.extern.slf4j.Slf4j;\nimport org.apache.ibatis.session.SqlSessionFactory;\nimport org.mybatis.spring.SqlSessionFactoryBean;\nimport org.springframework.beans.BeansException;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.beans.factory.annotation.Qualifier;\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;\nimport org.springframework.boot.context.properties.EnableConfigurationProperties;\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.io.Resource;\n\nimport javax.sql.DataSource;\n\n/**\n * @author Created by wuhao on 2021/2/19.\n */\n@Configuration\n@Slf4j\n@EnableConfigurationProperties(EasyRetryMybatisProperties.class)\n@ConditionalOnProperty(name = \"spring.easyretry.mybatis.enabled\", matchIfMissing = true)\npublic class MybatisAutoConfiguration extends CommonAutoConfiguration {\n\n\t@Autowired\n\tprivate EasyRetryMybatisProperties easyRetryMybatisProperties;\n\n\t@Value(\"classpath:/dal/easyretry/easy-mybatis-config.xml\")\n\tprivate Resource easyRetryMybatisResouse;\n\n\t@Bean(\"easyRetrySqlSessionFactory\")\n\tpublic SqlSessionFactory sqlSessionFactory(\n\t\t@Qualifier(\"easyRetryMybatisDataSource\") DataSource easyRetryMybatisDataSource)\n\t\tthrows Exception {\n\t\tSqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();\n\t\tsqlSessionFactoryBean.setDataSource(easyRetryMybatisDataSource);\n\t\tsqlSessionFactoryBean.setConfigLocation(easyRetryMybatisResouse);\n\t\treturn sqlSessionFactoryBean.getObject();\n\t}\n\n\t@Bean(initMethod = \"start\")\n\tpublic RetryContainer retryContainer(\n\t\tRetryConfiguration configuration, RetryExecutor defaultRetryExecutor) {\n\t\tlog.warn(\"RetryConfiguration start\");\n\t\treturn new SimpleRetryContainer(\n\t\t\tconfiguration, defaultRetryExecutor);\n\t}\n\n\t@Bean\n\tpublic RetryTaskDAO retryTaskDAO(\n\t\t@Qualifier(\"easyRetrySqlSessionFactory\") SqlSessionFactory sqlSessionFactory) {\n\t\treturn new RetryTaskDAOImpl(sqlSessionFactory);\n\t}\n\n\t@Bean\n\tpublic RetryTaskAccess retryTaskAccess(RetryTaskDAO retryTaskDAO) {\n\t\treturn new MybatisRetryTaskAccess(retryTaskDAO);\n\t}\n\n\t@Override\n\tpublic Integer getMaxRetryTimes() {\n\t\treturn easyRetryMybatisProperties.getMaxRetryTimes();\n\t}\n}\n"
  },
  {
    "path": "easy-retry-starters/easy-retry-mybatis-starter/src/main/java/com/alibaba/easyretry/mybatis/conifg/EasyRetryMybatisProperties.java",
    "content": "package com.alibaba.easyretry.mybatis.conifg;\n\nimport lombok.Data;\nimport org.springframework.boot.context.properties.ConfigurationProperties;\n\n/**\n * @author Created by wuhao on 2021/2/21.\n */\n@ConfigurationProperties(prefix = \"spring.easyretry.mybatis\")\n@Data\npublic class EasyRetryMybatisProperties {\n\n\tprivate Integer maxRetryTimes = 5;\n\n}\n"
  },
  {
    "path": "easy-retry-starters/easy-retry-mybatis-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json",
    "content": "{\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\": \"enable AmoebaCompatible or not.\"\n\t\t},\n\t\t{\n\t\t\t\"name\": \"spring.easyretry.mybatis.maxRetryTimes\",\n\t\t\t\"type\": \"java.lang.Integer\",\n\t\t\t\"description\": \"definition the maxRetryTimes\"\n\t\t}\n\t]\n}"
  },
  {
    "path": "easy-retry-starters/easy-retry-mybatis-starter/src/main/resources/META-INF/spring.factories",
    "content": "org.springframework.boot.autoconfigure.EnableAutoConfiguration=\\\ncom.alibaba.easyretry.mybatis.MybatisAutoConfiguration"
  },
  {
    "path": "easy-retry-starters/easy-retry-starter-common/pom.xml",
    "content": "<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:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<parent>\n\t\t<groupId>com.alibaba</groupId>\n\t\t<artifactId>easy-retry-starters</artifactId>\n\t\t<version>${revision}</version>\n\t\t<relativePath>../pom.xml</relativePath>\n\t</parent>\n\n\t<artifactId>easy-retry-starter-common</artifactId>\n\t<name>easy-retry-starter-common</name>\n\t<description>easy-retry-starter-common</description>\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t<artifactId>spring-boot-autoconfigure</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>com.alibaba</groupId>\n\t\t\t<artifactId>easy-retry-spring-extension</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>com.alibaba</groupId>\n\t\t\t<artifactId>easy-retry-guava-extension</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>${project.groupId}</groupId>\n\t\t\t<artifactId>easy-retry-core</artifactId>\n\t\t</dependency>\n\n\t</dependencies>\n\n</project>"
  },
  {
    "path": "easy-retry-starters/easy-retry-starter-common/src/main/java/com/alibaba/easyretry/starter/common/CommonAutoConfiguration.java",
    "content": "package com.alibaba.easyretry.starter.common;\n\nimport org.springframework.beans.BeansException;\nimport org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.ApplicationContextAware;\nimport org.springframework.context.annotation.Bean;\n\nimport com.alibaba.easyretry.common.RetryConfiguration;\nimport com.alibaba.easyretry.common.RetryExecutor;\nimport com.alibaba.easyretry.common.access.RetrySerializerAccess;\nimport com.alibaba.easyretry.common.access.RetryStrategyAccess;\nimport com.alibaba.easyretry.common.access.RetryTaskAccess;\nimport com.alibaba.easyretry.common.event.RetryEventMulticaster;\nimport com.alibaba.easyretry.common.filter.RetryFilterDiscover;\nimport com.alibaba.easyretry.common.filter.RetryFilterInvocation;\nimport com.alibaba.easyretry.common.filter.RetryFilterInvocationHandler;\nimport com.alibaba.easyretry.common.filter.RetryFilterRegister;\nimport com.alibaba.easyretry.common.filter.RetryFilterRegisterHandler;\nimport com.alibaba.easyretry.common.resolve.ExecutorSolver;\nimport com.alibaba.easyretry.common.serializer.ResultPredicateSerializer;\nimport com.alibaba.easyretry.common.strategy.StopStrategy;\nimport com.alibaba.easyretry.common.strategy.WaitStrategy;\nimport com.alibaba.easyretry.core.PersistenceRetryExecutor;\nimport com.alibaba.easyretry.core.access.DefaultRetrySerializerAccess;\nimport com.alibaba.easyretry.core.event.SimpleRetryEventMulticaster;\nimport com.alibaba.easyretry.core.filter.DefaultRetryFilterInvocationHandler;\nimport com.alibaba.easyretry.core.filter.DefaultRetryFilterRegisterHandler;\nimport com.alibaba.easyretry.core.filter.SimpleRetryFilterRegister;\nimport com.alibaba.easyretry.core.serializer.HessianResultPredicateSerializer;\nimport com.alibaba.easyretry.core.strategy.DefaultRetryStrategy;\nimport com.alibaba.easyretry.extension.spring.RetryListenerInitialize;\nimport com.alibaba.easyretry.extension.spring.SpringEventApplicationListener;\nimport com.alibaba.easyretry.extension.spring.SpringRetryFilterDiscover;\nimport com.alibaba.easyretry.extension.spring.aop.RetryInterceptor;\n\nimport lombok.extern.slf4j.Slf4j;\n\n/**\n * @author Created by wuhao on 2021/2/19.\n */\n@Slf4j\npublic abstract class CommonAutoConfiguration implements ApplicationContextAware {\n\n\tprotected ApplicationContext applicationContext;\n\n\t@Bean\n\t@ConditionalOnMissingBean(RetryConfiguration.class)\n\tpublic RetryConfiguration configuration(RetryTaskAccess retryTaskAccess,\n\t\t\t\t\t\t\t\t\t\t\tRetryEventMulticaster retryEventMulticaster) {\n\t\tDefaultRetryStrategy defaultRetryStrategy = new DefaultRetryStrategy();\n\t\treturn new RetryConfiguration() {\n\t\t\t@Override\n\t\t\tpublic RetryTaskAccess getRetryTaskAccess() {\n\t\t\t\treturn retryTaskAccess;\n\t\t\t}\n\n\t\t\t@Override\n\t\t\tpublic RetrySerializerAccess getRetrySerializerAccess() {\n\t\t\t\treturn new DefaultRetrySerializerAccess();\n\t\t\t}\n\n\t\t\t@Override\n\t\t\tpublic RetryStrategyAccess getRetryStrategyAccess() {\n\t\t\t\treturn new RetryStrategyAccess() {\n\n\t\t\t\t\t@Override\n\t\t\t\t\tpublic StopStrategy getCurrentGlobalStopStrategy() {\n\t\t\t\t\t\treturn defaultRetryStrategy;\n\t\t\t\t\t}\n\n\t\t\t\t\t@Override\n\t\t\t\t\tpublic WaitStrategy getCurrentGlobalWaitStrategy() {\n\t\t\t\t\t\treturn defaultRetryStrategy;\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t@Override\n\t\t\tpublic ExecutorSolver getExecutorSolver() {\n\t\t\t\treturn executorName -> applicationContext.getBean(executorName);\n\t\t\t}\n\n\t\t\t@Override\n\t\t\tpublic ResultPredicateSerializer getResultPredicateSerializer() {\n\t\t\t\treturn new HessianResultPredicateSerializer();\n\t\t\t}\n\n\t\t\t@Override\n\t\t\tpublic Integer getMaxRetryTimes() {\n\t\t\t\treturn CommonAutoConfiguration.this.getMaxRetryTimes();\n\t\t\t}\n\n\t\t\t@Override\n\t\t\tpublic RetryEventMulticaster getRetryEventMulticaster() {\n\t\t\t\treturn retryEventMulticaster;\n\t\t\t}\n\t\t};\n\t}\n\n\t@Bean\n\t@ConditionalOnMissingBean(RetryInterceptor.class)\n\tpublic RetryInterceptor retryInterceptor(RetryConfiguration configuration) {\n\t\tRetryInterceptor retryInterceptor = new RetryInterceptor();\n\t\tretryInterceptor.setApplicationContext(applicationContext);\n\t\tretryInterceptor.setRetryConfiguration(configuration);\n\t\treturn retryInterceptor;\n\t}\n\n\t@Bean\n\t@ConditionalOnMissingBean(RetryExecutor.class)\n\tpublic RetryExecutor defaultRetryExecutor(RetryConfiguration configuration,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t RetryFilterInvocation retryInvocationHandler) {\n\t\tPersistenceRetryExecutor persistenceRetryExecutor = new PersistenceRetryExecutor();\n\t\tpersistenceRetryExecutor.setRetryConfiguration(configuration);\n\t\tpersistenceRetryExecutor.setRetryFilterInvocation(retryInvocationHandler);\n\t\treturn persistenceRetryExecutor;\n\t}\n\n\t@Bean\n\t@ConditionalOnMissingBean(RetryEventMulticaster.class)\n\tpublic RetryEventMulticaster retryEventMulticaster() {\n\t\treturn new SimpleRetryEventMulticaster();\n\t}\n\n\t@Bean\n\t@ConditionalOnMissingBean(RetryListenerInitialize.class)\n\tpublic RetryListenerInitialize retryListenerInitialize(RetryEventMulticaster retryEventMulticaster) {\n\t\tRetryListenerInitialize retryListenerInitialize = new RetryListenerInitialize();\n\t\tretryListenerInitialize.setRetryEventMulticaster(retryEventMulticaster);\n\t\treturn retryListenerInitialize;\n\t}\n\n\t@Bean\n\t@ConditionalOnMissingBean(SpringRetryFilterDiscover.class)\n\tpublic SpringRetryFilterDiscover springRetryFilterDiscover() {\n\t\treturn new SpringRetryFilterDiscover();\n\t}\n\n\t@Bean\n\t@ConditionalOnMissingBean(RetryFilterRegister.class)\n\tpublic SimpleRetryFilterRegister simpleRetryFilterRegister() {\n\t\treturn new SimpleRetryFilterRegister();\n\t}\n\n\t@Bean\n\t@ConditionalOnMissingBean(RetryFilterInvocationHandler.class)\n\tpublic DefaultRetryFilterInvocationHandler retryInvocationHandler(RetryFilterRegister simpleRetryFilterRegister) {\n\t\tDefaultRetryFilterInvocationHandler defaultRetryFilterInvocationHandler\n\t\t\t= new DefaultRetryFilterInvocationHandler();\n\t\tdefaultRetryFilterInvocationHandler.setRetryFilterRegister(simpleRetryFilterRegister);\n\t\treturn defaultRetryFilterInvocationHandler;\n\t}\n\n\t@Bean\n\t@ConditionalOnMissingBean(RetryFilterRegisterHandler.class)\n\tpublic RetryFilterRegisterHandler retryFilterRegisterHandler(RetryFilterDiscover springRetryFilterDiscover,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t RetryFilterRegister simpleRetryFilterRegister) {\n\t\tDefaultRetryFilterRegisterHandler defaultRetryFilterRegisterHandler = new DefaultRetryFilterRegisterHandler();\n\t\tdefaultRetryFilterRegisterHandler.setRetryFilterRegister(simpleRetryFilterRegister);\n\t\tdefaultRetryFilterRegisterHandler.setRetryFilterDiscover(springRetryFilterDiscover);\n\t\treturn defaultRetryFilterRegisterHandler;\n\t}\n\n\t@Bean\n\tpublic SpringEventApplicationListener easyRetryApplicationListener(RetryFilterInvocationHandler retryFilterInvocationHandler,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tRetryFilterRegisterHandler retryFilterRegisterHandler) {\n\t\tSpringEventApplicationListener springEventApplicationListener = new SpringEventApplicationListener();\n\t\tspringEventApplicationListener.setRetryFilterRegisterHandler(retryFilterRegisterHandler);\n\t\tspringEventApplicationListener.setRetryFilterInvocationHandler(retryFilterInvocationHandler);\n\t\treturn springEventApplicationListener;\n\t}\n\n\t@Override\n\tpublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {\n\t\tthis.applicationContext = applicationContext;\n\t}\n\n\tpublic abstract Integer getMaxRetryTimes();\n\n}\n"
  },
  {
    "path": "easy-retry-starters/pom.xml",
    "content": "<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:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\t<parent>\n\t\t<groupId>com.alibaba</groupId>\n\t\t<artifactId>easy-retry</artifactId>\n\t\t<version>${revision}</version>\n\t\t<relativePath>../pom.xml</relativePath>\n\t</parent>\n\n\t<artifactId>easy-retry-starters</artifactId>\n\t<packaging>pom</packaging>\n\n\t<name>easy-retry-starters</name>\n\t<description>easy-retry-starters</description>\n\n\t<modules>\n\t\t<module>easy-retry-memory-starter</module>\n\t\t<module>easy-retry-mybatis-starter</module>\n\t\t<module>easy-retry-starter-common</module>\n\t</modules>\n\n\t<dependencyManagement>\n\t\t<dependencies>\n\t\t\t<dependency>\n\t\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t\t<artifactId>spring-boot-autoconfigure</artifactId>\n\t\t\t\t<version>2.4.0</version>\n\t\t\t</dependency>\n\t\t</dependencies>\n\t</dependencyManagement>\n\n</project>"
  },
  {
    "path": "pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<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:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\n\t<modelVersion>4.0.0</modelVersion>\n\t<groupId>com.alibaba</groupId>\n\t<artifactId>easy-retry</artifactId>\n\t<version>${revision}</version>\n\t<packaging>pom</packaging>\n\t<properties>\n\t\t<maven.compiler.target>1.8</maven.compiler.target>\n\t\t<maven.compiler.source>1.8</maven.compiler.source>\n\t\t<java.version>1.8</java.version>\n\t\t<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n\t\t<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>\n\t\t<revision>1.0.3</revision>\n\t\t<slf4j.version>1.7.30</slf4j.version>\n\t\t<lombok.version>1.18.18</lombok.version>\n\t\t<guava.version>16.0</guava.version>\n\t\t<fastjson.version>1.2.73</fastjson.version>\n\t\t<maven-source-plugin.version>2.2.1</maven-source-plugin.version>\n\t\t<maven-javadoc-plugin.version>3.2.0</maven-javadoc-plugin.version>\n\t\t<maven-gpg-plugin.version>1.6</maven-gpg-plugin.version>\n\t</properties>\n\t<modules>\n\t\t<module>easy-retry-common</module>\n\t\t<module>easy-retry-core</module>\n\t\t<module>easy-retry-extensions</module>\n\t\t<module>easy-retry-starters</module>\n\t</modules>\n\n\t<name>easy-retry</name>\n\t<description>easy-retry</description>\n\t<url>https://github.com/alibaba/easy-retry</url>\n\n\n\t<scm>\n\t\t<url>https://github.com/alibaba/easy-retry</url>\n\t\t<connection>scm:git@github.com:alibaba/easy-retry.git</connection>\n\t</scm>\n\n\t<organization>\n\t\t<name>Alibaba Group</name>\n\t\t<url>https://github.com/alibaba</url>\n\t</organization>\n\n\t<developers>\n\t\t<developer>\n\t\t\t<name>wuhao</name>\n\t\t\t<email>wuhao7171@gmail.com</email>\n\t\t</developer>\n\t</developers>\n\n\t<licenses>\n\t\t<license>\n\t\t\t<name>MIT License</name>\n\t\t\t<url>http://www.opensource.org/licenses/mit-license.php</url>\n\t\t</license>\n\t</licenses>\n\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>org.junit.jupiter</groupId>\n\t\t\t<artifactId>junit-jupiter</artifactId>\n\t\t\t<scope>test</scope>\n\t\t</dependency>\n\t</dependencies>\n\n\t<dependencyManagement>\n\t\t<dependencies>\n\t\t\t<dependency>\n\t\t\t\t<groupId>org.junit</groupId>\n\t\t\t\t<artifactId>junit-bom</artifactId>\n\t\t\t\t<version>5.7.1</version>\n\t\t\t\t<type>pom</type>\n\t\t\t\t<scope>import</scope>\n\t\t\t</dependency>\n\n\t\t\t<dependency>\n\t\t\t\t<groupId>org.slf4j</groupId>\n\t\t\t\t<artifactId>slf4j-api</artifactId>\n\t\t\t\t<version>${slf4j.version}</version>\n\t\t\t</dependency>\n\t\t\t<dependency>\n\t\t\t\t<groupId>org.projectlombok</groupId>\n\t\t\t\t<artifactId>lombok</artifactId>\n\t\t\t\t<version>${lombok.version}</version>\n\t\t\t\t<optional>true</optional>\n\t\t\t</dependency>\n\n\t\t\t<dependency>\n\t\t\t\t<groupId>com.google.guava</groupId>\n\t\t\t\t<artifactId>guava</artifactId>\n\t\t\t\t<version>${guava.version}</version>\n\t\t\t</dependency>\n\n\t\t\t<dependency>\n\t\t\t\t<groupId>com.alibaba</groupId>\n\t\t\t\t<artifactId>easy-retry-core</artifactId>\n\t\t\t\t<version>${project.version}</version>\n\t\t\t</dependency>\n\n\t\t\t<dependency>\n\t\t\t\t<groupId>com.alibaba</groupId>\n\t\t\t\t<artifactId>easy-retry-common</artifactId>\n\t\t\t\t<version>${project.version}</version>\n\t\t\t</dependency>\n\n\t\t\t<dependency>\n\t\t\t\t<groupId>com.caucho</groupId>\n\t\t\t\t<artifactId>hessian</artifactId>\n\t\t\t\t<version>4.0.60</version>\n\t\t\t\t<scope>provided</scope>\n\t\t\t</dependency>\n\n\t\t\t<dependency>\n\t\t\t\t<groupId>org.apache.commons</groupId>\n\t\t\t\t<artifactId>commons-lang3</artifactId>\n\t\t\t\t<version>3.11</version>\n\t\t\t</dependency>\n\n\t\t\t<dependency>\n\t\t\t\t<groupId>com.alibaba</groupId>\n\t\t\t\t<artifactId>fastjson</artifactId>\n\t\t\t\t<version>${fastjson.version}</version>\n\t\t\t</dependency>\n\n\t\t\t<dependency>\n\t\t\t\t<groupId>org.apache.commons</groupId>\n\t\t\t\t<artifactId>commons-collections4</artifactId>\n\t\t\t\t<version>4.4</version>\n\t\t\t</dependency>\n\t\t\t<dependency>\n\t\t\t\t<groupId>${project.groupId}</groupId>\n\t\t\t\t<artifactId>easy-retry-spring-extension</artifactId>\n\t\t\t\t<version>${project.version}</version>\n\t\t\t</dependency>\n\t\t\t<dependency>\n\t\t\t\t<groupId>${project.groupId}</groupId>\n\t\t\t\t<artifactId>easy-retry-guava-extension</artifactId>\n\t\t\t\t<version>${project.version}</version>\n\t\t\t</dependency>\n\n\t\t\t<dependency>\n\t\t\t\t<groupId>${project.groupId}</groupId>\n\t\t\t\t<artifactId>easy-retry-mybatis-extension</artifactId>\n\t\t\t\t<version>${project.version}</version>\n\t\t\t</dependency>\n\n\t\t\t<dependency>\n\t\t\t\t<groupId>${project.groupId}</groupId>\n\t\t\t\t<artifactId>easy-retry-starter-common</artifactId>\n\t\t\t\t<version>${project.version}</version>\n\t\t\t</dependency>\n\t\t</dependencies>\n\t</dependencyManagement>\n\t<build>\n\t\t<plugins>\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t<artifactId>maven-compiler-plugin</artifactId>\n\t\t\t\t<version>3.8.1</version>\n\t\t\t\t<configuration>\n\t\t\t\t\t<source>1.8</source>\n\t\t\t\t\t<target>1.8</target>\n\t\t\t\t\t<encoding>UTF-8</encoding>\n\t\t\t\t</configuration>\n\t\t\t</plugin>\n\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t<artifactId>maven-resources-plugin</artifactId>\n\t\t\t\t<version>3.2.0</version>\n\t\t\t\t<configuration>\n\t\t\t\t\t<encoding>UTF-8</encoding>\n\t\t\t\t</configuration>\n\t\t\t</plugin>\n\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.codehaus.mojo</groupId>\n\t\t\t\t<artifactId>flatten-maven-plugin</artifactId>\n\t\t\t\t<version>1.1.0</version>\n\t\t\t\t<configuration>\n\t\t\t\t\t<updatePomFile>true</updatePomFile>\n\t\t\t\t\t<flattenMode>oss</flattenMode>\n\t\t\t\t</configuration>\n\t\t\t\t<executions>\n\t\t\t\t\t<execution>\n\t\t\t\t\t\t<id>flatten</id>\n\t\t\t\t\t\t<phase>process-resources</phase>\n\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t<goal>flatten</goal>\n\t\t\t\t\t\t</goals>\n\t\t\t\t\t</execution>\n\t\t\t\t\t<execution>\n\t\t\t\t\t\t<id>flatten.clean</id>\n\t\t\t\t\t\t<phase>clean</phase>\n\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t<goal>clean</goal>\n\t\t\t\t\t\t</goals>\n\t\t\t\t\t</execution>\n\t\t\t\t</executions>\n\t\t\t</plugin>\n\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t<artifactId>maven-surefire-plugin</artifactId>\n\t\t\t\t<version>3.0.0-M5</version>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n\n\t<profiles>\n\t\t<profile>\n\t\t\t<id>release</id>\n\t\t\t<build>\n\t\t\t\t<plugins>\n\t\t\t\t\t<plugin>\n\t\t\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t\t\t<artifactId>maven-gpg-plugin</artifactId>\n\t\t\t\t\t\t<version>${maven-gpg-plugin.version}</version>\n\t\t\t\t\t\t<executions>\n\t\t\t\t\t\t\t<execution>\n\t\t\t\t\t\t\t\t<phase>verify</phase>\n\t\t\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t\t\t<goal>sign</goal>\n\t\t\t\t\t\t\t\t</goals>\n\t\t\t\t\t\t\t</execution>\n\t\t\t\t\t\t</executions>\n\t\t\t\t\t</plugin>\n\n\t\t\t\t\t<plugin>\n\t\t\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t\t\t<artifactId>maven-source-plugin</artifactId>\n\t\t\t\t\t\t<version>3.2.1</version>\n\t\t\t\t\t\t<executions>\n\t\t\t\t\t\t\t<execution>\n\t\t\t\t\t\t\t\t<id>attach-sources</id>\n\t\t\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t\t\t<goal>jar</goal>\n\t\t\t\t\t\t\t\t</goals>\n\t\t\t\t\t\t\t</execution>\n\t\t\t\t\t\t</executions>\n\t\t\t\t\t</plugin>\n\n\t\t\t\t\t<plugin>\n\t\t\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t\t\t<artifactId>maven-javadoc-plugin</artifactId>\n\t\t\t\t\t\t<version>${maven-javadoc-plugin.version}</version>\n\t\t\t\t\t\t<executions>\n\t\t\t\t\t\t\t<execution>\n\t\t\t\t\t\t\t\t<id>attach-javadocs</id>\n\t\t\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t\t\t<goal>jar</goal>\n\t\t\t\t\t\t\t\t</goals>\n\t\t\t\t\t\t\t</execution>\n\t\t\t\t\t\t</executions>\n\t\t\t\t\t</plugin>\n\t\t\t\t</plugins>\n\t\t\t</build>\n\n\t\t\t<distributionManagement>\n\t\t\t\t<snapshotRepository>\n\t\t\t\t\t<id>esnapshots</id>\n\t\t\t\t\t<url>https://oss.sonatype.org/content/repositories/snapshots</url>\n\t\t\t\t</snapshotRepository>\n\t\t\t\t<repository>\n\t\t\t\t\t<id>erelease</id>\n\t\t\t\t\t<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>\n\t\t\t\t</repository>\n\t\t\t</distributionManagement>\n\t\t</profile>\n\t</profiles>\n</project>\n"
  }
]