Skip to content

Commit 5ecb04f

Browse files
committed
Only rate limit remote IDL configurations.
1 parent 950f83f commit 5ecb04f

File tree

2 files changed

+39
-26
lines changed

2 files changed

+39
-26
lines changed

anchor-src-gen/src/main/java/software/sava/anchor/Entrypoint.java

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import static java.nio.file.StandardOpenOption.*;
3131
import static java.util.Objects.requireNonNullElse;
3232
import static java.util.concurrent.TimeUnit.MILLISECONDS;
33+
import static java.util.concurrent.TimeUnit.SECONDS;
3334
import static systems.comodal.jsoniter.JsonIterator.fieldEquals;
3435

3536
public 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,

gradle/sava.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
productDescription=Solana IDL Source Generator
22
javaVersion=24
3-
solanaBOMVersion=24.3.14
3+
solanaBOMVersion=24.4.0

0 commit comments

Comments
 (0)