12.7. Povratni pozivi kanala¶
Pozadinski objekt predan funkciji protocol.register() je Python klasa. Protokolna biblioteka ne pita klasu koje metode implementira; ona pregledava instancu i povezuje one koje pronađe. Upravo to introspekcijsko pregledavanje čini sučelje pozadinskog objekta fleksibilnim: najmanji koristan pozadinski objekt ima dvije metode, najsloženiji ih ima dvanaest, a aplikacija se uključuje u svaku mogućnost jednu po jednu metodu.
12.7.1. Pravila introspekcije¶
Kada se protocol.register() izvrši, biblioteka prolazi kroz fiksni popis imena pozivnih funkcija i veže svaku koju pronađe na instanci pozadinskog objekta:
Dodavanje
readu klasu uključujeCHANNEL_FLAG_READ. Poziv s domaćina premachannel_read()dolazi do pozadinskog objekta samo ako je ova zastavica postavljena.Dodavanje
writeuključujeCHANNEL_FLAG_WRITE, čime se omogućujechannel_write().Dodavanje
lockiunlockuključujeCHANNEL_FLAG_LOCK, čime se domaćinu omogućuje zaključavanje kanala za atomarno čitanje višestrukih paketa.Dodavanje
pollomogućuje domaćinu da jeftino upita „je li nešto spremno?”, bez prisiljavanja na potpuno čitanje.
Nedostajuće metode nisu pogreške – protokolna biblioteka jednostavno ostavlja odgovarajuću mogućnost onemogućenom. Pozadinski objekt sa samo size i read posve je valjan; to je podatkovni kanal samo za čitanje.
12.7.2. Senzorski kanal samo za čitanje¶
Senzorski kanal koji objavljuje svježe očitanje svaki put kada domaćin upita, odbijajući zapise s domaćina, koristi četiri povratna poziva:
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))
Prolazak kroz ono što svaka metoda radi:
pollvraća zastavicu svježine. Domaćin je poziva prije čitanja i u potpunosti preskače čitanje kada ona vratiFalse. Time se uštedi trošak povratnog putovanja za „još nema novih podataka”.sizeregenerira međuspremnik na zahtjev i prijavljuje njegovu duljinu. Provođenje uzorkovanja ovdje znači da pozadinskom objektu nije potreban pozadinski zadatak – poziv s domaćina pokreće svako mjerenje.readvraća isječak međuspremnika. Protokolna biblioteka može ga pozvati više puta kada je međuspremnik veći od dogovorenog maksimalnog korisnog tereta; argumentoffsetprolazi kroz fragmente.Nepostojanje metode
writeznači da se zapisi s domaćina odbijaju na sloju uokvirivanja, prije nego što se pozadinski objekt uopće uključi.
12.7.3. Potpuni skup povratnih poziva¶
Za referencu, svaka metoda koju biblioteka traži na pozadinskom objektu:
Metoda |
Vraća |
Svrha |
|---|---|---|
|
objekt |
Neobavezna jednokratna inicijalizacija kada se kanal prvi put veže na domaćina. Vrati bilo koju vrijednost koja nije |
|
bool |
Vrati |
|
bool |
Preuzmi kanal za atomarni prijenos višestrukih paketa. |
|
bool |
Otpusti prethodni |
|
int |
Broj bajtova koje je trenutačno moguće pročitati s kanala. |
|
tuple |
Do četiri cijela broja koja opisuju strukturu podataka (npr. visina slike, širina, broj bajtova). Domaćin ih koristi za raspakiranje tipiziranih međuspremnika. |
|
bytes |
Vrati do size bajtova počevši od offset. Poziva se jednom po fragmentu kada korisni teret premaši dogovoreni maksimum. |
|
bytes |
Inačica metode |
|
int |
Domaćin je zapisao data na offset. |
|
int |
Aplikacijski definirani operacijski kod izvan modela čitanja/pisanja. Negativna povratna vrijednost je pogreška. |
|
objekt |
Odbaci sve podatke iz međuspremnika. Poziva se kada domaćin želi ponovno postaviti kanal. |
|
bool |
Smisleno samo na pozadinskim objektima koji predstavljaju fizički transport (ugrađeni USB kanali). Aplikacijskim kanalima ovo nije potrebno. |
To je cijelo sučelje pozadinskog objekta. Dvanaest imena metoda, sve neobavezne, a protokolna biblioteka odlučuje što svaki kanal može raditi na temelju toga koje su prisutne.