Define re-usable idiom for deferrable upgrade steps
Overview
In managing upgrade-steps, there is some tension between:
- Making the upgrades automatic for typical sysadmins
- Allowing very large deployments to schedule/manage expensive upgrade-steps
This proposes to balance those expectations by defining a deferrable upgrade task. Sysadmins can choose to approach them a few ways:
- "Just run the task like every other upgrade step" (e.g. default; for average and small systems)
- "Let me decide when to run it... but please don't make me figure out obscure incantations" (for larger systems)
- "Let me find a highly-optimized/bespoke way to accomplish the change" (for extra-large systems with a team of admins)
Example use-case
- Take a table (like
civicrm_contact
,civicrm_activity
,civicrm_mailing_event_queue
) which can be very large on some deployments. - Define a schema change (e.g. add a column and an index)
- Executing this change be quite slow.
- In the long-term, all systems need the schema-change. If people skip it, then it will lead to problems/confusion/bug-reports/etc.
- In the near-future, the schema change is not quite mandatory. (The new column isn't actively used; or its usages are limited+guarded.)
A sketch
- Designate a place to store a list of deferred upgrade steps (e.g.
civicrm_deferred_upgrade
orcivicrm_queue_item
) - In the
CRM/Upgrade/
system, add some helpers to conditionally execute or defer a step. Ex:$this->addDeferrableTask(ts('Update CiviMail tracking'), 'doCiviMailQueueConversion');
function addDeferrableTask($title, $funcName, $args) { if (deferred upgrades enabled) { // Add $title, $action, $args to a persistent TODO list } else { $this->addTask($title, $funcName, $args); } }
- Add a system-status-check and post-upgrade message to warn if there are any of these things that need to run
- Add an API/job/command/UI to list/execute/skip/delete deferred steps