RemoteKillSwitchController class
Emergency remote kill switch for a feature/event/shop/animation — built on top of RemoteConfigService (FEAT-39/ENH-58 already give it asset-fallback + partial-merge + last-known-good semantics at the config-value level; this controller adds the kill-switch-specific safety policy ON TOP: an invalid or missing remote value can never flip a feature from killed back to enabled — see KillSwitchSource for the exact resolution order).
Reactive: states is an RxMap, so any widget wrapped in Obx
watching states[featureId] rebuilds the moment isKilled (or
refreshAll) resolves a new decision for that feature — a screen
already open when ops flips a switch remotely reacts without needing
to be rebuilt/reopened, and without touching whatever it's currently
doing (no crash, since it's just watching a value, not being torn
down).
- Inheritance
-
- Object
- GetLifeCycle
- DisposableInterface
- GetxService
- RemoteKillSwitchController
Constructors
-
RemoteKillSwitchController({required RemoteConfigService remoteConfig, Map<
String, bool> assetDefaults = const {}, String keyPrefix = 'kill_switch_', int nowMs()?})
Properties
-
assetDefaults
→ Map<
String, bool> -
Bundled fallback kill state per feature, used only when no valid
remote value has EVER been seen for that feature (see
KillSwitchSource.assetDefault) — a feature absent from this map
defaults to
false(not killed, normal operation).final -
auditLog
→ List<
KillSwitchState> -
Every decision ever made, oldest first, capped at
_auditCapacity— "audit reason/version" over time, not just the current snapshot.no setter - hashCode → int
-
The hash code for this object.
no setterinherited
- initialized → bool
-
Checks whether the controller has already been initialized.
no setterinherited
- isClosed → bool
-
Checks whether the controller has already been closed.
no setterinherited
- keyPrefix → String
-
The remote config key for
featureIdis'$keyPrefix$featureId'.final -
onDelete
→ InternalFinalCallback<
void> -
Internal callback that starts the cycle of this controller.
finalinherited
-
onStart
→ InternalFinalCallback<
void> -
Called at the exact moment the widget is allocated in memory.
It uses an internal "callable" type, to avoid any @overrides in subclases.
This method should be internal and is required to define the
lifetime cycle of the subclass.
finalinherited
- remoteConfig → RemoteConfigService
-
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
-
states
→ RxMap<
String, KillSwitchState> -
Reactive last-resolved state per feature — read-through by
isKilled/refreshAll, never written directly by a caller.
final
Methods
-
$configureLifeCycle(
) → void -
inherited
-
clearLocalOverride(
String featureId) → void -
Removes a prior forceKillLocally override for
featureId— the next isKilled/refreshAll call falls back through to the normal remote/cached/asset resolution order again. -
forceKillLocally(
String featureId, {required String reason}) → void -
Force-kills
featureIdimmediately, CLIENT-SIDE, without waiting for the next remoteConfig poll — see KillSwitchSource.localOverride.reasonis required (unlike the remote/asset paths, where it's optional) since a local override always needs an audit trail explaining why THIS device decided to kill a feature on its own. -
isKilled(
String featureId) → bool -
Resolves
featureId's current kill state (updating states and auditLog as a side effect) and returns whether it's killed. -
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
onClose(
) → void -
Called before
onDeletemethod.onClosemight be used to dispose resources used by the controller. Like closing events, or streams before the controller is destroyed. Or dispose objects that can potentially create some memory leaks, like TextEditingControllers, AnimationControllers. Might be useful as well to persist some data on disk.inherited -
onInit(
) → void -
Called immediately after the widget is allocated in memory.
You might use this to initialize something for the controller.
inherited
-
onReady(
) → void -
Called 1 frame after onInit(). It is the perfect place to enter
navigation events, like snackbar, dialogs, or a new route, or
async request.
inherited
-
refreshAll(
Iterable< String> featureIds) → void -
Re-resolves every id in
featureIds— for a periodic/lifecycle- resume hook that wants every tracked switch's states entry fresh even for features no widget has directly asked about yet. -
runIfEnabled<
T> (String featureId, T action()) → T? -
Runs
actionand returns its result — but ONLY iffeatureIdis not currently killed; returnsnulland never callsactionotherwise. Makes "don't grant/execute a killed feature" the path of least resistance instead of relying on every call site remembering its ownif (!isKilled(...))guard. -
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited
Static Properties
- maybe → RemoteKillSwitchController?
-
no setter