2525import java .util .Set ;
2626import java .util .concurrent .CopyOnWriteArrayList ;
2727import java .util .concurrent .atomic .AtomicReference ;
28+ import java .util .concurrent .locks .LockSupport ;
2829import java .util .function .Consumer ;
2930
3031public abstract class ProtocolAdapterFSM implements Consumer <ProtocolAdapterState .ConnectionStatus > {
@@ -120,15 +121,24 @@ public void stopAdapter() {
120121 }
121122
122123 public boolean transitionAdapterState (final @ NotNull AdapterStateEnum newState ) {
124+ int retryCount = 0 ;
123125 while (true ) {
124126 final var currentState = adapterState .get ();
125127 if (canTransition (currentState , newState )) {
126128 if (adapterState .compareAndSet (currentState , newState )) {
129+ final State snapshotState = new State (newState , northboundState .get (), southboundState .get ());
127130 log .debug ("Adapter state transition from {} to {} for adapter {}" , currentState , newState , adapterId );
128- notifyListenersAboutStateTransition (currentState () );
131+ notifyListenersAboutStateTransition (snapshotState );
129132 return true ;
130133 }
131- // CAS failed due to concurrent modification, retry
134+ retryCount ++;
135+ if (retryCount > 3 ) {
136+ // progressive backoff: 1μs, 2μs, 4μs, 8μs, ..., capped at 100μs
137+ // reduces CPU consumption and cache line contention under high load
138+ final long backoffNanos = Math .min (1_000L * (1L << (retryCount - 4 )), 100_000L );
139+ LockSupport .parkNanos (backoffNanos );
140+ }
141+ // Fast retry for attempts 1-3 (optimizes for low contention case)
132142 } else {
133143 // Transition not allowed from current state
134144 throw new IllegalStateException ("Cannot transition adapter state to " + newState );
@@ -137,15 +147,23 @@ public boolean transitionAdapterState(final @NotNull AdapterStateEnum newState)
137147 }
138148
139149 public boolean transitionNorthboundState (final @ NotNull StateEnum newState ) {
150+ int retryCount = 0 ;
140151 while (true ) {
141152 final var currentState = northboundState .get ();
142153 if (canTransition (currentState , newState )) {
143154 if (northboundState .compareAndSet (currentState , newState )) {
155+ final State snapshotState = new State (adapterState .get (), newState , southboundState .get ());
144156 log .debug ("Northbound state transition from {} to {} for adapter {}" , currentState , newState , adapterId );
145- notifyListenersAboutStateTransition (currentState () );
157+ notifyListenersAboutStateTransition (snapshotState );
146158 return true ;
147159 }
148- // CAS failed due to concurrent modification, retry
160+ retryCount ++;
161+ if (retryCount > 3 ) {
162+ // progressive backoff: 1μs, 2μs, 4μs, 8μs, ..., capped at 100μs
163+ final long backoffNanos = Math .min (1_000L * (1L << (retryCount - 4 )), 100_000L );
164+ LockSupport .parkNanos (backoffNanos );
165+ }
166+ // Fast retry for attempts 1-3 (optimizes for low contention case)
149167 } else {
150168 // Transition not allowed from current state
151169 throw new IllegalStateException ("Cannot transition northbound state to " + newState );
@@ -154,15 +172,23 @@ public boolean transitionNorthboundState(final @NotNull StateEnum newState) {
154172 }
155173
156174 public boolean transitionSouthboundState (final @ NotNull StateEnum newState ) {
175+ int retryCount = 0 ;
157176 while (true ) {
158177 final var currentState = southboundState .get ();
159178 if (canTransition (currentState , newState )) {
160179 if (southboundState .compareAndSet (currentState , newState )) {
180+ final State snapshotState = new State (adapterState .get (), northboundState .get (), newState );
161181 log .debug ("Southbound state transition from {} to {} for adapter {}" , currentState , newState , adapterId );
162- notifyListenersAboutStateTransition (currentState () );
182+ notifyListenersAboutStateTransition (snapshotState );
163183 return true ;
164184 }
165- // CAS failed due to concurrent modification, retry
185+ retryCount ++;
186+ if (retryCount > 3 ) {
187+ // progressive backoff: 1μs, 2μs, 4μs, 8μs, ..., capped at 100μs
188+ final long backoffNanos = Math .min (1_000L * (1L << (retryCount - 4 )), 100_000L );
189+ LockSupport .parkNanos (backoffNanos );
190+ }
191+ // Fast retry for attempts 1-3 (optimizes for low contention case)
166192 } else {
167193 // Transition not allowed from current state
168194 throw new IllegalStateException ("Cannot transition southbound state to " + newState );
0 commit comments