Padrões de concorrência
Produtor-consumidor, pool de trabalhadores, espalhar e juntar — montados com as peças da biblioteca.
Pool de trabalhadores#
N trabalhadores tirando tarefas de um canal: o número de trabalhadores limita quantas rodam ao mesmo tempo — o que protege o serviço externo que eles chamam.
dataforge
adopt Arcane.Concurrent as P
fila := P.canal()
resultados := P.ator(lambda acc, r: acc + [r], [])
action trabalhador():
persist yes:
t := fila.receber()
given t is void:
halt
resultados.enviar(t * t)
action alimentar():
cycle i from 1 to 6:
fila.enviar(i)
fila.fechar()
parallel:
alimentar()
trabalhador()
trabalhador()
trabalhador()
assert sorted(resultados.parar()) is [1, 4, 9, 16, 25, 36]Espalhar e juntar#
Muitas chamadas independentes ao mesmo tempo, e o resultado de todas na ordem da entrada — P.map faz os dois, com um teto de trabalhadores:
dataforge
adopt Arcane.Concurrent as P
action buscar_preco(item):
sleep(10) // a rede
yield len(item) * 10
precos := P.map(buscar_preco, ["café", "chá", "açúcar"], 3)
assert precos is [40, 30, 60] // na ordem da entrada, não da chegada| Padrão | Peças |
|---|---|
| produtor-consumidor | P.canal(n) — a capacidade é a contrapressão |
| pool de trabalhadores | canal + N threads + um ator para os resultados |
| espalhar e juntar | P.map(acao, itens, trabalhadores) |
| estado disputado | P.ator |
| várias escritas que andam juntas | Arcane.Stm |