This commit is contained in:
Javier Casares 2026-02-18 16:09:17 +00:00
commit 768bbfbdd2
6 changed files with 150 additions and 34 deletions

View file

@ -339,12 +339,64 @@ class Settings_Page {
*/
public function render_batch_size_field() {
$options = get_option( self::OPTION_NAME, array() );
$batch_size = $options['batch_size'] ?? 10;
$batch_size = absint( $options['batch_size'] ?? 10 );
?>
<input type="number" name="<?php echo esc_attr( self::OPTION_NAME ); ?>[batch_size]" value="<?php echo esc_attr( $batch_size ); ?>" min="1" max="10000" class="small-text">
<p class="description">
<?php esc_html_e( 'Number of emails to send in each batch. Higher values improve performance with SMTPKeepAlive.', 'robotstxt-smtp-newsletter' ); ?><br>
<?php esc_html_e( 'See calculated recommendations below based on your rate limits and cron interval.', 'robotstxt-smtp-newsletter' ); ?>
<?php esc_html_e( 'Number of emails each worker picks up and sends per cycle. Workers read this value from the database automatically — no need to specify it in the command line.', 'robotstxt-smtp-newsletter' ); ?>
</p>
<table style="margin-top:10px; border-collapse:collapse; font-size:13px;">
<thead>
<tr>
<th style="text-align:left; padding:4px 12px 4px 0; color:#666; font-weight:normal; border-bottom:1px solid #ddd;">
<?php esc_html_e( 'Workers', 'robotstxt-smtp-newsletter' ); ?>
</th>
<th style="text-align:left; padding:4px 12px 4px 0; color:#666; font-weight:normal; border-bottom:1px solid #ddd;">
<?php esc_html_e( 'Batch Size', 'robotstxt-smtp-newsletter' ); ?>
</th>
<th style="text-align:left; padding:4px 0; color:#666; font-weight:normal; border-bottom:1px solid #ddd;">
<?php esc_html_e( 'Simultaneous emails', 'robotstxt-smtp-newsletter' ); ?>
</th>
</tr>
</thead>
<tbody>
<?php
$examples = array( 1, 5, 10, 20, 50 );
foreach ( $examples as $example ) :
$simultaneous = 10 * $example;
$is_current = ( $example === $batch_size );
$row_style = $is_current ? 'background:#e8f4fd; font-weight:bold;' : '';
?>
<tr style="<?php echo esc_attr( $row_style ); ?>">
<td style="padding:3px 12px 3px 0;">10</td>
<td style="padding:3px 12px 3px 0;">
<?php echo absint( $example ); ?>
<?php if ( $is_current ) : ?>
&larr; <?php esc_html_e( 'current', 'robotstxt-smtp-newsletter' ); ?>
<?php endif; ?>
</td>
<td style="padding:3px 0;">
<strong><?php echo number_format_i18n( $simultaneous ); ?></strong>
</td>
</tr>
<?php endforeach; ?>
<?php if ( ! in_array( $batch_size, $examples, true ) && $batch_size > 0 ) : ?>
<tr style="background:#e8f4fd; font-weight:bold;">
<td style="padding:3px 12px 3px 0;">10</td>
<td style="padding:3px 12px 3px 0;">
<?php echo absint( $batch_size ); ?>
&larr; <?php esc_html_e( 'current', 'robotstxt-smtp-newsletter' ); ?>
</td>
<td style="padding:3px 0;">
<strong><?php echo number_format_i18n( 10 * $batch_size ); ?></strong>
</td>
</tr>
<?php endif; ?>
</tbody>
</table>
<p class="description" style="margin-top:8px;">
<?php esc_html_e( 'Table assumes the recommended setup of 10 parallel workers. Adjust your worker command to run more or fewer workers.', 'robotstxt-smtp-newsletter' ); ?><br>
<?php esc_html_e( 'See calculated recommendations below based on your rate limits.', 'robotstxt-smtp-newsletter' ); ?>
</p>
<?php
}
@ -489,27 +541,50 @@ class Settings_Page {
$worker_path = ROBOTSTXT_SMTP_NEWSLETTER_PATH . 'worker.php';
$is_multisite = is_multisite();
$site_url = get_site_url();
$options = get_option( 'robotstxt_smtp_newsletter_options', array() );
$batch_size = max( 1, absint( $options['batch_size'] ?? 10 ) );
?>
<div class="notice notice-info inline">
<p><strong><?php esc_html_e( 'Important: Queue Processing', 'robotstxt-smtp-newsletter' ); ?></strong></p>
<p><?php esc_html_e( 'Newsletter emails are now queued to the database and require a worker process to send them.', 'robotstxt-smtp-newsletter' ); ?></p>
<p>
<?php esc_html_e( 'Newsletter emails are queued to the database and processed by external worker processes.', 'robotstxt-smtp-newsletter' ); ?>
<?php esc_html_e( 'Workers read the Batch Size from the database automatically — no need to pass it as a command-line argument.', 'robotstxt-smtp-newsletter' ); ?>
</p>
<table style="margin:10px 0 15px 0; border-collapse:collapse; font-size:13px;">
<tr>
<td style="padding:3px 15px 3px 0; color:#666;"><?php esc_html_e( 'Parallel workers:', 'robotstxt-smtp-newsletter' ); ?></td>
<td style="padding:3px 0;"><strong>10</strong></td>
</tr>
<tr>
<td style="padding:3px 15px 3px 0; color:#666;"><?php esc_html_e( 'Batch size (current setting):', 'robotstxt-smtp-newsletter' ); ?></td>
<td style="padding:3px 0;"><strong><?php echo absint( $batch_size ); ?></strong></td>
</tr>
<tr style="border-top:1px solid #ddd;">
<td style="padding:6px 15px 3px 0; color:#666;"><?php esc_html_e( 'Simultaneous emails:', 'robotstxt-smtp-newsletter' ); ?></td>
<td style="padding:6px 0;"><strong style="font-size:15px;"><?php echo number_format_i18n( 10 * $batch_size ); ?></strong>
<small style="color:#666; margin-left:5px;">(10 &times; <?php echo absint( $batch_size ); ?>)</small>
</td>
</tr>
</table>
<?php if ( $is_multisite ) : ?>
<div style="background:#fff3cd; border-left:4px solid #ffc107; padding:10px; margin:15px 0;">
<p style="margin:0;">
<strong><?php esc_html_e( 'MultiSite Detected:', 'robotstxt-smtp-newsletter' ); ?></strong>
<?php esc_html_e( 'This WordPress installation is running in MultiSite mode. Worker commands must include the --url parameter to specify which site to process.', 'robotstxt-smtp-newsletter' ); ?>
<?php esc_html_e( 'Worker commands must include the --url parameter to specify which site to process.', 'robotstxt-smtp-newsletter' ); ?>
</p>
</div>
<h4><?php esc_html_e( 'Single Worker Command (MultiSite)', 'robotstxt-smtp-newsletter' ); ?></h4>
<code style="display:block; padding:10px; background:#f5f5f5; overflow-x:auto; margin:10px 0; font-family:monospace;">
php <?php echo esc_html( $worker_path ); ?> 10 "w1" --url="<?php echo esc_html( $site_url ); ?>"
php <?php echo esc_html( $worker_path ); ?> "w1" --url="<?php echo esc_html( $site_url ); ?>"
</code>
<h4><?php esc_html_e( 'Parallel Processing (10 workers) - MultiSite', 'robotstxt-smtp-newsletter' ); ?></h4>
<code style="display:block; padding:10px; background:#f5f5f5; overflow-x:auto; margin:10px 0; font-family:monospace;">
seq 1 10 | xargs -P10 -I{} php <?php echo esc_html( $worker_path ); ?> 10 "w{}" --url="<?php echo esc_html( $site_url ); ?>"
seq 1 10 | xargs -P10 -I{} php <?php echo esc_html( $worker_path ); ?> "w{}" --url="<?php echo esc_html( $site_url ); ?>"
</code>
<p style="margin-top:10px; color:#856404;">
@ -525,12 +600,12 @@ class Settings_Page {
<?php else : ?>
<h4><?php esc_html_e( 'Single Worker Command', 'robotstxt-smtp-newsletter' ); ?></h4>
<code style="display:block; padding:10px; background:#f5f5f5; overflow-x:auto; margin:10px 0; font-family:monospace;">
php <?php echo esc_html( $worker_path ); ?> 10 "w1"
php <?php echo esc_html( $worker_path ); ?> "w1"
</code>
<h4><?php esc_html_e( 'Parallel Processing (10 workers)', 'robotstxt-smtp-newsletter' ); ?></h4>
<code style="display:block; padding:10px; background:#f5f5f5; overflow-x:auto; margin:10px 0; font-family:monospace;">
seq 1 10 | xargs -P10 -I{} php <?php echo esc_html( $worker_path ); ?> 10 "w{}"
seq 1 10 | xargs -P10 -I{} php <?php echo esc_html( $worker_path ); ?> "w{}"
</code>
<?php endif; ?>

View file

@ -1,9 +1,18 @@
= 2.2.8 =
* CHANGED: Batch Size is now read from the plugin settings database — workers no longer require it as a command-line argument
* CHANGED: Worker command simplified: php worker.php "w1" (batch_size argument removed)
* IMPROVED: Batch Size field now shows a throughput table (10 workers × N emails = simultaneous emails)
* IMPROVED: Worker section in settings shows the calculated simultaneous email count based on current settings
* TECHNICAL: Legacy command format (php worker.php 10 "w1") still accepted with a deprecation warning
= 2.2.7 =
* IMPROVED: Worker now runs as a continuous loop, draining the queue completely before exiting
* IMPROVED: Statistics are synced after each batch (not only at the end)
* IMPROVED: Worker output includes worker ID on each line for clearer parallel logs
* FIXED: Uneven work distribution between parallel workers
* INVESTIGATING: Possible incompatibility with the Redirection plugin in MultiSite environments - output buffering mitigates known symptoms while investigation is ongoing
= 2.2.6 =

View file

@ -4,7 +4,7 @@ Tags: newsletter, smtp, email, bulk, queue, worker, amazonses, statistics
Requires at least: 4.7
Tested up to: 6.9
Requires PHP: 7.2
Stable tag: 2.2.7
Stable tag: 2.2.8
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
@ -70,15 +70,17 @@ SMTP (by ROBOTSTXT) Newsletter connects your Newsletter plugin with ROBOTSTXT SM
Set up a cron job or process supervisor to run the worker:
Single worker:
`* * * * * php /path/to/wp-content/plugins/robotstxt-smtp-newsletter/worker.php 10 "w1"`
`* * * * * php /path/to/wp-content/plugins/robotstxt-smtp-newsletter/worker.php "w1"`
Parallel processing (10 workers):
`* * * * * seq 1 10 | xargs -P10 -I{} php /path/to/worker.php 10 "w{}"`
`* * * * * seq 1 10 | xargs -P10 -I{} php /path/to/worker.php "w{}"`
Workers read the Batch Size directly from the plugin settings database. With 10 parallel workers each picking up N emails, the total simultaneous throughput is 10 × N emails.
**For WordPress MultiSite:**
Workers require the --url parameter to specify which site to process:
`* * * * * php /path/to/worker.php 10 "w1" --url="https://site.example.com"`
`* * * * * php /path/to/worker.php "w1" --url="https://site.example.com"`
See Settings → SMTP → Queue Worker Configuration for detailed commands tailored to your installation.
@ -139,8 +141,19 @@ In typical scenarios, you'll see 20-30x performance improvement. For example:
Yes. The plugin integrates with ROBOTSTXT SMTP rate limiting system to ensure you don't exceed your provider's limits.
= Is the Redirection plugin compatible? =
A possible incompatibility with the Redirection plugin is currently under investigation. When Redirection is active in a MultiSite environment, it may issue HTTP redirect headers during WordPress initialization, which can interfere with CLI worker processes. The worker uses output buffering to mitigate known symptoms. If you experience issues with the worker on a site running the Redirection plugin, please report them at the support link below.
== Changelog ==
= 2.2.8 =
* CHANGED: Batch Size is now read from plugin settings database — no longer passed as a command-line argument to the worker
* CHANGED: Worker command simplified to: php worker.php "w1" (no batch_size argument needed)
* IMPROVED: Batch Size field shows a throughput table: 10 workers × N emails = simultaneous emails
* IMPROVED: Worker section displays the current calculated simultaneous email count
* TECHNICAL: Legacy format (php worker.php 10 "w1") still supported with a deprecation warning
= 2.2.7 =
* IMPROVED: Worker now runs as a continuous loop, draining the queue completely before exiting
* IMPROVED: Statistics are synced after each batch

View file

@ -3,7 +3,7 @@
* Plugin Name: Newsletter - SMTP (by ROBOTSTXT)
* Plugin URI: https://git.robotstxt.es/ROBOTSTXT/robotstxt-smtp-newsletter
* Description: Integrates ROBOTSTXT SMTP configuration with Newsletter plugin for efficient bulk email delivery with database-backed queue and external workers.
* Version: 2.2.7
* Version: 2.2.8
* Requires at least: 4.7
* Requires PHP: 7.2
* Security: robotstxt@robotstxt.es
@ -25,7 +25,7 @@ if ( ! defined( 'ABSPATH' ) ) {
}
// Plugin constants.
define( 'ROBOTSTXT_SMTP_NEWSLETTER_VERSION', '2.2.7' );
define( 'ROBOTSTXT_SMTP_NEWSLETTER_VERSION', '2.2.8' );
define( 'ROBOTSTXT_SMTP_NEWSLETTER_FILE', __FILE__ );
define( 'ROBOTSTXT_SMTP_NEWSLETTER_PATH', plugin_dir_path( __FILE__ ) );
define( 'ROBOTSTXT_SMTP_NEWSLETTER_URL', plugin_dir_url( __FILE__ ) );

File diff suppressed because one or more lines are too long

View file

@ -7,12 +7,17 @@
*
* This script runs as a standalone CLI process, independent of WordPress cron.
* It loads WordPress with DOING_CRON defined to prevent triggering actual cron.
* Batch size is read from the plugin settings in the database no need to pass it
* as a command-line argument.
*
* Usage: php worker.php <batch_size> <worker_id> [--url=<site_url>]
* Example: php worker.php 10 "w1"
* MultiSite: php worker.php 10 "w1" --url="https://example.com"
* Parallel: seq 1 10 | xargs -P10 -I{} php worker.php 10 "w{}"
* Parallel MultiSite: seq 1 10 | xargs -P10 -I{} php worker.php 10 "w{}" --url="https://example.com"
* Usage: php worker.php <worker_id> [--url=<site_url>]
* Example: php worker.php "w1"
* MultiSite: php worker.php "w1" --url="https://example.com"
* Parallel: seq 1 10 | xargs -P10 -I{} php worker.php "w{}"
* Parallel MS: seq 1 10 | xargs -P10 -I{} php worker.php "w{}" --url="https://example.com"
*
* Legacy format (deprecated, still supported):
* php worker.php <batch_size> <worker_id> [--url=<site_url>]
*
* @package ROBOTSTXT_SMTP_Newsletter
* @since 2.2.0
@ -28,19 +33,29 @@ if ( php_sapi_name() !== 'cli' ) {
}
// Parse command-line arguments.
if ( $argc < 3 ) {
fwrite( STDERR, "Usage: php worker.php <batch_size> <worker_id> [--url=<site_url>]\n" );
fwrite( STDERR, "Example: php worker.php 10 \"w1\"\n" );
fwrite( STDERR, "MultiSite: php worker.php 10 \"w1\" --url=\"https://example.com\"\n" );
// New format: php worker.php <worker_id> [--url=<site_url>]
// Legacy format (deprecated): php worker.php <batch_size> <worker_id> [--url=<site_url>]
if ( $argc < 2 ) {
fwrite( STDERR, "Usage: php worker.php <worker_id> [--url=<site_url>]\n" );
fwrite( STDERR, "Example: php worker.php \"w1\"\n" );
fwrite( STDERR, "MultiSite: php worker.php \"w1\" --url=\"https://example.com\"\n" );
exit( 1 );
}
$batch_size = max( 1, (int) $argv[1] );
// Detect legacy format: first arg is numeric (old batch_size), second arg is worker_id.
$arg_offset = 2;
if ( is_numeric( $argv[1] ) && $argc >= 3 && 0 !== strpos( $argv[2], '--' ) ) {
// Legacy: php worker.php <batch_size> <worker_id> — batch_size argument is now ignored.
$worker_id = $argv[2];
$arg_offset = 3;
fwrite( STDERR, "[DEPRECATED] Batch size is now read from plugin settings. Remove the numeric argument from the command.\n" );
} else {
$worker_id = $argv[1];
}
// Parse optional --url parameter for MultiSite support.
$site_url = null;
for ( $i = 3; $i < $argc; $i++ ) {
for ( $i = $arg_offset; $i < $argc; $i++ ) {
if ( strpos( $argv[ $i ], '--url=' ) === 0 ) {
$site_url = substr( $argv[ $i ], 6 );
break;
@ -126,6 +141,10 @@ if ( $plugin_manually_loaded ) {
\Robotstxt_SMTP_Newsletter\Plugin::instance_init();
}
// Read batch size from plugin settings (database).
$plugin_options = get_option( 'robotstxt_smtp_newsletter_options', array() );
$batch_size = max( 1, (int) ( $plugin_options['batch_size'] ?? 10 ) );
// Get queue and statistics instances.
$queue = \Robotstxt_SMTP_Newsletter\Queue::get_instance();
$stats = \Robotstxt_SMTP_Newsletter\Statistics::get_instance();