Index

ActivateTask

MMO\admin\tasks · 1 symbol · generated 5 Oct 2026

class

ActivateTask

ActivateTask.php:20

The deploy itself: point current at the new release.

class MMO\admin\tasks\ActivateTask extends MMO\admin\classes\aDeployTask
Namespace
MMO\admin\tasks
Extends
aDeployTask
It is one atomic `rename` ([`ShellRunner::symlink`](https://mcp.mmoframework.fr/documentation/mmo.core/php/server/ShellRunner.md#shellrunner-symlink)), so there is no window in which the site serves a half-updated tree -- which a `git pull` into the live folder cannot avoid, and which is the reason the old pipeline had to ship at quiet hours. It is also the only reversible deploy step: [`rollback`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/tasks/ActivateTask.md#activatetask-rollback) re-points the link at [`Context::$previous`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/helpers/Context.md#context-previous), which takes milliseconds and needs neither git nor the network on the target.

Properties2

healthIsFatal

protected bool $healthIsFatal
Type
bool

healthTimeout

protected int $healthTimeout
Type
int

Methods17

checkHealth($context, $url)

ActivateTask.php:177

Ask the target, repeatedly, whether it is serving the release that was just activated.

protected function checkHealth(MMO\admin\helpers\Context $context, string $url): ?Throwable**What counts.** The target's `healthPath` is requested, redirects FOLLOWED, and only a final 2xx counts -- then, when the target declares `healthExpect`, only an answer containing that text. A status alone used to be enough, and a 301 counted: so the http->https redirect of the vhost passed the check without the application running at all, and so did a static `index.html` answering 200 while the release's `.htaccess` was ignored. `{checksum}` in `healthExpect` is this release's `.release` stamp: an answer containing it can only come from this release ([`expected`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/tasks/ActivateTask.md#activatetask-expected)). **On a machine of ours** the probe goes to **127.0.0.1**, the origin's name pinned there (`curl --resolve` on 80, 443 and the url's port), not to wherever DNS says. Hitting the public url from the target proves very little: a CDN, a cache or a load balancer in front of the site can answer 200 from a copy of the old release while this machine serves 500s, and a DNS record pointing elsewhere makes the check pass while the deployment is broken. The loopback probe exercises this web server, this vhost, its TLS, this symlink -- which is exactly what the swap just changed. The public url is still checked, because "works locally, unreachable from outside" is worth knowing, but it only ever WARNS: it fails for plenty of reasons that are not the release's fault, and a spurious rollback is its own outage. **On a managed webspace** none of that holds. There is no vhost of ours on that machine, so `127.0.0.1` answers the provider's default host or nothing at all, and treating that as authoritative would roll back every release. There is also frequently no `curl` on the webspace. So the probe runs from the DEPLOYING machine against the public url, which is the only statement about a shared host that is both true and checkable: *the site the customer visits serves something*. [`Target::getProbe`](https://mcp.mmoframework.fr/documentation/mmo.admin/php/entities/Target.md#target-getprobe)
$contextContext
$urlstringthe target's url; what is requested is its healthPath on that host.
returnsnull | Throwablenull when the release answered.

describe($answer, $expect)

ActivateTask.php:298
protected function describe(array $answer, ?string $expect): string
$answerarray
$expectnull | string
returnsstringwhat an answer was, for a message: its status, and why it does not count.

expected($context)

ActivateTask.php:237
protected function expected(MMO\admin\helpers\Context $context): ?string
$contextContext
returnsnull | stringthe target's healthExpect with this release's placeholders resolved: {release}, and {checksum} read from the activated release's own .release -- what is on the target, not what this run believes it shipped, so an activate or a rerun that shipped nothing checks the right thing too.

getTimeout($context)

ActivateTask.php:37
protected function getTimeout(MMO\admin\helpers\Context $context): int
$contextContext
returnsinthow long THIS target's health check may take: its own healthTimeout wins, because the right answer is a property of the machine. A host we control restarts its interpreter in reload and answers at once; a shared webspace has nothing to restart and picks the swap up as each worker's realpath cache expires, so the same 20 seconds would roll back a release that was about to be fine.

isChecked($context)

ActivateTask.php:42
protected function isChecked(MMO\admin\helpers\Context $context): bool
$contextContext
returnsboolwhether this target gets an http check at all -- it needs a url, a deadline and a probe.

isHealthy($answer, $expect)

ActivateTask.php:292
protected function isHealthy(array $answer, ?string $expect): bool
$answerarray
$expectnull | string
returnsboolwhether it means "this release is serving": a final 2xx (redirects were followed, so a 3xx here is one that went nowhere), holding $expect when there is one.

isRollbackCritical()

ActivateTask.php:146

A failed swap that cannot be undone is the one thing worth stopping the whole rollback for.

function isRollbackCritical(): bool
returnsbool

onOrigin($url, $origin)

ActivateTask.php:249
protected function onOrigin(string $url, string $origin): string
$urlstring
$originstring
returnsstring$url with its host replaced by $origin (the target's healthOrigin, usually the same).

probe($runner, $url, $loopback, $body)

ActivateTask.php:261
protected function probe( MMO\core\server\ShellRunner $runner, string $url, ?string $loopback = null, bool $body = false ): string
$runnerShellRunnerthe shell that will run it.
$urlstring
$loopback = nullnull | stringa host name to pin to 127.0.0.1 -- on 80 and 443, so the vhost's http->https redirect stays on this machine, and on the url's own port.
$body = falseboolwhether the answer's body is needed (to look for healthExpect in it).
returnsstringthe curl command: it prints the body (when wanted), a newline, then the FINAL http status.

request($runner, $command)

ActivateTask.php:275
protected function request(MMO\core\server\ShellRunner $runner, string $command): array
$runnerShellRunner
$commandstring
returnsarraystring, body: string} the final http status ('' when the request did not complete) and the body.

__construct($healthTimeout, $healthIsFatal)

ActivateTask.php:21
function __construct(int $healthTimeout = 20, bool $healthIsFatal = true)
$healthTimeout = 20int
$healthIsFatal = truebool
Inherited members (36)
ConstantsDeclared byDescription
ALERTiLogLevelAlert: Action must be taken immediately.
ALLiLogLevelMask for all
ALL_PLUSiLogLeveldebug everything
BACKTRACEiLogLevel
CRITICALiLogLevelCritical: Critical conditions.
DEBUGiLogLevelDebug: Detailed debug information.
DEEPiLogLeveldebug everything with arguments
EMERGENCYiLogLevelEmergency: System is unusable.
ERRORiLogLevelError: Runtime errors that do not require immediate action but should typically be logged and monitored.
ERROR_PLUSiLogLevelMask for all error
FATALiLogLevelMask for all fatal error
INFOiLogLevelInfo: Interesting events.
INFO_PLUSiLogLevelMask for all errors/warning/notices/info
MEMORYiLogLevelinclude backtrace object
NOTICEiLogLevelNotice: Normal but significant events.
NOTICE_PLUSiLogLevelMask for all errors/warning/notices/info
TRACEiLogLevelinclude backtrace as origins
WARNINGiLogLevelWarning: Exceptional occurrences that are not errors.
WARNING_PLUSiLogLevelMask for all errors and warnings
PropertiesDeclared byDescription
verbosityaDeployTask
MethodsDeclared byDescription
alert($message, $context)aDeployTaskAction must be taken immediately.
backtraces($message, $context)aDeployTaskForce-log a message at INFO level together with a full stack trace/memory snapshot (iLogLevel::BACKTRACE), bypassing the verbosity mask entirely (any non-zero verbosity is enough to trigger it).
critical($message, $context)aDeployTaskCritical conditions. No-op if CRITICAL is currently filtered out by the verbosity mask.
debug($message, $context)aDeployTaskDetailed debug information.
debugName()aDeployTask
emergency($message, $context)aDeployTaskSystem is unusable. No-op if EMERGENCY is currently filtered out by the verbosity mask.
error($message, $context)aDeployTaskRuntime errors that do not require immediate action but should typically be logged and monitored.
getName()aDeployTask
getVerbosity()aDeployTask
info($message, $context)aDeployTaskInteresting events. No-op if INFO is currently filtered out by the verbosity mask.
isChange()aDeployTaskWhether running this task CHANGES anything.
log($level, $message, $context)aDeployTaskLogs with an arbitrary level.
notice($message, $context)aDeployTaskNormal but significant events.
setVerbosity($verb)aDeployTaskSet the current verbosity mask, replacing whatever it was before.
testVerbosity($level)aDeployTaskTest whether a given level (or set of levels) is currently enabled by this instance's verbosity mask.
warning($message, $context)aDeployTaskExceptional occurrences that are not errors.