File tree Expand file tree Collapse file tree 1 file changed +23
-7
lines changed
core/src/main/java/dev/failsafe/internal Expand file tree Collapse file tree 1 file changed +23
-7
lines changed Original file line number Diff line number Diff line change @@ -96,14 +96,30 @@ synchronized CompletableFuture<Void> acquirePermitAsync() {
9696
9797 @ Override
9898 public synchronized void releasePermit () {
99- if (permits < maxPermits ) {
100- permits += 1 ;
101- CompletableFuture <Void > future = futures .pollFirst ();
102- if (future != null ){
103- permits -= 1 ;
104- future .complete (null );
99+ if (permits < maxPermits ) {
100+ permits += 1 ;
101+ /*
102+ * It is possible to get future from the list that already had been completed. This
103+ * happens because setting future to 'completed' state happens before (and not
104+ * atomically with) removing future from the list. Handle this by pulling futures from
105+ * the list until we find one we can complete (or reach the end of the list). Not doing
106+ * this may result in 'dandling' messages in the list that are never completed. For some
107+ * details see FutureLinkedList.add - how it returns a future that weill remove entry
108+ * from the list when it is completed. And also see BulkheadExecutor.preExecuteAsync
109+ * that calls acquirePermitAsync and gets that future in response.
110+ */
111+ while (true ) {
112+ CompletableFuture <Void > future = futures .pollFirst ();
113+ if (future == null ) {
114+ break ;
115+ }
116+ permits -= 1 ;
117+ if (future .complete (null )) {
118+ break ;
119+ }
120+ permits += 1 ;
121+ }
105122 }
106- }
107123 }
108124
109125 @ Override
You can’t perform that action at this time.
0 commit comments