Appearance
P-WORLDメール取得・TTLバッチ
目的
P-WORLD 配信メールを IMAP で取得・保存し、必要に応じてメール本文・関連画像・GIF 添付の TTL パージを実行する。取得経路は、管理画面から起動する手動非同期ジョブと、WP-Cron による定期ジョブの2つ。
管理画面と admin-ajax の契約は ADM-001 P-WORLDメールアーカイブ管理画面 と EP-一覧 を参照する。
トリガー
| トリガー | 実行内容 |
|---|---|
pworld_archive_run | 手動取得ジョブを pworld_archive_async_run として単発 WP-Cron に登録する |
pworld_archive_async_run | 管理画面から起動された IMAP 取得を実行する |
admin_init | 定期取得・メール本文 TTL・GIF TTL のいずれかが有効な場合、定期 slot の単発 WP-Cron を同期する |
pworld_archive_cron_settings_save | 定期取得・TTL 設定を保存し、定期 slot を再登録する |
pworld_archive_scheduled_job | 定期 IMAP 取得、メール TTL パージ、GIF TTL パージを実行する |
手動取得ジョブ
PworldArchiveAdminPage::ajax_run() が入力を検証し、ジョブ状態を running(job_type=imap_fetch)にしたうえで pworld_archive_async_run を単発登録する。
| 項目 | 内容 |
|---|---|
| 実行クラス | PworldArchiveAsyncRunner |
| 入力 | job_id, date_from, date_to, limit |
| 件数上限 | 1〜500。未指定または範囲外はデフォルト 5 |
| 排他 | PworldArchiveMysqlRunLock |
| 成功時 | PworldArchiveJobState::set_done() に取得結果を保存する |
| 失敗時 | PworldArchiveJobState::set_error() にエラーを保存する |
同時実行で MySQL ロックを取れない場合は、先行ジョブの完了状態を壊さないため、ジョブ状態は running のまま維持してログだけ出す。
バルク記事連携保存ジョブ
PworldArchiveAdminPage::ajax_bulk_save_article_links() が行を同期検証し、ジョブ状態を running(job_type=bulk_article_link)にしたうえで同一 Cron hook pworld_archive_async_run を単発登録する。Runner は bulk_update_article_links のみ実行し、一覧ペイロードは ajax_job_status 完了時にマージする。手動 IMAP 取得と JobState / MySQL ロックを共有する。
| 項目 | 内容 |
|---|---|
| 実行クラス | PworldArchiveAsyncRunner(handle 内で job_type 分岐) |
| 入力 | 検証済み rows、一覧ページ・フィルタ(JobState params) |
| 排他 | PworldArchiveMysqlRunLock + 単一 pworld_archive_job_state |
| 成功時 | set_done({ updated_count }) |
| 失敗時 | set_error() |
| stale 閾値 | BULK_STALE_THRESHOLD_SECONDS(180 秒。IMAP 用 720 秒とは別) |
定期ジョブ
PworldArchiveCronScheduler が、サイトタイムゾーンの壁時計に寄せた単発イベント連鎖で定期 slot を登録する。
| 項目 | 内容 |
|---|---|
| 実行クラス | PworldArchiveScheduledCronRunner |
| Cron hook | pworld_archive_scheduled_job |
| slot | 2100, 2130, 2145, 2200, 2230(21:00・21:30・21:45・22:00・22:30) |
| 登録条件 | 定期取得・メール本文 TTL・GIF TTL のいずれかが有効 |
| 排他 | PworldArchiveScheduledMysqlRunLock |
| ログ | PworldArchiveScheduledJobLogger に status / fetch / ttl / gif_ttl を保存する |
定期ジョブは、Cron 実行時またはスケジュール同期時に maybe_upgrade_cron_event_model() を実行する。保存済みの pworld_archive_cron_event_model_version が CRON_EVENT_MODEL_VERSION より古ければ、reschedule_all_slots() を一度だけ実行する。旧 daily 再発火モデルから単発連鎖モデルへの移行(バージョン 2)と、21:30・21:45 の slot 追加(バージョン 3、Issue #3988)でこの仕組みを使った。
reschedule_all_slots() は wp_unschedule_hook() で pworld_archive_scheduled_job のイベントを引数に関係なくすべて外し、登録条件を満たすときだけ各 slot を 1 件ずつ登録し直す。各回は [ $slot ] 付きで登録しているため、引数が空のイベントしか消さない wp_clear_scheduled_hook() は使わない(Issue #4028)。予定時刻を過ぎてまだ実行されていない回(サーバー cron の起動待ちや、先の回の処理が長引いた場合)は、外す前に予定時刻を控えておき、その時刻で登録し直す。この回は次の Cron 実行で処理され、翌日分は実行後に同 slot の次回登録で追加されるため、当日分と翌日分が重複しない。その回が fatal(実行時間やメモリの上限超過)で終わり次回登録まで進まなかった場合は、次のスケジュール同期(admin_init で 1 日 1 回、または設定保存)で翌日分が登録される。登録条件を満たさないときは、期限切れの回も含めて予定を 0 件にする。wp_unschedule_hook() が失敗した場合は error_log() に記録する。
slot の追加・削除・時刻の変更をしたときはバージョンを上げる。上げないと、追加した slot は次のスケジュール同期(admin_init で 1 日 1 回、未登録の slot を追加する)または設定保存まで登録されない。削除・変更前の slot のイベントは 1 回だけ実行される(Runner が許可リスト外として終了し、翌日分は登録しない)。スケジュール同期で登録条件を満たさないときも、wp_unschedule_hook() で登録済みのイベントをすべて外す。登録条件は、定期ジョブの処理内容の「すべて無効なら終了する」と同じ 3 設定で判定する(Issue #4042)。GIF TTL だけを有効にしても各 slot が登録され、GIF TTL パージが実行される。
TTL パージ
| 対象 | 保持日数 | 件数上限 | dry-run | 削除対象 |
|---|---|---|---|---|
| メール本文・関連画像 | 管理画面設定。既定 90 日 | 管理画面設定。既定 50 件 | 管理画面設定。既定 ON | 保持期間を超えたメール、本文内画像、関連参照 |
| GIF 添付 | 管理画面設定。既定 30 日 | 管理画面設定。既定 50 件 | 管理画面設定。既定 ON | _pworld_gif_expires_at を過ぎた GIF 添付のみ |
GIF TTL では代表静止画添付は削除しない。代表静止画の選択ルールは P-WORLD GIF 代表静止画・TTL を参照する。
定期ジョブの処理内容
- 保存済みの Cron event model のバージョンが古ければ
reschedule_all_slots()で全 slot を登録し直す。 - slot が許可リスト外なら終了する。
- 定期取得・メール TTL・GIF TTL がすべて無効なら終了する。
- MySQL ロックを取得する。取得できない場合は
skipped/lock_not_acquiredとしてログに残す。 - 定期取得が有効なら
PworldArchiveService::run(null, null, limit)を実行する。 - メール TTL が有効なら
PworldMailTtlPurgeServiceInterface::purge()を実行する。 - GIF TTL が有効なら
PworldGifTtlPurgeServiceInterface::purge()を実行する。 - 実行結果を保存し、ロックを解放する。
- 単発連鎖モデル移行直後でなければ、同 slot の次回イベントを登録する。
定期ジョブで \Throwable が発生した場合は、PworldArchiveScheduledJobLogger に status: error として記録する。
関連処理
メール保存成功後には、日別ホールサムネイル自動生成が呼び出される。GIF バックフィルや GIF 代表静止画再生成は、管理画面の明示操作から起動される保守処理であり、本定期取得ジョブとは別経路で実行する。
参照ファイル
core_src/Admin/pworld_archive/PworldArchiveAdminPage.phpcore_src/Admin/pworld_archive/PworldArchiveAsyncRunner.phpcore_src/Admin/pworld_archive/PworldArchiveCronScheduler.phpcore_src/Admin/pworld_archive/PworldArchiveScheduledCronRunner.phpcore_src/Admin/pworld_archive/PworldArchiveCronSettings.phpcore_src/Admin/pworld_archive/PworldArchiveJobState.phpcore_src/Bootstrap/service_provider/AdminServiceProvider.php