├── .editorconfig
├── .github
└── workflows
│ └── maven.yml
├── .gitignore
├── LICENSE
├── README.md
├── config
└── intellij-java-google-style.xml
├── easy-retry-common
├── pom.xml
└── src
│ └── main
│ └── java
│ └── com
│ └── alibaba
│ └── easyretry
│ └── common
│ ├── AbstractResultPredicate.java
│ ├── AbstractRetrySyncExecutor.java
│ ├── EasyRetryPredicate.java
│ ├── Invocation.java
│ ├── RetryConfiguration.java
│ ├── RetryContainer.java
│ ├── RetryContext.java
│ ├── RetryExecutor.java
│ ├── RetryIdentify.java
│ ├── RetryLifecycle.java
│ ├── RetrySyncExecutor.java
│ ├── SCallable.java
│ ├── SimpleMethodInvocation.java
│ ├── access
│ ├── RetrySerializerAccess.java
│ ├── RetryStrategyAccess.java
│ └── RetryTaskAccess.java
│ ├── constant
│ ├── enums
│ │ ├── HandleResultEnum.java
│ │ ├── RetryTaskStatusEnum.java
│ │ └── RetryTypeEnum.java
│ └── package-info.java
│ ├── entity
│ └── RetryTask.java
│ ├── event
│ ├── RetryEvent.java
│ ├── RetryEventMulticaster.java
│ ├── RetryListener.java
│ ├── before
│ │ ├── AfterSaveBeforeRetryEvent.java
│ │ ├── BeforeRetryEvent.java
│ │ └── PrepSaveBeforeRetryEvent.java
│ └── on
│ │ ├── FailureOnRetryEvent.java
│ │ ├── OnRetryEvent.java
│ │ ├── StopOnRetryEvent.java
│ │ └── SuccessOnRetryEvent.java
│ ├── filter
│ ├── AbstractRetryFilter.java
│ ├── RetryFilter.java
│ ├── RetryFilterDiscover.java
│ ├── RetryFilterInvocation.java
│ ├── RetryFilterInvocationHandler.java
│ ├── RetryFilterRegister.java
│ ├── RetryFilterRegisterHandler.java
│ └── RetryFilterResponse.java
│ ├── processor
│ ├── AsyncPersistenceProcessor.java
│ ├── RetryProcessor.java
│ └── SyncProcessor.java
│ ├── resolve
│ └── ExecutorSolver.java
│ ├── retryer
│ ├── Retryer.java
│ └── RetryerInfo.java
│ ├── serializer
│ ├── ArgDeSerializerInfo.java
│ ├── ArgSerializerInfo.java
│ ├── EasyRetrySerializer.java
│ ├── ResultPredicateSerializer.java
│ └── RetryArgSerializer.java
│ └── strategy
│ ├── RetryStrategy.java
│ ├── StopStrategy.java
│ └── WaitStrategy.java
├── easy-retry-core
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── com
│ │ └── alibaba
│ │ └── easyretry
│ │ └── core
│ │ ├── DegradeAbleRetryExecutor.java
│ │ ├── PersistenceRetryExecutor.java
│ │ ├── PersistenceRetryer.java
│ │ ├── PersistenceRetryerBuilder.java
│ │ ├── RetryerBuilder.java
│ │ ├── SyncRetryer.java
│ │ ├── SyncRetryerBuilder.java
│ │ ├── access
│ │ ├── DefaultRetrySerializerAccess.java
│ │ └── MemoryRetryTaskAccess.java
│ │ ├── container
│ │ └── SimpleRetryContainer.java
│ │ ├── context
│ │ └── MaxAttemptsPersistenceRetryContext.java
│ │ ├── degrade
│ │ └── EasyRetryDegradeHelper.java
│ │ ├── event
│ │ └── SimpleRetryEventMulticaster.java
│ │ ├── filter
│ │ ├── DefaultRetryFilterInvocationHandler.java
│ │ ├── DefaultRetryFilterRegisterHandler.java
│ │ ├── IdentifyRetryFilter.java
│ │ ├── MethodExcuteRetryFilter.java
│ │ ├── NOOPRetryFilter.java
│ │ ├── SPIRetryFilterDiscover.java
│ │ └── SimpleRetryFilterRegister.java
│ │ ├── process
│ │ ├── async
│ │ │ ├── AbstractAsyncPersistenceProcessor.java
│ │ │ ├── before
│ │ │ │ ├── AbstractAsyncPersistenceBeforeRetryProcessor.java
│ │ │ │ ├── ExceptionPersistenceAsyncBeforeRetryProcessor.java
│ │ │ │ └── ResultAsynPersistenceBeforeRetryProcessor.java
│ │ │ └── on
│ │ │ │ ├── AbstractAsyncPersistenceOnRetryProcessor.java
│ │ │ │ ├── ExceptionPersistenceAsynOnRetryProcessor.java
│ │ │ │ └── ResultAsynPersistenceOnRetryProcessor.java
│ │ └── package-info.java
│ │ ├── serializer
│ │ ├── FastJsonRetryArgSerializer.java
│ │ ├── HessianResultPredicateSerializer.java
│ │ └── HessianRetryArgSerializer.java
│ │ ├── strategy
│ │ └── DefaultRetryStrategy.java
│ │ └── utils
│ │ ├── HessianSerializerUtils.java
│ │ ├── LogUtils.java
│ │ └── PrintUtils.java
│ └── test
│ └── java
│ └── com
│ └── alibaba
│ └── easyretry
│ └── core
│ └── utils
│ └── TestClass.java
├── easy-retry-extensions
├── easy-retry-guava-extension
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── alibaba
│ │ └── easyretry
│ │ └── extension
│ │ └── guava
│ │ ├── GuavaRetrySyncExecutor.java
│ │ └── package-info.java
├── easy-retry-mybatis-extension
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── alibaba
│ │ │ │ └── easyretry
│ │ │ │ └── extension
│ │ │ │ └── mybatis
│ │ │ │ ├── access
│ │ │ │ └── MybatisRetryTaskAccess.java
│ │ │ │ ├── common
│ │ │ │ └── utils
│ │ │ │ │ └── HostUtils.java
│ │ │ │ ├── dao
│ │ │ │ ├── BaseDAOSupport.java
│ │ │ │ ├── RetryTaskDAO.java
│ │ │ │ └── RetryTaskDAOImpl.java
│ │ │ │ ├── po
│ │ │ │ └── RetryTaskPO.java
│ │ │ │ └── query
│ │ │ │ └── RetryTaskQuery.java
│ │ └── resources
│ │ │ └── dal
│ │ │ └── easyretry
│ │ │ ├── easy-mybatis-config.xml
│ │ │ └── mapper
│ │ │ └── easy-retry-task-mapper.xml
│ │ └── test
│ │ ├── java
│ │ └── com
│ │ │ └── alibaba
│ │ │ └── easyretry
│ │ │ └── extension
│ │ │ └── mybatis
│ │ │ ├── DbConfig.java
│ │ │ ├── MyBatisConfig.java
│ │ │ ├── access
│ │ │ └── MybatisRetryTaskAccessTest.java
│ │ │ ├── common
│ │ │ └── utils
│ │ │ │ └── HostUtilsTest.java
│ │ │ └── dao
│ │ │ └── RetryTaskDAOImplTest.java
│ │ └── resources
│ │ ├── logback.xml
│ │ └── task.sql
├── easy-retry-spring-extension
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── alibaba
│ │ └── easyretry
│ │ └── extension
│ │ └── spring
│ │ ├── RetryListenerInitialize.java
│ │ ├── SPELParamPredicate.java
│ │ ├── SPELResultPredicate.java
│ │ ├── SpringEventApplicationListener.java
│ │ ├── SpringRetryFilterDiscover.java
│ │ └── aop
│ │ ├── EasyRetryable.java
│ │ └── RetryInterceptor.java
└── pom.xml
├── easy-retry-starters
├── easy-retry-memory-starter
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── alibaba
│ │ │ └── easyretry
│ │ │ └── memory
│ │ │ ├── MemoryAutoConfiguration.java
│ │ │ └── config
│ │ │ └── EasyRetryMemoryCompatibleProperties.java
│ │ └── resources
│ │ └── META-INF
│ │ ├── additional-spring-configuration-metadata.json
│ │ └── spring.factories
├── easy-retry-mybatis-starter
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── alibaba
│ │ │ └── easyretry
│ │ │ └── mybatis
│ │ │ ├── MybatisAutoConfiguration.java
│ │ │ └── conifg
│ │ │ └── EasyRetryMybatisProperties.java
│ │ └── resources
│ │ └── META-INF
│ │ ├── additional-spring-configuration-metadata.json
│ │ └── spring.factories
├── easy-retry-starter-common
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── alibaba
│ │ └── easyretry
│ │ └── starter
│ │ └── common
│ │ └── CommonAutoConfiguration.java
└── pom.xml
├── img
└── readme
│ └── arch.jpg
└── pom.xml
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 |
6 | [*.java]
7 | indent_style = tab
8 | indent_size = 4
9 | end_of_line = lf
10 | trim_trailing_whitespace = true
11 | insert_final_newline = true
12 |
13 | [*.{json, yml, xml}]
14 | indent_style = tab
15 | indent_size = 4
16 |
17 | [*.md]
18 | insert_final_newline = false
19 | trim_trailing_whitespace = false
20 |
21 | [*.properties]
22 | ij_properties_align_group_field_declarations = false
23 | ij_properties_keep_blank_lines = false
24 | ij_properties_key_value_delimiter = equals
25 | ij_properties_spaces_around_key_value_delimiter = false
--------------------------------------------------------------------------------
/.github/workflows/maven.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build a Java project with Maven
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
3 |
4 | name: Java CI with Maven
5 |
6 | on:
7 | push:
8 | branches: [ main ]
9 | pull_request:
10 | branches: [ main ]
11 |
12 |
13 | jobs:
14 | build:
15 | runs-on: ubuntu-latest
16 | steps:
17 | - uses: actions/checkout@v2
18 | - name: Set up JDK 1.8
19 | uses: actions/setup-java@v1
20 | with:
21 | java-version: 1.8
22 | - name: Build with Maven
23 | run: mvn -B package --file pom.xml
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 | *.classpath
4 | *.factorypath
5 |
6 | # Log file
7 | *.log
8 |
9 | # BlueJ files
10 | *.ctxt
11 |
12 | # Mobile Tools for Java (J2ME)
13 | .mtj.tmp/
14 |
15 | # Package Files #
16 | *.jar
17 | *.war
18 | *.ear
19 | *.zip
20 | *.tar.gz
21 | *.rar
22 |
23 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
24 | hs_err_pid*
25 |
26 | # IDE Files #
27 | *.iml
28 | .idea
29 | .idea/
30 | .project
31 | .settings
32 | target
33 | .DS_Store
34 |
35 | # temp ignore
36 | *.cache
37 | *.diff
38 | *.patch
39 | *.tmp
40 |
41 | # Maven ignore
42 | .flattened-pom.xml
43 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Alibaba
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Easy-Retry
2 |
3 | 一种存储介质可扩展的持久化重试方案
4 | 
5 |
6 | ### Getting started
7 |
8 | #### Memory Retry
9 |
10 | 1. 增加pom依赖
11 |
12 | ```xml
13 |
14 | com.alibaba
15 | easy-retry-memory-starter
16 | ${last-version}
17 |
18 | ```
19 |
20 | 2. 在application.properties增加配置
21 |
22 | `spring.easyretry.memory.enabled = true`
23 |
24 | 3. 在需要重试的方法上增加`@EasyRetryable`注解
25 |
26 | ```java
27 | public class MemoryUserService {
28 | @EasyRetryable
29 | public User getUserById(Long userId){
30 | return new User();
31 | }
32 | }
33 | ```
34 |
35 | #### Mybatis Retry
36 |
37 | 1. 增加pom依赖
38 | ```xml
39 |
40 | com.alibaba
41 | easy-retry-mybatis-starter
42 | ${last-version}
43 |
44 | ```
45 |
46 | 2. 在application.properties增加配置
47 |
48 | `spring.easyretry.mybatis.enabled = true`
49 |
50 | 3. 声明`javax.sql.DataSource`的`Bean`实例,参考下面例子(以`druid`连接池为例)
51 | ```
52 | @Bean(name = "easyRetryMybatisDataSource", initMethod = "init", destroyMethod = "close")
53 | public DataSource easyRetryMybatisDataSource() {
54 | DruidDataSource tds = new DruidDataSource();
55 | tds.setUrl("");
56 | tds.setUsername("");
57 | tds.setPassword("");
58 | ...
59 | return tds;
60 | }
61 | ```
62 |
63 | 4. 新增持久化表
64 |
65 | ```
66 | CREATE TABLE `easy_retry_task` (
67 | `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
68 | `gmt_create` datetime NOT NULL COMMENT '创建时间',
69 | `gmt_modified` datetime NOT NULL COMMENT '修改时间',
70 | `sharding` varchar(64) DEFAULT NULL COMMENT '数据库分片字段',
71 | `biz_id` varchar(64) DEFAULT NULL COMMENT '业务id',
72 | `executor_name` varchar(512) NOT NULL COMMENT '执行名称',
73 | `executor_method_name` varchar(512) NOT NULL COMMENT '执行方法名称',
74 | `retry_status` tinyint(4) NOT NULL COMMENT '重试状态',
75 | `args_str` varchar(7168) DEFAULT NULL COMMENT '执行方法参数',
76 | `ext_attrs` varchar(3000) DEFAULT NULL COMMENT '扩展字段',
77 | PRIMARY KEY (`id`)
78 | ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COMMENT='easy_retry_task'
79 | ;
80 | ```
81 |
82 | 5. 在需要重试的方法上增加@EasyRetryable注解
83 |
84 | ```java
85 | public class MybatisUserService {
86 | @EasyRetryable
87 | public User getUserById(Long userId){
88 | return new User();
89 | }
90 | }
91 | ```
92 |
93 | ### Built With
94 |
95 | • JDK1.8
96 |
97 | • Spring Framework5+
98 |
99 | • Spring Boot2.4+
100 |
101 | • Maven3.0
102 |
--------------------------------------------------------------------------------
/config/intellij-java-google-style.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 | xmlns:android
229 |
230 | ^$
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 | xmlns:.*
240 |
241 | ^$
242 |
243 |
244 | BY_NAME
245 |
246 |
247 |
248 |
249 |
250 |
251 | .*:id
252 |
253 | http://schemas.android.com/apk/res/android
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 | style
264 |
265 | ^$
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 | .*
275 |
276 | ^$
277 |
278 |
279 | BY_NAME
280 |
281 |
282 |
283 |
284 |
285 |
286 | .*:.*Style
287 |
288 | http://schemas.android.com/apk/res/android
289 |
290 |
291 |
292 | BY_NAME
293 |
294 |
295 |
296 |
297 |
298 |
299 | .*:layout_width
300 |
301 | http://schemas.android.com/apk/res/android
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 | .*:layout_height
312 |
313 | http://schemas.android.com/apk/res/android
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 | .*:layout_weight
324 |
325 | http://schemas.android.com/apk/res/android
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 | .*:layout_margin
336 |
337 | http://schemas.android.com/apk/res/android
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 | .*:layout_marginTop
348 |
349 | http://schemas.android.com/apk/res/android
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 | .*:layout_marginBottom
360 |
361 | http://schemas.android.com/apk/res/android
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 | .*:layout_marginStart
372 |
373 | http://schemas.android.com/apk/res/android
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 | .*:layout_marginEnd
384 |
385 | http://schemas.android.com/apk/res/android
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 | .*:layout_marginLeft
396 |
397 | http://schemas.android.com/apk/res/android
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 | .*:layout_marginRight
408 |
409 | http://schemas.android.com/apk/res/android
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 | .*:layout_.*
420 |
421 | http://schemas.android.com/apk/res/android
422 |
423 |
424 |
425 | BY_NAME
426 |
427 |
428 |
429 |
430 |
431 |
432 | .*:padding
433 |
434 | http://schemas.android.com/apk/res/android
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 | .*:paddingTop
445 |
446 | http://schemas.android.com/apk/res/android
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 | .*:paddingBottom
457 |
458 | http://schemas.android.com/apk/res/android
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 | .*:paddingStart
469 |
470 | http://schemas.android.com/apk/res/android
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 | .*:paddingEnd
481 |
482 | http://schemas.android.com/apk/res/android
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 | .*:paddingLeft
493 |
494 | http://schemas.android.com/apk/res/android
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 | .*:paddingRight
505 |
506 | http://schemas.android.com/apk/res/android
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 | .*
517 | http://schemas.android.com/apk/res/android
518 |
519 |
520 |
521 | BY_NAME
522 |
523 |
524 |
525 |
526 |
527 |
528 | .*
529 | http://schemas.android.com/apk/res-auto
530 |
531 |
532 |
533 | BY_NAME
534 |
535 |
536 |
537 |
538 |
539 |
540 | .*
541 | http://schemas.android.com/tools
542 |
543 |
544 | BY_NAME
545 |
546 |
547 |
548 |
549 |
550 |
551 | .*
552 | .*
553 |
554 |
555 | BY_NAME
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
--------------------------------------------------------------------------------
/easy-retry-common/pom.xml:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 |
6 | com.alibaba
7 | easy-retry
8 | ${revision}
9 | ../pom.xml
10 |
11 | easy-retry-common
12 | easy-retry-common
13 | easy-retry-common
14 |
15 |
16 |
17 | org.projectlombok
18 | lombok
19 |
20 |
21 | org.apache.commons
22 | commons-lang3
23 |
24 |
25 | com.google.guava
26 | guava
27 |
28 |
29 | org.slf4j
30 | slf4j-api
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/AbstractResultPredicate.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common;
2 |
3 | /**
4 | * @author Created by wuhao on 2021/3/26.
5 | */
6 | public abstract class AbstractResultPredicate implements EasyRetryPredicate {
7 |
8 | @Override
9 | public abstract Boolean apply(T result);
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/AbstractRetrySyncExecutor.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common;
2 |
3 | import com.alibaba.easyretry.common.retryer.RetryerInfo;
4 |
5 | /**
6 | * @author zhangchi20
7 | * Created on 2023-07-17
8 | */
9 | public abstract class AbstractRetrySyncExecutor implements RetrySyncExecutor {
10 |
11 | private RetryerInfo retryerInfo;
12 |
13 | @Override
14 | public void setRetryerInfo(RetryerInfo retryerInfo) {
15 | this.retryerInfo = retryerInfo;
16 | }
17 |
18 | public RetryerInfo getRetryerInfo() {
19 | return retryerInfo;
20 | }
21 |
22 |
23 | @Override
24 | public abstract V call(SCallable callable) throws Throwable;
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/EasyRetryPredicate.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * @author Created by wuhao on 2021/3/18.
7 | */
8 | public interface EasyRetryPredicate extends Serializable {
9 |
10 | R apply(T result);
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/Invocation.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common;
2 |
3 | /**
4 | * @author Created by wuhao on 2021/3/29.
5 | */
6 | public interface Invocation {
7 |
8 | Object invoke() throws Throwable;
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common;
2 |
3 | import com.alibaba.easyretry.common.access.RetrySerializerAccess;
4 | import com.alibaba.easyretry.common.access.RetryStrategyAccess;
5 | import com.alibaba.easyretry.common.access.RetryTaskAccess;
6 | import com.alibaba.easyretry.common.event.RetryEventMulticaster;
7 | import com.alibaba.easyretry.common.resolve.ExecutorSolver;
8 | import com.alibaba.easyretry.common.serializer.ResultPredicateSerializer;
9 |
10 | /**
11 | * @author Created by wuhao on 2020/11/5.
12 | */
13 | public interface RetryConfiguration {
14 |
15 | RetryTaskAccess getRetryTaskAccess();
16 |
17 | RetrySerializerAccess getRetrySerializerAccess();
18 |
19 | RetryStrategyAccess getRetryStrategyAccess();
20 |
21 | ExecutorSolver getExecutorSolver();
22 |
23 | ResultPredicateSerializer getResultPredicateSerializer();
24 |
25 | Integer getMaxRetryTimes();
26 |
27 | RetryEventMulticaster getRetryEventMulticaster();
28 |
29 | default AbstractRetrySyncExecutor getRetrySyncExecutor() {
30 | return null;
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryContainer.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common;
2 |
3 | /**
4 | * @author Created by wuhao on 2020/11/5.
5 | */
6 | public interface RetryContainer extends RetryLifecycle {
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryContext.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common;
2 |
3 | public interface RetryContext extends RetryLifecycle {
4 |
5 | void setAttribute(String key, String value);
6 |
7 | String getAttribute(String key);
8 |
9 | /**
10 | * 获取唯一标识
11 | */
12 | String getId();
13 |
14 | Invocation getInvocation();
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryExecutor.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common;
2 |
3 | import com.alibaba.easyretry.common.constant.enums.HandleResultEnum;
4 |
5 | /**
6 | * @author Created by wuhao on 2021/3/2.
7 | */
8 | public interface RetryExecutor {
9 |
10 | HandleResultEnum doExecute(RetryContext context);
11 | }
12 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryIdentify.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common;
2 |
3 | import java.util.Objects;
4 |
5 | /**
6 | * @author Created by wuhao on 2021/2/20.
7 | */
8 | public class RetryIdentify {
9 |
10 | private static final ThreadLocal RETRY_CONTEXT_THREAD_LOCAL = new ThreadLocal<>();
11 |
12 | private static final String RETRY_FLAG = "RETRY_FLAG";
13 |
14 | public static void start() {
15 | RETRY_CONTEXT_THREAD_LOCAL.set(RETRY_FLAG);
16 | }
17 |
18 | public static void stop() {
19 | RETRY_CONTEXT_THREAD_LOCAL.set(null);
20 | }
21 |
22 | public static boolean isOnRetry() {
23 | return Objects.nonNull(RETRY_CONTEXT_THREAD_LOCAL.get());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetryLifecycle.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common;
2 |
3 | /**
4 | * @author Created by wuhao on 2020/11/2.
5 | */
6 | public interface RetryLifecycle {
7 |
8 | void start();
9 |
10 | void stop();
11 | }
12 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/RetrySyncExecutor.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common;
2 |
3 | import com.alibaba.easyretry.common.retryer.RetryerInfo;
4 |
5 | /**
6 | * @author zhangchi20
7 | * Created on 2023-07-17
8 | */
9 | public interface RetrySyncExecutor {
10 |
11 | V call(SCallable callable) throws Throwable;
12 |
13 | void setRetryerInfo(RetryerInfo retryerInfo);
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/SCallable.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * @author Created by wuhao on 2020/11/5.
7 | */
8 | @FunctionalInterface
9 | public interface SCallable extends Serializable {
10 |
11 | V call() throws Throwable;
12 | }
13 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/SimpleMethodInvocation.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common;
2 |
3 | import java.lang.reflect.Method;
4 | import java.util.Arrays;
5 |
6 | import lombok.AllArgsConstructor;
7 | import lombok.Setter;
8 |
9 | /**
10 | * @author Created by wuhao on 2021/3/29.
11 | */
12 | @AllArgsConstructor
13 | public class SimpleMethodInvocation implements Invocation {
14 |
15 | @Setter
16 | private Object executor;
17 |
18 | @Setter
19 | private Method method;
20 |
21 | @Setter
22 | private Object[] args;
23 |
24 | @Override
25 | public Object invoke() throws Throwable {
26 | return method.invoke(executor, args);
27 | }
28 |
29 | @Override
30 | public String toString() {
31 | return "[Invocation] executor is " + executor.getClass().getName() + " method is " + method
32 | .getName() + " args is " + Arrays.toString(args);
33 |
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/access/RetrySerializerAccess.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.access;
2 |
3 | import com.alibaba.easyretry.common.serializer.RetryArgSerializer;
4 |
5 | /**
6 | * 重试信息序列化器获取 如果方法上有指定序列化器,则使用getRetrySerializer 否则使用全局序列化器getCurrentGlobalRetrySerializer
7 | *
8 | * @author Created by wuhao on 2020/11/6.
9 | */
10 | public interface RetrySerializerAccess {
11 |
12 | /**
13 | * 获取全局序列化器
14 | */
15 | RetryArgSerializer getCurrentGlobalRetrySerializer();
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/access/RetryStrategyAccess.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.access;
2 |
3 | import com.alibaba.easyretry.common.strategy.StopStrategy;
4 | import com.alibaba.easyretry.common.strategy.WaitStrategy;
5 |
6 | /**
7 | * 重试策略获取 如果方法上有指定则用指定Strategy 否则使用Global
8 | *
9 | * @author Created by wuhao on 2020/11/6.
10 | */
11 | public interface RetryStrategyAccess {
12 |
13 | /**
14 | * 获取全局重试任务停止策略
15 | */
16 | StopStrategy getCurrentGlobalStopStrategy();
17 |
18 | /**
19 | * 获取全局等待策略
20 | */
21 | WaitStrategy getCurrentGlobalWaitStrategy();
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/access/RetryTaskAccess.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.access;
2 |
3 | import java.util.List;
4 |
5 | import com.alibaba.easyretry.common.entity.RetryTask;
6 |
7 | /**
8 | * 重试任务获取器
9 | */
10 | public interface RetryTaskAccess {
11 |
12 | /**
13 | * 保存重试任务
14 | */
15 | boolean saveRetryTask(RetryTask retryTask);
16 |
17 | /**
18 | * 更改重试任务为处理中
19 | */
20 | boolean handlingRetryTask(RetryTask retryTask);
21 |
22 | /**
23 | * 完结重试任务
24 | */
25 | boolean finishRetryTask(RetryTask retryTask);
26 |
27 | /**
28 | * 停止重试任务
29 | */
30 | boolean stopRetryTask(RetryTask retryTask);
31 |
32 | /**
33 | * 批量查询重试任务
34 | */
35 | List listAvailableTasks(Long lastId);
36 | }
37 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/constant/enums/HandleResultEnum.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.constant.enums;
2 |
3 | /**
4 | * 重试任务重试结果
5 | *
6 | * @author Created by wuhao on 2020/11/1.
7 | */
8 | public enum HandleResultEnum {
9 |
10 | /**
11 | * 处理成功
12 | */
13 | SUCCESS,
14 |
15 | /**
16 | * 处理失败
17 | */
18 | FAILURE,
19 |
20 | /**
21 | * 等待策略返回该case还在等待队列中
22 | */
23 | WAITING,
24 |
25 | /**
26 | * 根据停止策略该笔case停止重试
27 | */
28 | STOP,
29 |
30 | ERROR;
31 | }
32 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/constant/enums/RetryTaskStatusEnum.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.constant.enums;
2 |
3 | import java.util.Map;
4 | import java.util.stream.Collectors;
5 | import java.util.stream.Stream;
6 |
7 | import lombok.Getter;
8 |
9 | /**
10 | * 重试任务状态
11 | *
12 | * @author Created by wuhao on 2020/10/31.
13 | */
14 | public enum RetryTaskStatusEnum {
15 |
16 | /**
17 | * 初始化状态
18 | */
19 | INIT(0, "初始化"),
20 |
21 | /**
22 | * 任务处理中
23 | */
24 | HANDLING(1, "处理中"),
25 |
26 | /**
27 | * 任务处理异常
28 | */
29 | ERROR(2, "异常"),
30 |
31 | /**
32 | * 任务完结
33 | */
34 | FINISH(3, "完结");
35 |
36 | private static final Map MAP =
37 | Stream.of(values())
38 | .collect(Collectors.toMap(RetryTaskStatusEnum::getCode, (value) -> value));
39 | @Getter
40 | private int code;
41 | @Getter
42 | private String desc;
43 |
44 | RetryTaskStatusEnum(int code, String desc) {
45 | this.code = code;
46 | this.desc = desc;
47 | }
48 |
49 | public static RetryTaskStatusEnum fromCode(int code) {
50 | return MAP.get(code);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/constant/enums/RetryTypeEnum.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.constant.enums;
2 |
3 | /**
4 | * 重试种类
5 | *
6 | * @author Created by zhangchi on 2023-07-12
7 | */
8 | public enum RetryTypeEnum {
9 |
10 | /**
11 | * 同步
12 | */
13 | SYNC,
14 |
15 | /**
16 | * 异步
17 | */
18 | ASYNC,
19 | ;
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/constant/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * @author Created by wuhao on 2020/11/6.
3 | */
4 | package com.alibaba.easyretry.common.constant;
5 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/entity/RetryTask.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.entity;
2 |
3 | import java.util.Date;
4 | import java.util.Map;
5 |
6 | import com.alibaba.easyretry.common.constant.enums.RetryTaskStatusEnum;
7 |
8 | import lombok.Data;
9 |
10 | /**
11 | * 重试任务实体
12 | *
13 | * @author wuhao
14 | */
15 | @Data
16 | public class RetryTask {
17 |
18 | /**
19 | * 主键id
20 | */
21 | private Long id;
22 |
23 | /**
24 | * 业务信息
25 | */
26 | private String bizId;
27 |
28 | /**
29 | * 执行者名称
30 | */
31 | private String executorName;
32 |
33 | /**
34 | * 执行者方法
35 | */
36 | private String executorMethodName;
37 |
38 | /**
39 | * 当重试失败时候执行的方法
40 | */
41 | private String onFailureMethod;
42 |
43 | /**
44 | * 重试任务状态
45 | */
46 | private RetryTaskStatusEnum status;
47 |
48 | /**
49 | * 任务上的扩展字段
50 | */
51 | private Map extAttrs;
52 |
53 | /**
54 | * 重试执行者方法参数
55 | */
56 | private String argsStr;
57 |
58 | private Date gmtCreate;
59 |
60 | private Date gmtModified;
61 | }
62 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/RetryEvent.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.event;
2 |
3 | /**
4 | * @author Created by wuhao on 2021/3/25.
5 | */
6 | public interface RetryEvent {
7 |
8 | String getName();
9 |
10 | boolean isOnRetry();
11 |
12 | void setAttribute(String key, String vule);
13 | }
14 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/RetryEventMulticaster.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.event;
2 |
3 | /**
4 | * @author Created by wuhao on 2021/3/26.
5 | */
6 | public interface RetryEventMulticaster {
7 |
8 | void register(RetryListener listener);
9 |
10 | void multicast(RetryEvent retryEvent);
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/RetryListener.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.event;
2 |
3 | /**
4 | * @author Created by wuhao on 2021/3/25.
5 | */
6 | public interface RetryListener {
7 |
8 | void onRetryEvent(T event);
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/before/AfterSaveBeforeRetryEvent.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.event.before;
2 |
3 | import com.alibaba.easyretry.common.entity.RetryTask;
4 |
5 | /**
6 | * @author Created by wuhao on 2021/3/25.
7 | */
8 | public class AfterSaveBeforeRetryEvent extends BeforeRetryEvent {
9 |
10 | public AfterSaveBeforeRetryEvent(RetryTask retryTask) {
11 | super(retryTask);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/before/BeforeRetryEvent.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.event.before;
2 |
3 | import java.util.Map;
4 | import java.util.Objects;
5 |
6 | import com.alibaba.easyretry.common.entity.RetryTask;
7 | import com.alibaba.easyretry.common.event.RetryEvent;
8 |
9 | import com.google.common.collect.Maps;
10 |
11 | /**
12 | * @author Created by wuhao on 2021/3/25.
13 | */
14 | public abstract class BeforeRetryEvent implements RetryEvent {
15 |
16 | private RetryTask retryTask;
17 |
18 | public BeforeRetryEvent(RetryTask retryTask) {
19 | this.retryTask = retryTask;
20 | }
21 |
22 | @Override
23 | public boolean isOnRetry() {
24 | return false;
25 | }
26 |
27 | @Override
28 | public void setAttribute(String key, String value) {
29 | Map extAttrs = retryTask.getExtAttrs();
30 | if (Objects.isNull(extAttrs)) {
31 | extAttrs = Maps.newHashMap();
32 | }
33 | extAttrs.put(key, value);
34 | }
35 |
36 | @Override
37 | public String getName() {
38 | return this.getClass().getSimpleName();
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/before/PrepSaveBeforeRetryEvent.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.event.before;
2 |
3 | import com.alibaba.easyretry.common.entity.RetryTask;
4 |
5 | /**
6 | * @author Created by wuhao on 2021/3/25.
7 | */
8 | public class PrepSaveBeforeRetryEvent extends BeforeRetryEvent {
9 |
10 | public PrepSaveBeforeRetryEvent(RetryTask retryTask) {
11 | super(retryTask);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/on/FailureOnRetryEvent.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.event.on;
2 |
3 | import com.alibaba.easyretry.common.RetryContext;
4 |
5 | /**
6 | * @author Created by wuhao on 2021/3/25.
7 | */
8 | public class FailureOnRetryEvent extends OnRetryEvent {
9 |
10 | public FailureOnRetryEvent(RetryContext retryContext) {
11 | super(retryContext);
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/on/OnRetryEvent.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.event.on;
2 |
3 | import com.alibaba.easyretry.common.RetryContext;
4 | import com.alibaba.easyretry.common.event.RetryEvent;
5 |
6 | /**
7 | * @author Created by wuhao on 2021/3/25.
8 | */
9 | public abstract class OnRetryEvent implements RetryEvent {
10 |
11 | final private RetryContext retryContext;
12 |
13 | public OnRetryEvent(RetryContext retryContext) {
14 | this.retryContext = retryContext;
15 | }
16 |
17 | @Override
18 | public void setAttribute(String key, String value) {
19 | retryContext.setAttribute(key, value);
20 | }
21 |
22 | public String getAttribute(String key) {
23 | return retryContext.getAttribute(key);
24 | }
25 |
26 | @Override
27 | public boolean isOnRetry() {
28 | return true;
29 | }
30 |
31 | @Override
32 | public String getName() {
33 | return this.getClass().getSimpleName();
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/on/StopOnRetryEvent.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.event.on;
2 |
3 | import com.alibaba.easyretry.common.RetryContext;
4 |
5 | /**
6 | * @author Created by wuhao on 2021/3/25.
7 | */
8 | public class StopOnRetryEvent extends OnRetryEvent {
9 |
10 | public StopOnRetryEvent(RetryContext retryContext) {
11 | super(retryContext);
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/event/on/SuccessOnRetryEvent.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.event.on;
2 |
3 | import com.alibaba.easyretry.common.RetryContext;
4 |
5 | /**
6 | * @author Created by wuhao on 2021/3/25.
7 | */
8 | public class SuccessOnRetryEvent extends OnRetryEvent {
9 |
10 | public SuccessOnRetryEvent(RetryContext retryContext) {
11 | super(retryContext);
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/AbstractRetryFilter.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.filter;
2 |
3 | /**
4 | * @author Created by wuhao on 2021/3/22.
5 | */
6 | public abstract class AbstractRetryFilter implements RetryFilter {
7 |
8 | protected RetryFilter next;
9 |
10 | @Override
11 | public void setNext(RetryFilter next) {
12 | this.next = next;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilter.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.filter;
2 |
3 | import com.alibaba.easyretry.common.RetryContext;
4 |
5 | /**
6 | * @author Created by wuhao on 2021/3/22.
7 | */
8 | public interface RetryFilter {
9 |
10 | RetryFilterResponse doFilter(RetryContext retryContext) throws Throwable;
11 |
12 | void setNext(RetryFilter next);
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterDiscover.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.filter;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * @author Created by wuhao on 2021/4/9.
7 | */
8 | public interface RetryFilterDiscover {
9 |
10 | List discoverAll();
11 | }
12 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterInvocation.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.filter;
2 |
3 | import com.alibaba.easyretry.common.RetryContext;
4 |
5 | /**
6 | * @author Created by wuhao on 2021/4/10.
7 | */
8 | public interface RetryFilterInvocation {
9 |
10 | RetryFilterResponse invoke(RetryContext retryContext) throws Throwable;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterInvocationHandler.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.filter;
2 |
3 | /**
4 | * @author Created by wuhao on 2021/3/19.
5 | */
6 | public interface RetryFilterInvocationHandler {
7 | void handle();
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterRegister.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.filter;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * @author Created by wuhao on 2021/3/22.
7 | */
8 | public interface RetryFilterRegister {
9 |
10 | void register(RetryFilter retryFilter);
11 |
12 | List export();
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterRegisterHandler.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.filter;
2 |
3 | /**
4 | * @author Created by wuhao on 2021/4/9.
5 | */
6 | public interface RetryFilterRegisterHandler {
7 |
8 | void handle();
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/filter/RetryFilterResponse.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.filter;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | * @author Created by wuhao on 2021/3/22.
7 | */
8 | @Data
9 | public class RetryFilterResponse {
10 |
11 | private Object response;
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/processor/AsyncPersistenceProcessor.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.processor;
2 |
3 | /**
4 | * @author Created by wuhao on 2021/3/19.
5 | */
6 | public interface AsyncPersistenceProcessor extends RetryProcessor {
7 |
8 | @Override
9 | void process();
10 |
11 | boolean needRetry();
12 |
13 | R getResult() throws Throwable;
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/processor/RetryProcessor.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.processor;
2 |
3 | /**
4 | * @author Created by wuhao on 2021/3/19.
5 | */
6 | public interface RetryProcessor {
7 |
8 | void process();
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/processor/SyncProcessor.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.processor;
2 |
3 | /**
4 | * @author Created by zhangchi on 2023-07-12
5 | */
6 | public interface SyncProcessor extends RetryProcessor {
7 |
8 | R getResult() throws Throwable;
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/resolve/ExecutorSolver.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.resolve;
2 |
3 | /**
4 | * @author Created by wuhao on 2020/11/8.
5 | */
6 | public interface ExecutorSolver {
7 |
8 | Object resolver(String executorName);
9 | }
10 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/retryer/Retryer.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.retryer;
2 |
3 | import com.alibaba.easyretry.common.SCallable;
4 |
5 | /**
6 | * @author Created by wuhao on 2020/11/5.
7 | */
8 | public interface Retryer {
9 |
10 | V call(SCallable callable) throws Throwable;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/retryer/RetryerInfo.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.retryer;
2 |
3 | import com.alibaba.easyretry.common.AbstractResultPredicate;
4 | import com.alibaba.easyretry.common.RetryConfiguration;
5 |
6 | import lombok.Data;
7 | import lombok.experimental.Accessors;
8 |
9 | /**
10 | * @author Created by wuhao on 2021/3/19.
11 | */
12 | @Data
13 | @Accessors(chain = true)
14 | public class RetryerInfo {
15 |
16 | /**
17 | * 执行者名称
18 | */
19 | private String executorName;
20 |
21 | /**
22 | * 执行者方法
23 | */
24 | private String executorMethodName;
25 |
26 | private String onFailureMethod;
27 |
28 | /**
29 | * 业务id,外部可以自定义存储一些信息
30 | */
31 | private String bizId;
32 |
33 | private Object[] args;
34 |
35 | private Class extends Throwable> onException;
36 |
37 | private RetryConfiguration retryConfiguration;
38 |
39 | private String namespace;
40 |
41 | private boolean reThrowException;
42 |
43 | private AbstractResultPredicate resultPredicate;
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/ArgDeSerializerInfo.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.serializer;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | * @author Created by wuhao on 2020/11/1.
7 | */
8 | @Data
9 | public class ArgDeSerializerInfo {
10 |
11 | private String argsStr;
12 | }
13 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/ArgSerializerInfo.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.serializer;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | * @author Created by wuhao on 2020/11/1.
7 | */
8 | @Data
9 | public class ArgSerializerInfo {
10 |
11 | /**
12 | * 执行者名称
13 | */
14 | private String executorName;
15 |
16 | private String executorClassName;
17 |
18 | /**
19 | * 执行者方法
20 | */
21 | private String executorMethodName;
22 |
23 | private Object[] args;
24 | }
25 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/EasyRetrySerializer.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.serializer;
2 |
3 | /**
4 | * @author Created by wuhao on 2021/3/18.
5 | */
6 | public interface EasyRetrySerializer {
7 |
8 | String serialize(T serializeInfo);
9 |
10 | T deSerialize(String infoStr);
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/ResultPredicateSerializer.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.serializer;
2 |
3 | import com.alibaba.easyretry.common.AbstractResultPredicate;
4 |
5 | /**
6 | * @author Created by wuhao on 2021/3/18.
7 | */
8 | public interface ResultPredicateSerializer extends EasyRetrySerializer {
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/serializer/RetryArgSerializer.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.serializer;
2 |
3 | /**
4 | * Retry 序列化器
5 | */
6 | public interface RetryArgSerializer extends EasyRetrySerializer {
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/strategy/RetryStrategy.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.strategy;
2 |
3 | import com.alibaba.easyretry.common.RetryContext;
4 |
5 | /**
6 | * @author Created by wuhao on 2020/11/2.
7 | */
8 | public interface RetryStrategy {
9 |
10 | void clear(RetryContext context);
11 | }
12 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/strategy/StopStrategy.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.strategy;
2 |
3 | import com.alibaba.easyretry.common.RetryContext;
4 |
5 | /**
6 | * @author Created by wuhao on 2020/11/1.
7 | */
8 | public interface StopStrategy extends RetryStrategy {
9 |
10 | boolean shouldStop(RetryContext context);
11 | }
12 |
--------------------------------------------------------------------------------
/easy-retry-common/src/main/java/com/alibaba/easyretry/common/strategy/WaitStrategy.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.common.strategy;
2 |
3 | import com.alibaba.easyretry.common.RetryContext;
4 |
5 | /**
6 | * @author Created by wuhao on 2020/11/1.
7 | */
8 | public interface WaitStrategy extends RetryStrategy {
9 |
10 | boolean shouldWait(RetryContext context);
11 |
12 | void backOff(RetryContext context);
13 | }
14 |
--------------------------------------------------------------------------------
/easy-retry-core/pom.xml:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 |
6 | com.alibaba
7 | easy-retry
8 | ${revision}
9 | ../pom.xml
10 |
11 | easy-retry-core
12 |
13 | easy-retry-core
14 | easy-retry-core
15 |
16 |
17 | ${project.groupId}
18 | easy-retry-common
19 |
20 |
21 |
22 | org.apache.commons
23 | commons-lang3
24 |
25 |
26 |
27 | com.google.guava
28 | guava
29 |
30 |
31 |
32 | com.caucho
33 | hessian
34 |
35 |
36 |
37 | org.slf4j
38 | slf4j-api
39 |
40 |
41 |
42 | com.alibaba
43 | fastjson
44 |
45 |
46 |
47 | org.apache.commons
48 | commons-collections4
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/easy-retry-core/src/main/java/com/alibaba/easyretry/core/DegradeAbleRetryExecutor.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.core;
2 |
3 | import com.alibaba.easyretry.common.RetryContext;
4 | import com.alibaba.easyretry.common.RetryExecutor;
5 | import com.alibaba.easyretry.common.constant.enums.HandleResultEnum;
6 | import com.alibaba.easyretry.core.degrade.EasyRetryDegradeHelper;
7 | import lombok.Setter;
8 | import lombok.extern.slf4j.Slf4j;
9 |
10 | /**
11 | * @author Created by gejinfeng on 2021/4/29.
12 | */
13 | @Slf4j
14 | public class DegradeAbleRetryExecutor implements RetryExecutor {
15 |
16 | @Setter
17 | private RetryExecutor retryExecutor;
18 |
19 | @Setter
20 | private EasyRetryDegradeHelper easyRetryDegradeHelper;
21 |
22 | @Override
23 | public HandleResultEnum doExecute(RetryContext context) {
24 | if (easyRetryDegradeHelper.degrade(context)) {
25 | return HandleResultEnum.STOP;
26 | }
27 | return retryExecutor.doExecute(context);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/easy-retry-core/src/main/java/com/alibaba/easyretry/core/PersistenceRetryExecutor.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.easyretry.core;
2 |
3 | import java.lang.reflect.InvocationTargetException;
4 |
5 | import com.alibaba.easyretry.common.RetryConfiguration;
6 | import com.alibaba.easyretry.common.RetryContext;
7 | import com.alibaba.easyretry.common.RetryExecutor;
8 | import com.alibaba.easyretry.common.access.RetryTaskAccess;
9 | import com.alibaba.easyretry.common.constant.enums.HandleResultEnum;
10 | import com.alibaba.easyretry.common.entity.RetryTask;
11 | import com.alibaba.easyretry.common.event.RetryEvent;
12 | import com.alibaba.easyretry.common.event.on.FailureOnRetryEvent;
13 | import com.alibaba.easyretry.common.event.on.StopOnRetryEvent;
14 | import com.alibaba.easyretry.common.event.on.SuccessOnRetryEvent;
15 | import com.alibaba.easyretry.common.filter.RetryFilterInvocation;
16 | import com.alibaba.easyretry.common.filter.RetryFilterResponse;
17 | import com.alibaba.easyretry.core.context.MaxAttemptsPersistenceRetryContext;
18 | import com.alibaba.easyretry.core.process.async.on.AbstractAsyncPersistenceOnRetryProcessor;
19 | import com.alibaba.easyretry.core.process.async.on.ExceptionPersistenceAsynOnRetryProcessor;
20 | import com.alibaba.easyretry.core.process.async.on.ResultAsynPersistenceOnRetryProcessor;
21 | import com.alibaba.easyretry.core.utils.LogUtils;
22 | import com.alibaba.easyretry.core.utils.PrintUtils;
23 |
24 | import lombok.Setter;
25 | import lombok.extern.slf4j.Slf4j;
26 |
27 | /**
28 | * @author Created by wuhao on 2021/3/2.
29 | */
30 | @Slf4j
31 | public class PersistenceRetryExecutor implements RetryExecutor {
32 |
33 | @Setter
34 | private RetryConfiguration retryConfiguration;
35 |
36 | @Setter
37 | private RetryFilterInvocation retryFilterInvocation;
38 |
39 | @Override
40 | public HandleResultEnum doExecute(RetryContext context) {
41 | try {
42 | PrintUtils.monitorInfo("begin deal", context);
43 | return handle(context);
44 | } catch (Throwable e) {
45 | log.error("Retry invoke failed", e);
46 | return HandleResultEnum.ERROR;
47 | }
48 | }
49 |
50 | private HandleResultEnum handle(RetryContext context) {
51 | MaxAttemptsPersistenceRetryContext maxAttemptsPersistenceRetryContext
52 | = (MaxAttemptsPersistenceRetryContext)context;
53 | if (maxAttemptsPersistenceRetryContext.getWaitStrategy().shouldWait(context)) {
54 | PrintUtils.monitorInfo("shouldWait", context);
55 | return HandleResultEnum.WAITING;
56 | }
57 | PrintUtils.monitorInfo("handlingRetryTask", context);
58 | retryConfiguration.getRetryTaskAccess()
59 | .handlingRetryTask(maxAttemptsPersistenceRetryContext.getRetryTask());
60 | AbstractAsyncPersistenceOnRetryProcessor