2525import com .google .common .annotations .VisibleForTesting ;
2626import com .google .common .primitives .Ints ;
2727import jakarta .annotation .Nonnull ;
28+ import jakarta .annotation .PostConstruct ;
2829import jakarta .annotation .PreDestroy ;
2930import jakarta .enterprise .context .ApplicationScoped ;
3031import jakarta .inject .Inject ;
@@ -74,16 +75,17 @@ class NodeManagementImpl implements NodeManagement {
7475 static final Duration RESCHEDULE_AFTER_FAILURE = Duration .ofSeconds (10 );
7576 static final Duration RESCHEDULE_UNTIL_EXPIRATION = Duration .ofMinutes (1 );
7677 static final Duration RENEWAL_MIN_LEFT_FOR_RENEWAL = Duration .ofSeconds (30 );
77- private final NodeStore nodeStore ;
7878 private final NodeManagementConfig config ;
7979 private final MonotonicClock clock ;
8080 private final int numNodeIds ;
81- private final IdGeneratorFactory <?> idGenFactory ;
82- private final IdGeneratorSpec idGenSpec ;
83-
8481 private final Set <NodeLeaseImpl > registeredLeases = ConcurrentHashMap .newKeySet ();
85- private final IdGenerator systemIdGen ;
8682 private final AsyncExec scheduler ;
83+ private final NodeStoreFactory nodeStoreFactory ;
84+
85+ private NodeStore nodeStore ;
86+ private IdGeneratorFactory <?> idGenFactory ;
87+ private IdGeneratorSpec idGenSpec ;
88+ private IdGenerator systemIdGen ;
8789
8890 private volatile boolean closed ;
8991
@@ -95,6 +97,7 @@ class NodeManagementImpl implements NodeManagement {
9597 NodeStoreFactory nodeStoreFactory ,
9698 AsyncExec scheduler ) {
9799 var activePeriod = config .leaseDuration ().minus (config .renewalPeriod ());
100+ this .nodeStoreFactory = nodeStoreFactory ;
98101 this .numNodeIds = config .numNodes ();
99102 checkArgs (
100103 () ->
@@ -117,7 +120,11 @@ class NodeManagementImpl implements NodeManagement {
117120 this .config = config ;
118121 this .clock = clock ;
119122 this .scheduler = scheduler ;
123+ }
120124
125+ @ SuppressWarnings ("BusyWait" )
126+ @ PostConstruct
127+ void init () {
121128 var idGenSpec =
122129 (IdGeneratorSpec ) ImmutableIdGeneratorSpec .builder ().from (config .idGeneratorSpec ()).build ();
123130 var validationIdGeneratorSource =
@@ -132,6 +139,9 @@ public int nodeId() {
132139 return 0 ;
133140 }
134141 };
142+
143+ // If this loop doesn't complete within 10 minutes, we can only give up.
144+ var timeout = clock .currentInstant ().plus (Duration .ofMinutes (10 ));
135145 while (true ) {
136146 var existingNodeManagementState = nodeStoreFactory .fetchManagementState ();
137147 if (existingNodeManagementState .isPresent ()) {
@@ -157,6 +167,19 @@ public int nodeId() {
157167 break ;
158168 }
159169 }
170+ if (timeout .isBefore (clock .currentInstant ())) {
171+ throw new IllegalStateException (
172+ "Timed out to fetch and/or persist node management configuration. This is likely due to an overloaded backend database." );
173+ }
174+ try {
175+ // random sleep
176+ Thread .sleep (ThreadLocalRandom .current ().nextInt (10 , 500 ));
177+ } catch (InterruptedException e ) {
178+ Thread .currentThread ().interrupt ();
179+ throw new IllegalStateException (
180+ "Interrupted while waiting for node management configuration to be fetched/persisted" ,
181+ e );
182+ }
160183 }
161184
162185 this .idGenSpec = idGenSpec ;
0 commit comments