12.7. Csatorna-visszahívások¶
A protocol.register() függvénynek átadott backend objektum egy Python osztály. A protokollkönyvtár nem kérdezi meg az osztálytól, hogy mely metódusokat valósítja meg; megvizsgálja a példányt, és bedrótozza azokat, amelyeket megtalál. Ez az introspekció teszi rugalmassá a backend felületet: a legkisebb hasznos backend két metódusból áll, a legkidolgozottabb tizenkettőből, és az alkalmazás metódusonként, egyesével iratkozik fel az egyes képességekre.
12.7.1. Az introspekciós szabályok¶
Amikor a protocol.register() lefut, a könyvtár végigjárja a hívható nevek rögzített listáját, és mindegyiket hozzákapcsolja, amelyet megtalál a backend példányon:
A
readhozzáadása az osztályhoz bekapcsolja aCHANNEL_FLAG_READjelzőt. Achannel_read()gazdagéphívás csak akkor jut el a backendhez, ha ez a jelző be van állítva.A
writehozzáadása bekapcsolja aCHANNEL_FLAG_WRITEjelzőt, lehetővé téve achannel_write()használatát.A
lockésunlockhozzáadása bekapcsolja aCHANNEL_FLAG_LOCKjelzőt, lehetővé téve a gazdagép számára, hogy zárolja a csatornát egy több csomagból álló atomi olvasáshoz.A
pollhozzáadása lehetővé teszi a gazdagép számára, hogy olcsón megkérdezze: „van valami készen?”, anélkül hogy teljes olvasásra kényszerülne.
A hiányzó metódusok nem hibák – a protokollkönyvtár egyszerűen letiltva hagyja a megfelelő képességet. Egy olyan backend, amelynek csak size és read metódusa van, teljesen érvényes; ez egy csak olvasható adatcsatorna.
12.7.2. Egy csak olvasható érzékelőcsatorna¶
Egy olyan érzékelőcsatorna, amely minden gazdagéphívásra friss mérést tesz közzé, és elutasítja a gazdagép írásait, négyet használ a visszahívások közül:
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))
Végigvezetve azon, hogy mit csinál az egyes metódusok:
A
pollvisszaadja a frissesség jelzőt. A gazdagép olvasás előtt hívja meg, és teljesen kihagyja az olvasást, amikorFalseértéket ad vissza. Ez megspórolja az oda-vissza út költségét a „még nincs új adat” esetében.A
sizeigény szerint újragenerálja a puffert, és jelenti annak hosszát. A mintavételezés itteni elvégzése azt jelenti, hogy a backendnek nincs szüksége háttérfeladatra – minden mérést egy gazdagéphívás vezérel.A
reada puffer egy szeletét adja vissza. A protokollkönyvtár többször is meghívhatja, ha a puffer nagyobb a tárgyalt maximális hasznos terhelésnél; azoffsetargumentum végigjárja a töredékeket.A
writehiánya azt jelenti, hogy a gazdagép írásai a keretezési rétegben elutasításra kerülnek, még mielőtt a backend bevonódna.
12.7.3. A teljes visszahívás-készlet¶
Referenciaként minden metódus, amelyet a könyvtár keres egy backenden:
Metódus |
Visszaadott érték |
Cél |
|---|---|---|
|
object |
Opcionális egyszeri inicializálás, amikor a csatorna először kapcsolódik egy gazdagéphez. Sikeres esetén adjon vissza bármilyen nem |
|
bool |
Adjon vissza |
|
bool |
Lefoglalja a csatornát egy atomi, több csomagból álló átvitelhez. |
|
bool |
Felold egy korábbi |
|
int |
A csatornából jelenleg olvasható bájtok száma. |
|
tuple |
Legfeljebb négy egész szám, amely leírja az adatstruktúrát (pl. képmagasság, szélesség, bájtszám). A gazdagép használja a típusos pufferek kibontásához. |
|
bytes |
Legfeljebb size bájtot ad vissza offset pozíciótól kezdve. Töredékenként egyszer hívódik meg, ha a hasznos terhelés meghaladja a tárgyalt maximumot. |
|
bytes |
A |
|
int |
A gazdagép data adatot írt offset pozícióra. A |
|
int |
Az olvasás/írás modellen kívüli, alkalmazás által definiált opkód. A negatív visszatérési érték hibát jelez. |
|
object |
Eldobja a pufferelt adatokat. Akkor hívódik meg, amikor a gazdagép vissza akarja állítani a csatornát. |
|
bool |
Csak olyan backendeken értelmes, amelyek fizikai átvitelt képviselnek (a beépített USB-csatornák). Az alkalmazáscsatornáknak nincs erre szükségük. |
Ez a teljes backend felület. Tizenkét metódusnév, mind opcionális, és a protokollkönyvtár az alapján dönti el, hogy az egyes csatornák mit tehetnek, hogy melyek vannak jelen.