12.7. Callbacks de canal¶
O objeto de backend passado para protocol.register() é uma classe Python. A biblioteca de protocolo não pergunta à classe quais métodos ela implementa; ela inspeciona a instância e conecta os que encontrar. Essa introspecção é o que torna a interface de backend flexível: o menor backend útil tem dois métodos, o mais elaborado tem doze, e a aplicação adere a cada capacidade um método por vez.
12.7.1. As regras de introspecção¶
Quando protocol.register() é executado, a biblioteca percorre uma lista fixa de nomes invocáveis e vincula cada um que encontra na instância de backend:
Adicionar
readà classe ativaCHANNEL_FLAG_READ. Uma chamada do host achannel_read()só chega ao backend se esse flag estiver definido.Adicionar
writeativaCHANNEL_FLAG_WRITE, habilitandochannel_write().Adicionar
lockeunlockativaCHANNEL_FLAG_LOCK, permitindo que o host bloqueie o canal para uma leitura atômica de múltiplos pacotes.Adicionar
pollpermite que o host pergunte “há algo pronto?” de forma barata, sem forçar uma leitura completa.
Métodos ausentes não são erros – a biblioteca de protocolo simplesmente deixa a capacidade correspondente desabilitada. Um backend com apenas size e read é perfeitamente válido; trata-se de um canal de dados somente leitura.
12.7.2. Um canal de sensor somente leitura¶
Um canal de sensor que publica uma nova leitura toda vez que o host solicita, recusando escritas do host, exercita quatro dos callbacks:
import protocol
import struct
class TempChannel:
def __init__(self, read_sensor):
self._read_sensor = read_sensor
self._buf = b''
self._fresh = False
def poll(self):
# Tell the host whether a reading is waiting.
return self._fresh
def size(self):
# Sample fresh data on every host-side size query.
value = self._read_sensor()
self._buf = struct.pack('<f', value)
self._fresh = True
return len(self._buf)
def read(self, offset, size):
end = offset + size
if end >= len(self._buf):
self._fresh = False
return self._buf[offset:end]
protocol.register(name='temp', backend=TempChannel(read_temperature))
Percorrendo o que cada método faz:
pollretorna o flag de atualização. O host o chama antes de ler e pula a leitura completamente quando ele retornaFalse. Isso economiza o custo da ida e volta para “ainda não há dados novos”.sizeregenera o buffer sob demanda e relata seu tamanho. Fazer a amostragem aqui significa que o backend não precisa de uma tarefa em segundo plano – uma chamada do host conduz cada medição.readretorna uma fatia do buffer. A biblioteca de protocolo pode chamá-lo mais de uma vez quando o buffer é maior que o payload máximo negociado; o argumentooffsetpercorre os fragmentos.A ausência de
writesignifica que escritas do host são recusadas na camada de framing, antes de o backend ser envolvido.
12.7.3. O conjunto completo de callbacks¶
Para referência, todos os métodos que a biblioteca procura em um backend:
Método |
Retorna |
Finalidade |
|---|---|---|
|
object |
Inicialização opcional de uma única vez quando o canal se vincula pela primeira vez a um host. Retorne qualquer valor não |
|
bool |
Retorna |
|
bool |
Adquire o canal para uma transferência atômica de múltiplos pacotes. |
|
bool |
Libera um |
|
int |
Número de bytes atualmente legíveis do canal. |
|
tuple |
Até quatro inteiros descrevendo a estrutura de dados (por exemplo, altura, largura e contagem de bytes da imagem). Usado pelo host para desempacotar buffers tipados. |
|
bytes |
Retorna até size bytes começando em offset. Chamado uma vez por fragmento quando o payload excede o máximo negociado. |
|
bytes |
Variante sem cópia de |
|
int |
O host escreveu data em offset. |
|
int |
Opcode definido pela aplicação, fora do modelo de leitura/escrita. Retorno negativo é um erro. |
|
object |
Descarta quaisquer dados em buffer. Chamado quando o host quer reiniciar o canal. |
|
bool |
Significativo apenas em backends que representam um transporte físico (os canais USB integrados). Canais de aplicação não precisam disso. |
Essa é toda a interface de backend. Doze nomes de métodos, todos opcionais, e a biblioteca de protocolo decide o que cada canal pode fazer com base em quais deles estão presentes.