Add rate-limit handling to bulk AI summary generation
Add 3s delay between successful batches and 10s retry delay with up to 3 retries when rate-limited. Prevents exhausting free-tier rate limits (20 req/min) on OpenRouter. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -599,9 +599,13 @@ class Peptide_News_Admin {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Generate AI Summaries — loops in batches until all articles are done.
|
// Generate AI Summaries — loops in batches until all articles are done.
|
||||||
|
// Uses a 3-second delay between batches to respect free-tier rate limits,
|
||||||
|
// and retries up to 3 times when a batch fails before giving up.
|
||||||
$('#peptide-generate-summaries').on('click', function() {
|
$('#peptide-generate-summaries').on('click', function() {
|
||||||
var $btn = $(this), $result = $('#peptide-summary-result');
|
var $btn = $(this), $result = $('#peptide-summary-result');
|
||||||
var totalProcessed = 0;
|
var totalProcessed = 0;
|
||||||
|
var retries = 0;
|
||||||
|
var maxRetries = 3;
|
||||||
|
|
||||||
$btn.prop('disabled', true);
|
$btn.prop('disabled', true);
|
||||||
$result.text('<?php echo esc_js( __( 'Starting...', 'peptide-news' ) ); ?>');
|
$result.text('<?php echo esc_js( __( 'Starting...', 'peptide-news' ) ); ?>');
|
||||||
@@ -618,10 +622,17 @@ class Peptide_News_Admin {
|
|||||||
$result.text(totalProcessed + ' summarized, ' + remaining + ' remaining...');
|
$result.text(totalProcessed + ' summarized, ' + remaining + ' remaining...');
|
||||||
|
|
||||||
if (remaining > 0 && response.data.processed > 0) {
|
if (remaining > 0 && response.data.processed > 0) {
|
||||||
// Continue with next batch.
|
// Success — reset retry counter and continue after a delay
|
||||||
runBatch();
|
// to respect the free-tier rate limit (20 req/min).
|
||||||
|
retries = 0;
|
||||||
|
setTimeout(runBatch, 3000);
|
||||||
|
} else if (remaining > 0 && retries < maxRetries) {
|
||||||
|
// No progress — likely rate limited. Wait longer and retry.
|
||||||
|
retries++;
|
||||||
|
$result.text(totalProcessed + ' summarized, ' + remaining + ' remaining... (rate limited, retrying in 10s, attempt ' + retries + '/' + maxRetries + ')');
|
||||||
|
setTimeout(runBatch, 10000);
|
||||||
} else {
|
} else {
|
||||||
// Done — either all processed or no progress (error).
|
// Done — either all processed or exhausted retries.
|
||||||
$btn.prop('disabled', false).text('<?php echo esc_js( __( 'Generate AI Summaries', 'peptide-news' ) ); ?>');
|
$btn.prop('disabled', false).text('<?php echo esc_js( __( 'Generate AI Summaries', 'peptide-news' ) ); ?>');
|
||||||
if (remaining === 0) {
|
if (remaining === 0) {
|
||||||
$result.text('Done! ' + totalProcessed + ' article(s) summarized.');
|
$result.text('Done! ' + totalProcessed + ' article(s) summarized.');
|
||||||
@@ -638,8 +649,14 @@ class Peptide_News_Admin {
|
|||||||
$result.text('Error: ' + (response.data || 'Unknown error'));
|
$result.text('Error: ' + (response.data || 'Unknown error'));
|
||||||
}
|
}
|
||||||
}).fail(function() {
|
}).fail(function() {
|
||||||
$btn.prop('disabled', false).text('<?php echo esc_js( __( 'Generate AI Summaries', 'peptide-news' ) ); ?>');
|
if (retries < maxRetries) {
|
||||||
$result.text('Request failed. ' + totalProcessed + ' completed before failure.');
|
retries++;
|
||||||
|
$result.text(totalProcessed + ' completed. Request failed, retrying in 10s... (attempt ' + retries + '/' + maxRetries + ')');
|
||||||
|
setTimeout(runBatch, 10000);
|
||||||
|
} else {
|
||||||
|
$btn.prop('disabled', false).text('<?php echo esc_js( __( 'Generate AI Summaries', 'peptide-news' ) ); ?>');
|
||||||
|
$result.text('Request failed. ' + totalProcessed + ' completed before failure.');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -599,9 +599,13 @@ class Peptide_News_Admin {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Generate AI Summaries — loops in batches until all articles are done.
|
// Generate AI Summaries — loops in batches until all articles are done.
|
||||||
|
// Uses a 3-second delay between batches to respect free-tier rate limits,
|
||||||
|
// and retries up to 3 times when a batch fails before giving up.
|
||||||
$('#peptide-generate-summaries').on('click', function() {
|
$('#peptide-generate-summaries').on('click', function() {
|
||||||
var $btn = $(this), $result = $('#peptide-summary-result');
|
var $btn = $(this), $result = $('#peptide-summary-result');
|
||||||
var totalProcessed = 0;
|
var totalProcessed = 0;
|
||||||
|
var retries = 0;
|
||||||
|
var maxRetries = 3;
|
||||||
|
|
||||||
$btn.prop('disabled', true);
|
$btn.prop('disabled', true);
|
||||||
$result.text('<?php echo esc_js( __( 'Starting...', 'peptide-news' ) ); ?>');
|
$result.text('<?php echo esc_js( __( 'Starting...', 'peptide-news' ) ); ?>');
|
||||||
@@ -618,10 +622,17 @@ class Peptide_News_Admin {
|
|||||||
$result.text(totalProcessed + ' summarized, ' + remaining + ' remaining...');
|
$result.text(totalProcessed + ' summarized, ' + remaining + ' remaining...');
|
||||||
|
|
||||||
if (remaining > 0 && response.data.processed > 0) {
|
if (remaining > 0 && response.data.processed > 0) {
|
||||||
// Continue with next batch.
|
// Success — reset retry counter and continue after a delay
|
||||||
runBatch();
|
// to respect the free-tier rate limit (20 req/min).
|
||||||
|
retries = 0;
|
||||||
|
setTimeout(runBatch, 3000);
|
||||||
|
} else if (remaining > 0 && retries < maxRetries) {
|
||||||
|
// No progress — likely rate limited. Wait longer and retry.
|
||||||
|
retries++;
|
||||||
|
$result.text(totalProcessed + ' summarized, ' + remaining + ' remaining... (rate limited, retrying in 10s, attempt ' + retries + '/' + maxRetries + ')');
|
||||||
|
setTimeout(runBatch, 10000);
|
||||||
} else {
|
} else {
|
||||||
// Done — either all processed or no progress (error).
|
// Done — either all processed or exhausted retries.
|
||||||
$btn.prop('disabled', false).text('<?php echo esc_js( __( 'Generate AI Summaries', 'peptide-news' ) ); ?>');
|
$btn.prop('disabled', false).text('<?php echo esc_js( __( 'Generate AI Summaries', 'peptide-news' ) ); ?>');
|
||||||
if (remaining === 0) {
|
if (remaining === 0) {
|
||||||
$result.text('Done! ' + totalProcessed + ' article(s) summarized.');
|
$result.text('Done! ' + totalProcessed + ' article(s) summarized.');
|
||||||
@@ -638,8 +649,14 @@ class Peptide_News_Admin {
|
|||||||
$result.text('Error: ' + (response.data || 'Unknown error'));
|
$result.text('Error: ' + (response.data || 'Unknown error'));
|
||||||
}
|
}
|
||||||
}).fail(function() {
|
}).fail(function() {
|
||||||
$btn.prop('disabled', false).text('<?php echo esc_js( __( 'Generate AI Summaries', 'peptide-news' ) ); ?>');
|
if (retries < maxRetries) {
|
||||||
$result.text('Request failed. ' + totalProcessed + ' completed before failure.');
|
retries++;
|
||||||
|
$result.text(totalProcessed + ' completed. Request failed, retrying in 10s... (attempt ' + retries + '/' + maxRetries + ')');
|
||||||
|
setTimeout(runBatch, 10000);
|
||||||
|
} else {
|
||||||
|
$btn.prop('disabled', false).text('<?php echo esc_js( __( 'Generate AI Summaries', 'peptide-news' ) ); ?>');
|
||||||
|
$result.text('Request failed. ' + totalProcessed + ' completed before failure.');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user