Uma variável por thread
Inicialização declarada por thread e finalizador quando ela acaba — o que o armazém sozinho não dá.
Um armazém por thread resolve metade do problema. A outra metade é o que costuma faltar: a inicialização declarada num lugar só, e o finalizador quando a thread acaba.
Sem finalizador, uma conexão aberta por thread fica aberta depois que ela morre — e o sintoma aparece no servidor, não no código.
adopt Arcane.Inicio as I
// a inicializacao roda UMA VEZ POR THREAD, e cada uma ve a sua
contador := I.local(lambda => {"n": 0})
caixa := I.meu(contador)
caixa["n"] := caixa["n"] + 1
assert I.meu(contador)["n"] is 1
assert I.threads_com_valor(contador) bigger_eq 1| Símbolo | O que faz |
|---|---|
I.local(inicial, ao_terminar?) | cria a variável; inicial é uma ação que constrói o valor |
I.meu(local) | o valor desta thread, criando-o na primeira vez |
I.definir(local, v) | troca o valor desta thread |
I.limpar(local) | esquece; o próximo meu nasce de novo |
I.threads_com_valor(local) | quantas threads têm valor guardado |
Três decisões#
`inicial` é uma ação, e não um valor. Um valor seria compartilhado por todas as threads — que é exatamente o que a variável por thread existe para evitar. Passar um valor é recusado, com esse motivo na mensagem.
A inicialização roda fora da trava. Ela é código de quem chamou, pode demorar, e segurar a trava ali faria uma thread lenta parar todas as outras.