558 lines
24 KiB
Markdown
558 lines
24 KiB
Markdown
---
|
|
id: AGD-0008
|
|
ticket: perf-async-background-work-lanes-for-assets-and-fs
|
|
title: Agenda - [PERF] Async Background Work Lanes for Assets and FS
|
|
status: accepted
|
|
created: 2026-03-27
|
|
resolved: 2026-06-28
|
|
decision: DEC-0034
|
|
tags: [perf, asset, fs, async, scheduler, runtime]
|
|
---
|
|
|
|
# Agenda - [PERF] Async Background Work Lanes for Assets and FS
|
|
|
|
## Contexto
|
|
|
|
Depois das decisoes de render worker, a concorrencia de render saiu do escopo
|
|
desta agenda. O problema restante e a lane de trabalho assincrono para IO,
|
|
decode e persistencia.
|
|
|
|
O modelo de execucao que queremos discutir agora assume uma terceira core/lane
|
|
dedicada a trabalhos assincronos de runtime:
|
|
|
|
```text
|
|
Core/lane 1: VM, firmware, SystemOS e frame logico
|
|
Core/lane 2: render worker / rasterizacao assincrona
|
|
Core/lane 3: async work lane para asset IO/decode e possivelmente FS
|
|
```
|
|
|
|
Essa terceira lane nao deve virar um pool grande e solto. A intencao e ter uma
|
|
fila previsivel, com capacidade limitada, telemetria e regras de saturacao.
|
|
|
|
Para assets, a necessidade e concreta: `asset.load()` ainda cria uma thread do
|
|
SO por requisicao. Para FS, a motivacao provavel era evitar que operacoes de
|
|
leitura/escrita/listagem/delete, hoje chamadas de forma sincrona pelo dispatch,
|
|
roubem tempo do frame quando o backend real envolver IO. Precisamos verificar
|
|
se FS deve usar a mesma lane agora ou apenas reservar compatibilidade.
|
|
|
|
## Problema
|
|
|
|
`asset.load()` hoje dispara `thread::spawn` por requisicao de asset nao
|
|
residente. Isso escala mal, cria jitter e deixa o runtime sem uma politica
|
|
unica de backpressure.
|
|
|
|
O dominio `fs` tambem tem operacoes potencialmente bloqueantes (`read`,
|
|
`write`, `list_dir`, `delete`, memcard commit/read/write) e a tabela de
|
|
syscalls ja as marca como nao deterministicas/custosas. Ainda assim, a
|
|
implementacao atual executa essas chamadas diretamente no caminho de dispatch.
|
|
|
|
Sem um contrato explicito, cada dominio pode inventar sua propria concorrencia:
|
|
asset criando threads, FS bloqueando o frame, e memcard herdando comportamento
|
|
acidental do backend.
|
|
|
|
## Pontos Criticos
|
|
|
|
- `thread::spawn` por request escala mal e cria jitter.
|
|
- A terceira core/lane deve ser um recurso de plataforma controlado, nao uma
|
|
permissao geral para criar threads.
|
|
- Asset loading precisa de um pool/fila limitada para multiplos loads
|
|
pendentes.
|
|
- FS pode justificar a mesma lane quando envolver IO real, mas nao devemos
|
|
assinar uma API assincrona ampla sem entender a semantica de retorno.
|
|
- Commit/install em bancos residentes pode ter restricoes de determinismo e
|
|
ownership; decode pode ser assincrono, mas publicacao/instalacao talvez tenha
|
|
que cruzar de volta para a lane principal.
|
|
- A estrategia precisa funcionar em hardware alvo com poucos cores e tambem no
|
|
host desktop sem transformar desktop em referencia de custo errada.
|
|
- Render worker ja tem seu proprio contrato e nao deve compartilhar essa lane.
|
|
|
|
## Hotspots Atuais
|
|
|
|
- [asset.rs](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/runtime/crates/console/prometeu-drivers/src/asset.rs#L438) - `AssetManager::load`.
|
|
- [asset.rs](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/runtime/crates/console/prometeu-drivers/src/asset.rs#L507) - `thread::spawn` por load.
|
|
- [fs.rs](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/runtime/crates/console/prometeu-hal/src/syscalls/domains/fs.rs#L4) - `fs` e `mem` marcados como superficies custosas/nao deterministicas.
|
|
- [dispatch.rs](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/runtime/crates/console/prometeu-system/src/services/vm_runtime/dispatch.rs#L549) - chamadas `fs.*` executam no dispatch.
|
|
- [virtual_fs.rs](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/runtime/crates/console/prometeu-system/src/services/fs/virtual_fs.rs#L69) - VFS normaliza path e chama backend diretamente.
|
|
|
|
## Alvo da Discussao
|
|
|
|
Fechar um modelo de terceira core/lane para trabalho assincrono de runtime,
|
|
comecando por asset loading e avaliando se FS deve entrar na mesma lane no v1.
|
|
|
|
O alvo nao e criar multitarefa geral, callbacks para guest, ou um scheduler
|
|
paralelo da VM. A lane deve executar trabalho de IO/decode/sync e publicar
|
|
resultados observaveis por status/polling em pontos previsiveis.
|
|
|
|
## O Que Precisa Ser Definido
|
|
|
|
1. Topologia da terceira lane.
|
|
Definir:
|
|
- uma async work lane dedicada, separada da VM e do render worker;
|
|
- se a lane e uma thread fixa no host e uma core dedicada no hardware alvo;
|
|
- fallback quando nao houver core fisico dedicado;
|
|
- proibicao explicita de `thread::spawn` por request no caminho normal.
|
|
|
|
2. Pool/fila de asset loading.
|
|
Definir:
|
|
- backlog de pedidos sem limite operacional fixo;
|
|
- exatamente um job ativo por vez na lane;
|
|
- o "pool" significa backlog e estados de job, nao multiplos workers reais;
|
|
- politica de substituicao/cancelamento para pedidos que miram o mesmo
|
|
bank/slot;
|
|
- status para pending/backlog, ativo, progresso, cancelamento, erro de
|
|
decode e sucesso.
|
|
|
|
3. Fases do asset load.
|
|
Separar:
|
|
- request e alocacao de handle;
|
|
- leitura de bytes;
|
|
- decode/materializacao;
|
|
- staging de resultado;
|
|
- install/commit em banco residente.
|
|
|
|
Ponto a fechar: quais fases rodam na terceira lane e quais voltam para a
|
|
lane principal por determinismo/ownership.
|
|
|
|
4. Inclusao de FS na mesma lane.
|
|
Verificar se `fs` deve usar a terceira lane no v1 para:
|
|
- leituras grandes;
|
|
- escritas;
|
|
- listagem;
|
|
- delete;
|
|
- memcard commit/read/write.
|
|
|
|
Ponto a fechar: FS sync publico continua bloqueante/status-first, vira
|
|
request/poll, ou ganha apenas uma implementacao interna que drena trabalho em
|
|
pontos de frame.
|
|
|
|
5. Separacao por dominio.
|
|
Decidir se `asset` e `fs` compartilham uma fila com classes de prioridade ou
|
|
se a terceira lane contem subfilas dedicadas.
|
|
|
|
6. Politica de prioridade.
|
|
Definir:
|
|
- prioridade de loads visuais vs audio;
|
|
- prioridade de save/config;
|
|
- prioridade de memcard commit;
|
|
- starvation prevention;
|
|
- limite de trabalho de instalacao/publicacao por frame.
|
|
|
|
7. Modelo de retorno e telemetria.
|
|
Fechar como guest/runtime observa:
|
|
- `pending`;
|
|
- `loading`;
|
|
- `ready`;
|
|
- `canceled`;
|
|
- `backend_unavailable`;
|
|
- backlog;
|
|
- posicao de um asset no backlog;
|
|
- progresso percentual do asset ativo;
|
|
- drops/retries quando aplicavel.
|
|
|
|
8. Orcamento para hardware barato.
|
|
Definir o baseline:
|
|
- VM principal;
|
|
- render worker;
|
|
- terceira async work lane;
|
|
- limites de memoria para jobs pendentes e buffers temporarios.
|
|
|
|
## Opcoes
|
|
|
|
### Opcao A - Terceira lane unica com subfilas e pool limitado de assets
|
|
|
|
- **Abordagem:** criar uma async work lane dedicada. Assets usam um pool/fila
|
|
de jobs nessa lane; FS tambem pode submeter jobs na mesma lane, com
|
|
prioridade menor ou classe separada.
|
|
- **Pro:** modelo simples de budget; evita explosao de threads; encaixa no alvo
|
|
de terceira core; permite compartilhar backpressure e telemetria.
|
|
- **Contra:** assets e FS podem competir por IO; precisa politica clara para
|
|
evitar que save/config fique atras de loads longos.
|
|
- **Manutenibilidade:** boa se a lane tiver tipos de job e estados explicitos.
|
|
|
|
### Opcao B - Lane de assets agora, FS apenas reservado
|
|
|
|
- **Abordagem:** fechar v1 somente para asset loading, removendo `spawn` por
|
|
request. FS continua sincrono por enquanto, mas o contrato da lane reserva
|
|
compatibilidade para FS no futuro.
|
|
- **Pro:** menor escopo; resolve a dor concreta de assets rapidamente; evita
|
|
alterar semantica de FS antes da agenda de app home filesystem.
|
|
- **Contra:** nao resolve stalls reais de FS/memcard; pode exigir refatorar a
|
|
lane depois para aceitar FS.
|
|
- **Manutenibilidade:** boa no curto prazo, com risco de segunda migracao.
|
|
|
|
### Opcao C - Lanes separadas para asset e FS
|
|
|
|
- **Abordagem:** criar uma lane/pool para assets e outra para FS.
|
|
- **Pro:** isolamento forte; FS/save nao compete diretamente com loads de
|
|
textura/audio/cena.
|
|
- **Contra:** consome mais threads/cores; contraria a premissa de terceira core
|
|
unica; pior para hardware simples.
|
|
- **Manutenibilidade:** media; isolamento ajuda, mas a topologia fica pesada.
|
|
|
|
### Opcao D - Pool global pequeno sem nocao de terceira lane
|
|
|
|
- **Abordagem:** trocar `spawn` por request por um pool global fixo.
|
|
- **Pro:** simples de implementar em host desktop.
|
|
- **Contra:** perde a arquitetura de lanes por core; pode mascarar custo em
|
|
desktop; fica menos claro como mapear para hardware alvo.
|
|
- **Manutenibilidade:** baixa para o modelo de console se virar dependencia
|
|
acidental de scheduler do SO.
|
|
|
|
## Sugestao / Recomendacao
|
|
|
|
Recomendo seguir com a Opcao A como direcao de arquitetura, mas fechar a
|
|
decisao em duas camadas:
|
|
|
|
1. Contrato obrigatorio agora:
|
|
- terceira async work lane como recurso runtime;
|
|
- assets deixam de usar `thread::spawn` por requisicao;
|
|
- asset loading passa por backlog consultavel/reordenavel;
|
|
- status, progresso e telemetria de backlog ficam explicitos.
|
|
|
|
2. Contrato condicionado para FS:
|
|
- FS deve ser analisado como consumidor legitimo da mesma lane porque suas
|
|
operacoes podem envolver IO real e ja sao custosas/nao deterministicas;
|
|
- a decisao precisa escolher entre incluir FS no v1 ou reservar a lane para
|
|
FS sem mudar ainda a superficie publica;
|
|
- memcard precisa ser considerado junto com FS, porque usa a mesma
|
|
capacidade e backend de persistencia.
|
|
|
|
O ponto importante: a terceira core/lane deve ser a unidade de concorrencia.
|
|
O pool de assets deve existir dentro desse modelo, nao como criacao livre de
|
|
threads por load.
|
|
|
|
## Respostas Consolidadas Ate Aqui
|
|
|
|
1. O pool de assets deve ser uma lane serial.
|
|
- Ha exatamente um job ativo na async work lane.
|
|
- O pool representa backlog, estados e controle de ordem, nao multiplos
|
|
workers executando em paralelo.
|
|
|
|
2. O backlog de pedidos deve ser semanticamente ilimitado.
|
|
- Nao existe `queue_full` como status normal do dominio.
|
|
- Como cada pedido mira um `bank_type/slot` e pedidos novos para o mesmo
|
|
alvo substituem os anteriores, o backlog efetivo fica limitado pela soma
|
|
dos slots dos bancos.
|
|
- O contrato nao precisa expor limite de fila, mas a implementacao deve
|
|
garantir que metadados de handles cancelados/superseded nao crescam sem
|
|
coleta.
|
|
|
|
3. Asset loading precisa expor consulta e reordenacao do backlog.
|
|
- Deve existir API publica/runtime para consultar onde um asset esta no
|
|
backlog.
|
|
- Deve existir capacidade de adiantar ou atrasar um pedido de asset na fila.
|
|
- O asset ativo deve expor progresso percentual.
|
|
- Requests novos para o mesmo `bank_type/slot` devem cancelar pedidos
|
|
anteriores pendentes para aquele alvo, evitando carregar asset que ja foi
|
|
substituido antes de executar.
|
|
- Se o alvo ja estiver carregado com o mesmo `asset_id`, o novo request nao
|
|
entra no backlog; ele retorna imediatamente pronto com handle disponivel.
|
|
- Se um novo request substituir o alvo atualmente ativo, a lane deve cancelar
|
|
em ponto cooperativo quando possivel; se o trabalho nao puder ser
|
|
interrompido, o resultado antigo deve ser descartado ao final por geracao
|
|
superseded.
|
|
- `superseded` significa que um request foi substituido por outro request
|
|
mais novo para o mesmo `bank_type/slot`. Nao e erro e nao e cancelamento
|
|
manual; e obsolescencia operacional do pedido antigo.
|
|
- Handles representam o slot do bank como alvo estavel. Dentro do estado do
|
|
handle deve existir uma secao de request/backlog para aquele slot,
|
|
informando se ha pedido pendente/ativo, qual asset foi solicitado,
|
|
progresso, posicao e geracao.
|
|
- Handles devem ser capazes de consultar o estado do alvo `bank_type/slot`
|
|
a qualquer momento. Se nao houver asset valido carregado e tambem nao
|
|
houver request pendente para aquele alvo, a consulta deve retornar estado
|
|
explicito de vazio/invalido, nao falhar por ausencia de request ativo.
|
|
|
|
4. Decode/materializacao fria rodam na terceira lane.
|
|
- Leitura e decode de asset podem acontecer fora da lane principal.
|
|
- O resultado deve voltar como material pronto/staged.
|
|
|
|
5. Install/commit em bancos residentes continua na lane principal.
|
|
- A async lane prepara trabalho.
|
|
- A lane principal publica/instala em pontos previsiveis por ownership,
|
|
determinismo e integracao com bancos/render/audio.
|
|
|
|
6. FS e memcard entram como consumidores possiveis da mesma lane, mas precisam
|
|
ser melhor amarrados com a agenda de app home filesystem.
|
|
- A `DSC-0007` / `AGD-0006` deve ser ajustada para estabelecer melhor a
|
|
superficie publica e o modelo async/sync de FS.
|
|
- Esta agenda deve afirmar a existencia da lane para trabalhos async de IO
|
|
desse tipo e permitir que FS a consuma.
|
|
- Questoes de API publica de FS, request/poll e semantica de app home devem
|
|
ficar a cargo da agenda 6.
|
|
- FS, memcard e assets nao devem operar sobrepostos quando isso gerar
|
|
concorrencia real de backend; se houver competicao, a fila unica resolve a
|
|
ordem.
|
|
|
|
7. Prioridade quando houver competicao:
|
|
- memcard commit/write;
|
|
- FS write/config;
|
|
- asset visual/audio load;
|
|
- list/read nao critico.
|
|
|
|
8. Status-first continua valendo.
|
|
- `backend_unavailable`, `canceled`, erro de decode e estados de job sao
|
|
status operacionais.
|
|
- Cancelamento por superseding de pedido no mesmo bank/slot e resultado
|
|
operacional normal, nao fault.
|
|
- Nao ha `queue_full` no contrato esperado.
|
|
- Trap permanece para violacao estrutural, como argumento invalido,
|
|
capability ausente ou handle estruturalmente invalido.
|
|
|
|
9. Telemetria minima:
|
|
- backlog atual;
|
|
- posicao por asset;
|
|
- progresso percentual do asset ativo;
|
|
- jobs submetidos, concluidos, falhos e cancelados;
|
|
- tempo por job;
|
|
- percentis por asset enquanto estiver carregando na lane.
|
|
|
|
10. Escopo da agenda.
|
|
- O foco desta agenda e a lane, assets e memcard/game persistence.
|
|
- FS entra como consumidor permitido da lane de IO, mas as decisoes de API
|
|
publica de FS pertencem a `AGD-0006`.
|
|
|
|
11. API de backlog.
|
|
- A API inicial sugerida cobre os casos esperados.
|
|
- `asset.backlog_promote(handle)` deve ser mantido como atalho oficial para
|
|
`asset.backlog_move(handle, 1)`.
|
|
- `asset.backlog_demote(handle)` deve ser mantido como atalho oficial para
|
|
mover o pedido para o fim dos pendentes.
|
|
- Os atalhos nao criam semantica nova; apenas evitam que o caller calcule
|
|
posicoes comuns.
|
|
- O handle deve permitir consulta estavel do slot do bank mesmo quando nao ha
|
|
asset valido carregado.
|
|
- O estado do handle deve separar:
|
|
- estado do slot/residencia atual;
|
|
- estado do request/backlog atual para aquele slot.
|
|
- Operacoes que mudam estado, como commit/cancel/reorder, atuam sobre a
|
|
secao de request/backlog do handle e precisam validar geracao/request atual
|
|
para nao agir sobre um pedido substituido.
|
|
|
|
12. Cancelamento por substituicao.
|
|
- Quando um request novo chega para o mesmo `bank_type/slot`, o request
|
|
anterior e marcado imediatamente como `superseded`.
|
|
- Se o request anterior ainda estiver no backlog, ele sai da fila.
|
|
- Se o request anterior estiver ativo, a lane tenta cancelar
|
|
cooperativamente quando a fase atual permitir.
|
|
- Se a fase ativa nao puder ser interrompida com baixo custo, ela termina e
|
|
o resultado e descartado ao final porque a geracao do alvo ja mudou.
|
|
- Como o handle pertence ao slot do bank, ele continua consultavel; sua
|
|
secao de request deve indicar que a geracao anterior foi `superseded` ou
|
|
que nao ha request ativo para aquele alvo.
|
|
|
|
13. Fases de progresso.
|
|
- `read/decode/stage` e suficiente como modelo minimo para `GLYPH`, `SOUND`
|
|
e `SCENE`.
|
|
- Subfases futuras podem detalhar progresso dentro de `decode` sem mudar o
|
|
contrato geral.
|
|
|
|
14. Percentis.
|
|
- Percentis devem existir por `bank_type` como telemetria principal.
|
|
- Percentis por `asset_id` tambem sao uteis, mas podem usar janela pequena
|
|
ou agregador leve.
|
|
- Percentis sao atualizados no fechamento do job, nao durante o hot path.
|
|
|
|
15. Ajuste esperado na agenda de FS.
|
|
- `AGD-0006` deve registrar que existe uma async IO lane compartilhavel por
|
|
FS/memcard/assets.
|
|
- Esta agenda so decide que FS pode consumir a lane.
|
|
- A API publica de FS, incluindo request/poll ou sync aparente, pertence a
|
|
`AGD-0006`.
|
|
|
|
## API Inicial Sugerida Para Assets
|
|
|
|
Esta agenda ainda nao fecha nomes finais de ABI, mas a direcao inicial sugerida
|
|
e manter `asset.load/status/commit/cancel` e adicionar uma superficie pequena
|
|
para backlog:
|
|
|
|
1. `asset.backlog_info() -> (status, pending_count, active_handle, active_asset_id, active_bank_type, active_slot, active_progress)`
|
|
- Consulta o estado geral da lane de assets.
|
|
- `active_progress` usa escala inteira, preferencialmente `0..10000` para
|
|
permitir duas casas decimais sem float.
|
|
|
|
2. `asset.backlog_position(handle) -> (status, state, position, progress)`
|
|
- Consulta um pedido especifico.
|
|
- `position = 0` significa job ativo.
|
|
- `position > 0` significa posicao no backlog.
|
|
- `position = -1` pode representar nao enfileirado/pronto/cancelado,
|
|
dependendo do `state`.
|
|
|
|
3. `asset.backlog_move(handle, new_position) -> status`
|
|
- Move um pedido pendente para uma posicao absoluta.
|
|
- `new_position = 1` significa primeiro pendente depois do ativo.
|
|
- Nao interrompe diretamente o job ativo; substituicao do mesmo
|
|
`bank_type/slot` usa a regra de superseding.
|
|
|
|
4. `asset.backlog_promote(handle) -> status`
|
|
- Atalho para mover o pedido para a frente do backlog pendente.
|
|
|
|
5. `asset.backlog_demote(handle) -> status`
|
|
- Atalho para mover o pedido para o fim do backlog pendente.
|
|
|
|
6. `asset.target_status(bank_type, slot) -> (status, asset_id, handle, state, position, progress)`
|
|
- Consulta por alvo operacional, que e o que realmente controla superseding.
|
|
- Ajuda quando o caller quer saber "o que esta programado para este slot".
|
|
|
|
Estados sugeridos para `state`:
|
|
|
|
- `empty`;
|
|
- `invalid`;
|
|
- `queued`;
|
|
- `active`;
|
|
- `ready`;
|
|
- `committed`;
|
|
- `canceled`;
|
|
- `superseded`;
|
|
- `error`;
|
|
- `backend_unavailable`.
|
|
|
|
Regra de design: APIs de backlog sao operacionais e status-first. Reordenar um
|
|
handle inexistente, ja concluido ou ja superseded retorna status operacional
|
|
apropriado quando o handle e conhecido; violações estruturais continuam Trap.
|
|
|
|
Handles sao observaveis e representam slots de banks. Um handle conhecido pode
|
|
ser consultado mesmo quando o slot alvo nao contem asset valido carregado; nesse
|
|
caso a consulta deve retornar estado como `empty` ou `invalid`.
|
|
|
|
O estado do handle deve conter pelo menos duas partes:
|
|
|
|
```text
|
|
slot_state:
|
|
loaded_asset_id
|
|
resident_state
|
|
|
|
request_state:
|
|
requested_asset_id
|
|
generation
|
|
queued/active/ready/canceled/superseded/error
|
|
backlog_position
|
|
progress
|
|
```
|
|
|
|
Mutacoes seguem regras mais estritas e devem falhar operacionalmente quando a
|
|
secao de request/backlog do handle nao representa a geracao atual.
|
|
|
|
## Progresso e Percentis
|
|
|
|
### Progresso percentual
|
|
|
|
Sugestao:
|
|
|
|
- usar progresso em base inteira `0..10000`;
|
|
- quando o tamanho total de bytes for conhecido, calcular progresso por fases
|
|
ponderadas;
|
|
- quando o decode nao for linear ou nao houver tamanho confiavel, expor
|
|
progresso por fase com marcos conservadores.
|
|
|
|
Modelo inicial de fases:
|
|
|
|
```text
|
|
queued -> 0
|
|
read -> 0..4000
|
|
decode -> 4000..9000
|
|
stage -> 9000..10000
|
|
ready -> 10000
|
|
```
|
|
|
|
Se uma fase nao consegue reportar progresso interno, ela deve manter o ultimo
|
|
marco e saltar para o proximo marco ao concluir. Isso evita progresso falso
|
|
sem perder visibilidade de fase.
|
|
|
|
### Percentis por asset
|
|
|
|
Sugestao:
|
|
|
|
- registrar duracoes por asset no fim de cada job, nao por tick/frame;
|
|
- manter agregadores pequenos por `asset_id` e por `bank_type`;
|
|
- calcular percentis a partir de janela/ring buffer pequeno ou histograma
|
|
barato por bucket de duracao;
|
|
- nunca atualizar percentis no loop quente de decode por item/pixel;
|
|
- o job ativo pode expor tempo decorrido e fase atual; percentis sao atualizados
|
|
apenas no fechamento do job.
|
|
|
|
## Perguntas em Aberto
|
|
|
|
- [x] A agenda esta madura para virar decisao normativa ou ainda falta algum
|
|
caso de asset/memcard/lane?
|
|
- [x] A estrutura minima de `slot_state` e `request_state` no handle esta
|
|
completa ou falta algum campo para commit/cancel/reorder seguro?
|
|
|
|
## Resolucao
|
|
|
|
A agenda esta madura para decisao normativa.
|
|
|
|
A decisao deve formalizar:
|
|
|
|
- a terceira async work lane serial;
|
|
- um job ativo por vez;
|
|
- backlog efetivamente limitado pela unicidade de `bank_type/slot`;
|
|
- handles como observadores estaveis de slots de bank;
|
|
- `slot_state` e `request_state` dentro do handle;
|
|
- cancelamento/superseding por novo request para o mesmo alvo;
|
|
- load pronto imediato quando o asset ja esta residente no alvo;
|
|
- decode/materializacao na lane async;
|
|
- commit/install na lane principal;
|
|
- memcard como consumidor prioritario da mesma lane;
|
|
- FS como consumidor permitido, deixando API publica de FS para `AGD-0006`;
|
|
- progresso por fases e percentis atualizados no fechamento do job.
|
|
|
|
## Dependencias
|
|
|
|
- `docs/specs/runtime/09-events-and-concurrency.md`
|
|
- `docs/specs/runtime/15-asset-management.md`
|
|
- `docs/specs/runtime/16a-syscall-policies.md`
|
|
- `discussion/workflow/agendas/AGD-0006-app-home-filesystem-surface-and-semantics.md`
|
|
|
|
## Criterio para Encerrar
|
|
|
|
Pode virar PR quando houver decisao escrita sobre:
|
|
|
|
- existencia e papel da terceira async work lane;
|
|
- relacao dessa lane com a terceira core no hardware alvo e fallback no host;
|
|
- desenho do backlog serial de asset loading;
|
|
- regra de cancelamento/substituicao para requests no mesmo bank/slot;
|
|
- proibicao de `thread::spawn` por load no caminho normal;
|
|
- fases de asset load que rodam na lane vs lane principal;
|
|
- inclusao condicionada de FS/memcard nessa mesma lane;
|
|
- API de consulta e reordenacao do backlog de assets;
|
|
- comportamento de request imediato quando o asset ja esta residente no alvo;
|
|
- regra de bounded backlog por unicidade de `bank_type/slot`;
|
|
- politica de prioridade entre asset, FS e memcard;
|
|
- status e telemetria para backlog, progresso, percentis, cancelamento e falha.
|
|
|
|
## Discussao
|
|
|
|
- 2026-06-28: Agenda atualizada para remover render worker do escopo, assumir
|
|
uma terceira core/lane para trabalhos assincronos, exigir pool/fila limitada
|
|
para asset loading e reavaliar o papel de FS/memcard como consumidores da
|
|
mesma lane.
|
|
- 2026-06-28: Discussao consolidou que a async work lane deve ser serial, com
|
|
um job ativo, backlog semanticamente ilimitado, consulta/reordenacao publica
|
|
de backlog de assets, progresso percentual do asset ativo, decode na lane
|
|
async, install/commit na lane principal, e FS/memcard como consumidores a
|
|
alinhar com a agenda de app home filesystem.
|
|
- 2026-06-28: Acrescentada regra de asset pipe: requests para o mesmo bank/slot
|
|
devem cancelar pedidos anteriores pendentes para aquele alvo, tratando o
|
|
pedido mais novo como substituto operacional.
|
|
- 2026-06-28: Discussao refinou que o alvo canonico e `bank_type/slot`; um
|
|
asset ja residente deve retornar handle pronto sem entrar no backlog; o
|
|
backlog efetivo e limitado pela soma dos slots dos bancos; FS fica como
|
|
consumidor permitido da lane, enquanto API publica de FS permanece na agenda
|
|
6; progresso deve usar fases conservadoras e percentis devem ser atualizados
|
|
no fechamento do job, nao no hot path.
|
|
- 2026-06-28: Open questions restantes foram consolidadas: API de backlog
|
|
aceita com `promote/demote` como atalhos; superseding marca requests
|
|
substituidos por outro request para o mesmo `bank_type/slot`; cancelamento do
|
|
ativo e cooperativo quando barato e descarte por geracao quando nao for;
|
|
`read/decode/stage` cobre GLYPH/SOUND/SCENE; percentis ficam por `bank_type`
|
|
e por `asset_id`; API publica de FS permanece em `AGD-0006`.
|
|
- 2026-06-28: Adicionada a expectativa de que handles possam consultar o alvo
|
|
`bank_type/slot` a qualquer momento, inclusive quando nao houver asset valido
|
|
carregado; mutacoes devem continuar protegidas por request/geracao para evitar
|
|
commit/cancel acidental de pedidos substituidos.
|
|
- 2026-06-28: Refinado o modelo de handle: o handle pertence ao slot do bank e
|
|
contem uma secao de estado de request/backlog para aquele slot. Consulta e
|
|
residencia ficam estaveis por alvo; mutacoes atuam sobre a geracao atual do
|
|
request dentro do handle.
|