Recovery
What the application keeps ready for a project's recovery, as a connector may read it — the coverage object behind the readiness checklist — and the two places a connector files, a standby and a replacement, through the actions the dashboard runs.
Subscriby\Connector\Core\Recovery. The readiness checklist is the connector's to word (a "standby bot", a "mirrored channel") but the facts behind it are the application's: which installation stands by, which spaces have a standby and whether it is healthy, whether posts are mirrored, whether failover is automatic. A connector reads them here and answers RecoverySupport::readinessChecks() without importing an application class. The two writes are the answers to a Standby and a Replacement link request: the creator picked a place on the platform, and the connector files it here.
coverage()
$coverage = $recovery->coverage($project, 'example');
$coverage->standbyInstallation; // bool: a standby installation is registered
$coverage->autoFailover; // bool: the creator switched automatic failover on
foreach ($coverage->spaces as $space) {
$space->resourceId; // the gated resource
$space->kind; // its stored kind, connector:kind
$space->hasStandby; // a standby place is linked
$space->standbyHealthy; // the last probe of the standby was ready
$space->mirrored; // posts are copied into it
}RecoveryCoverage names the project's standing on your connector, one SpaceCoverage per gated place.
Wording a checklist from it
public function readinessChecks(InstallationRef $installation, ProjectRef $project): array
{
$coverage = $this->recovery->coverage($project, 'example');
return [
new ReadinessItem(
key: 'standby-bot',
label: __('A standby bot is ready'),
description: __('If Example bans your bot, the standby takes over in minutes.'),
icon: 'shield-check',
satisfied: $coverage->standbyInstallation,
prevention: true,
fixRoute: 'recovery.prevention',
),
...array_map(fn (SpaceCoverage $space): ReadinessItem => new ReadinessItem(
key: 'standby-room-'.$space->resourceId,
label: __('Every room has a standby'),
description: __('A standby room is where members are moved when a room is lost.'),
icon: 'home',
satisfied: $space->hasStandby && $space->standbyHealthy,
prevention: true,
fixRoute: 'recovery.prevention',
detail: $space->hasStandby ? null : __('No standby yet.'),
), $coverage->spaces),
];
}Keys must be unique within the connector (recovery.vocabulary_and_readiness); fixRoute is a named route of the core's, and the core builds the link. Items with prevention: true are shown locked to creators without the prevention tier.
registerStandby()
$recovery->registerStandby($resource, $reserve, mirror: false);File a place as a resource's standby: the reserve the core switches to, by the creator's click or automatic failover, when the resource's place is lost. $resource is the ResourceRef the request named (Resources::find() or findBySpace() gives you one), $reserve the place the creator picked, recorded through Spaces::record() first. With mirror: true every post in the resource's place is copied into the reserve from now on, for a connector whose manifest declares recovery_mirror.
replaceSpace()
$recovery->replaceSpace($resource, $replacement);Point a resource at the place that replaces the one it lost. The core opens or continues the recovery operation, re-points the resource, revokes the links into the old place and re-admits everyone with active access into the new one; the creator follows the roll call on the Disaster Recovery page. It is the dashboard's own swap, so the owner guard, the allowance and the notices are the same whichever road the creator took.
Refusals
Both writes throw Subscriby\Connector\Exceptions\ResourceRefused for a resource the core does not know, and Subscriby\Connector\Exceptions\RecoveryRefused for anything the core's recovery rules refuse: the actor does not own the project, the plan lacks prevention, the project switched standby places off for your connector, the place is another kind, already sold or already a standby, or the self-service allowance for the window is spent. RecoveryRefused carries the core's translated sentence in userMessage(), which is what you relay to the creator on the platform, and a stable reason you may branch on to say it in your own nouns instead.
What is not here
Incidents, operations, undo, quotas and the notices to members are the core's whole subsystem and never read by a connector; the connector only witnesses (probes) and acts (standby, failover, mirror, relink) when asked through RecoverySupport, and files the two places above when the creator answers a request.
Read it fresh
Coverage is computed when you ask; do not cache it across requests. The Readiness page asks once per render.
How is this guide?
Alerts
Where a creator's alerts go, as far as a connector may ask or change it — the one switch for the account in front of the connector, and what the core keeps to itself.
Support
The support inbox as a connector feeds it and answers from it — filing a member's message, sending the acknowledgement the core says is due, handing the core a creator's answer written on the platform, finding the thread a relay message or a relay-space thread belongs to, and recording the space a project relays into.