3030import static java .nio .file .StandardOpenOption .*;
3131import static java .util .Objects .requireNonNullElse ;
3232import static java .util .concurrent .TimeUnit .MILLISECONDS ;
33+ import static java .util .concurrent .TimeUnit .SECONDS ;
3334import static systems .comodal .jsoniter .JsonIterator .fieldEquals ;
3435
3536public final class Entrypoint extends Thread {
@@ -79,22 +80,21 @@ public void run() {
7980 AnchorIDL idl ;
8081 for (long delayMillis , latestCall , now , sleep ; ; ) {
8182 try {
82- task = this .tasks .peek ();
83+ task = this .tasks .poll ();
8384 if (task == null ) {
8485 return ;
8586 }
86- this .semaphore .acquire ();
87- delayMillis = this .baseDelayMillis * (this .errorCount .get () + 1 );
88- latestCall = this .latestCall .get ();
89- now = System .currentTimeMillis ();
90- sleep = (latestCall + delayMillis ) - now ;
91- if (sleep > 0 ) {
92- MILLISECONDS .sleep (sleep );
87+ if (task .remoteIDL ()) {
88+ this .semaphore .acquire ();
89+ delayMillis = this .baseDelayMillis * (this .errorCount .get () + 1 );
90+ latestCall = this .latestCall .get ();
9391 now = System .currentTimeMillis ();
94- }
95- task = this .tasks .poll ();
96- if (task == null ) {
97- return ;
92+ sleep = (latestCall + delayMillis ) - now ;
93+ if (sleep > 0 ) {
94+ MILLISECONDS .sleep (sleep );
95+ now = System .currentTimeMillis ();
96+ }
97+ this .latestCall .getAndAccumulate (now , MAX );
9898 }
9999 idl = task .fetchIDL (rpcClient .httpClient (), idlAccounts );
100100 if (idl == null ) {
@@ -110,6 +110,7 @@ public void run() {
110110 } finally {
111111 this .semaphore .release ();
112112 }
113+ this .errorCount .getAndUpdate (x -> x > 0 ? x - 1 : x );
113114
114115 final var packageName = task .formatPackage (basePackageName );
115116 final var generator = new AnchorSourceGenerator (
@@ -119,11 +120,8 @@ public void run() {
119120 tabLength ,
120121 idl
121122 );
122- this .latestCall .getAndAccumulate (now , MAX );
123123 generator .run ();
124124 generator .addExports (exports );
125- this .latestCall .getAndAccumulate (now + ((System .currentTimeMillis () - now ) >> 1 ), MAX );
126- this .errorCount .getAndUpdate (x -> x > 0 ? x - 1 : x );
127125 }
128126 }
129127
@@ -148,6 +146,10 @@ String formatPackage(final String basePackageName) {
148146 return String .format ("%s.%s.anchor" , basePackageName , packageName );
149147 }
150148
149+ boolean remoteIDL () {
150+ return idlURL != null ;
151+ }
152+
151153 AnchorIDL fetchIDL (final HttpClient httpClient , final Map <PublicKey , AccountInfo <byte []>> idlAccounts ) {
152154 if (idlURL != null ) {
153155 return AnchorSourceGenerator .fetchIDL (httpClient , idlURL ).join ();
@@ -259,10 +261,6 @@ public static void main(final String[] args) throws InterruptedException, IOExce
259261 }).toList ();
260262
261263 try {
262- final var semaphore = new Semaphore (numThreads , false );
263-
264- final var errorCount = new AtomicLong ();
265- final var latestCall = new AtomicLong ();
266264
267265 try (final var executor = Executors .newVirtualThreadPerTaskExecutor ()) {
268266 try (final var httpClient = HttpClient .newBuilder ().executor (executor ).build ()) {
@@ -276,17 +274,32 @@ public static void main(final String[] args) throws InterruptedException, IOExce
276274 idlAccounts = Map .of ();
277275 } else {
278276 idlAccounts = HashMap .newHashMap (idlAccountKeys .size ());
279- // TODO: Support retries.
280- final var accountInfoList = rpcClient .getAccounts (idlAccountKeys ).join ();
281- for (final var accountInfo : accountInfoList ) {
282- if (accountInfo != null ) {
283- idlAccounts .put (accountInfo .pubKey (), accountInfo );
277+ for (long errorCount = 0 ; ; ) {
278+ try {
279+ final var accountInfoList = rpcClient .getAccounts (idlAccountKeys ).join ();
280+ for (final var accountInfo : accountInfoList ) {
281+ if (accountInfo != null ) {
282+ idlAccounts .put (accountInfo .pubKey (), accountInfo );
283+ }
284+ }
285+ break ;
286+ } catch (final RuntimeException e ) {
287+ final long delay = Math .max (21 , ++errorCount );
288+ logger .log (ERROR , String .format (
289+ "Failed to fetch %d accounts %d times, retrying in %d seconds." ,
290+ idlAccountKeys .size (), ++errorCount , delay
291+ ), e
292+ );
293+ SECONDS .sleep (delay );
284294 }
285295 }
286296 }
287297
298+ final var semaphore = new Semaphore (numThreads , false );
299+ final var errorCount = new AtomicLong ();
300+ final var latestCall = new AtomicLong ();
288301 final var exports = new ConcurrentSkipListSet <String >();
289- final var threads = IntStream .range (0 , numThreads ).mapToObj (t -> new Entrypoint (
302+ final var threads = IntStream .range (0 , numThreads ).mapToObj (_ -> new Entrypoint (
290303 semaphore , tasks , errorCount , baseDelayMillis , latestCall ,
291304 rpcClient ,
292305 idlAccounts ,
0 commit comments