Jake Vanderwerf
2026-05-13 226b50642af0895948fbaa623a9b7180399a63b6
inc/managers/queue/Queue.php
@@ -19,7 +19,6 @@
   public function __construct()
   {
      $this->defineTables();
      $this->storage = new Storage();
      $this->registry = new TypeRegistry();
      $this->locker = new Locker();
@@ -29,6 +28,7 @@
      add_action('jvb_process_queue', [$this, 'checkQueue']);
      add_action('jvb_queue_maintenance', [$this, 'maintenance']);
      add_action('jvb_daily_snapshot', [$this->storage, 'snapshotDaily']);
      if (!wp_next_scheduled('jvb_process_queue')) {
         wp_schedule_event(time(), 'every-minute', 'jvb_process_queue');
@@ -36,89 +36,16 @@
      if (!wp_next_scheduled('jvb_queue_maintenance')) {
         wp_schedule_event(time(), 'hourly', 'jvb_queue_maintenance');
      }
      if (!wp_next_scheduled('jvb_daily_snapshot')) {
         // Schedule for next 3am
         $next3am = strtotime('tomorrow 3am', current_time('timestamp'));
         wp_schedule_event($next3am, 'daily', 'jvb_daily_snapshot');
      }
      jvb_register_do_once('queue_admin_action_registered', [$this, 'registerAdminAction']);
      add_filter(BASE.'admin_action_filter', [$this, 'adminActionFilter'], 10, 3);
   }
   public static function defineTables():void
   {
      $queue = CustomTable::for('_operation_queue');
      $queue->setColumns([
         'id'        => 'VARCHAR(64) NOT NULL',
         'type'         => 'VARCHAR(50) NOT NULL',
         'user_id'      => $queue->getUserIDType().' NOT NULL',
         'request_data' => 'JSON NOT NULL CHECK (JSON_VALID(request_data))',
         'total_items'  => 'INT(11) NOT NULL DEFAULT 1',
         'processed_items' => 'INT(11) DEFAULT 0',
         'failed_items' => 'JSON',
         'priority'     => 'ENUM(\'high\',\'normal\',\'low\') DEFAULT \'normal\'',
         'state'        => 'ENUM(\'pending\', \'scheduled\', \'processing\', \'completed\') DEFAULT \'pending\'',
         'outcome'      => 'ENUM(\'pending\', \'success\',\'partial\',\'merged\',\'failed\',\'failed_permanent\') DEFAULT \'pending\'',
         'retries'      => 'INT(11) DEFAULT 0',
         'last_error_hash'=> 'CHAR(32) DEFAULT NULL',
         'error_message'   => 'TEXT',
         'scheduled_at' => 'DATETIME DEFAULT NULL',
         'started_at'   => 'DATETIME DEFAULT CURRENT_TIMESTAMP',
         'completed_at' => 'DATETIME DEFAULT NULL',
         'metadata'     => 'JSON DEFAULT NULL',
         'result'    => 'JSON',
         'dependencies' => 'JSON',
         'merged_into'  => 'VARCHAR(64) DEFAULT NULL',
         'user_dismissed'=> 'tinyint(1) DEFAULT 0',
         'created_at'   => 'DATETIME DEFAULT CURRENT_TIMESTAMP',
         'updated_at'   => 'DATETIME DEFAULT CURRENT_TIMESTAMP',
      ]);
      $queue->setKeys([
         ['key' => 'PRIMARY', 'value' => '(`id`)'],
         '`idx_run_queue` (`state`, `priority`, `scheduled_at`)',
         '`idx_user_ops` (`user_id`, `state`)',
         '`idx_user_type_pending` (`user_id`, `type`, `state`)',
         '`idx_completed_at` (`completed_at`)',
         '`idx_processing_stuck` (`state`, `started_at`)'
      ]);
      $queue->defineTable();
      $stats = CustomTable::for('stats__operation_queue');
      $stats->setColumns([
         'id'  => 'BIGINT unsigned AUTO_INCREMENT',
         'date'   => 'DATE NOT NULL',
         'type'   => 'VARCHAR(50) NOT NULL',
         'total_operations'      => 'INT NOT NULL DEFAULT 0',
         'successful_operations' => 'INT NOT NULL DEFAULT 0',
         'partial_operations' => 'INT NOT NULL DEFAULT 0',
         'failed_operations'     => 'INT NOT NULL DEFAULT 0',
         'failed_permanent_operations'=> 'INT NOT NULL DEFAULT 0',
         'total_items_processed' => 'INT NOT NULL DEFAULT 0',
         'average_duration'      => 'FLOAT DEFAULT NULL',
         'max_duration'       => 'INT DEFAULT NULL',
         'peak_queue_size'    => 'INT NOT NULL DEFAULT 0',
         'peak_memory_usage'     => 'INT DEFAULT NULL',
         'peak_cpu_usage'     => 'FLOAT DEFAULT NULL',
         'created_at'         => 'TIMESTAMP DEFAULT CURRENT_TIMESTAMP',
      ]);
      $stats->setKeys([
         ['key' => 'PRIMARY', 'value' => '(`id`)'],
         ['key' => 'UNIQUE', 'value' => '(`date`, `type`)'],
         '`date_idx` (`date`)',
         '`type_idx` (`type`)'
      ]);
      $stats->defineTable();
   }
   /**
    * Access type registry for registering operation configs
    */