Backends¶
Overview¶
PACSys provides multiple backends that talk to various central services. The DPM backends connect to the DPM server, DMQ talks to DataBroker/Bunny OAC/DAE, etc.
flowchart TB
subgraph App[Your Application]
P[Python + pacsys]
end
subgraph CS[Central Services]
DPM[DPM]
ACL[ACL CGI]
DMQ[DataBroker<br>Bunny OAC/DAE]
DB[PostgreSQL]
CLX[CLX nodes]
end
FE[Frontends]
OT[Other tasks]
P -->|DPM/HTTP<br>TCP:6802<br>SDD| DPM
P -->|DPM/gRPC<br>gRPC:50051<br>Protobuf| DPM
P -->|HTTPS:443<br>CGI script| ACL
P -->|DMQ<br>TCP:5672<br>AMQP| DMQ
P -->|DevDB<br>gRPC:50051<br>Protobuf| DB
P -->|ACL-over-SSH<br>SSH:22| CLX
CS --> FE
CS --> OT
Backend Comparison¶
| Feature | DPM/HTTP | DPM/gRPC | DMQ | ACL |
|---|---|---|---|---|
| Read | ✓ | ✓ | ✓ | ✓ |
| Write | ✓ | ✓ | ✓ | - |
| Stream | ✓ | ✓ | ✓ | - |
| Auth | Kerberos² | JWT | Kerberos³ | None |
| Permissions | Role/class | Role | Console class | N/A |
| Protocol | TCP/SDD¹ | gRPC/Protobuf | AMQP/SDD¹ | HTTP/CGI |
| Port | 6802 | 50051 | 5672 | 443 |
| Factory | pacsys.dpm() |
pacsys.grpc() |
pacsys.dmq() |
pacsys.acl() |
¹ SDD = Self-Describing Data, the binary encoding used by protocol compiler in DMQ and DPM/HTTP ² DPM/HTTP: Kerberos required for writes only, reads work anonymously ³ DMQ: Kerberos required for ALL operations (reads, writes, streaming)
Implicit Write Conversion¶
All write-capable backends (DPM/HTTP, DPM/gRPC, DMQ) automatically adjust DRF strings when you call write():
- READING → SETTING:
M:OUTTMPbecomesM:OUTTMP.SETTING@N - STATUS → CONTROL:
M:OUTTMP.STATUSbecomesM:OUTTMP.CONTROL@N - Already correct: SETTING, CONTROL, ANALOG, DIGITAL are preserved (just
@Nis forced)
The @N ("never") event tells the server not to send periodic data back - writes are fire-and-confirm, not subscriptions.
Backend recommendations¶
| Scenario | Backend |
|---|---|
| Good-enough read/write | DPM/HTTP |
| High-performance with JWT token (ask ACORN when this will work) | DPM/gRPC |
| High-performance read-only (works now) | DPM/gRPC |
| Fallback if DPM has issues/bugs | DMQ |
| Last resort | ACL |
Multiple Backends¶
You can use different backends simultaneously:
import pacsys
from pacsys import KerberosAuth
# Quick read via ACL (no auth needed)
with pacsys.acl() as acl:
current = acl.read("M:OUTTMP")
# Write via DPM/HTTP with auth
with pacsys.dpm(auth=KerberosAuth(), role="testing") as dpm:
dpm.write("M:OUTTMP", current + 1.0)
# Or write via DMQ (no role needed, just Kerberos)
with pacsys.dmq(auth=KerberosAuth()) as dmq:
dmq.write("M:OUTTMP", current + 1.0)
# Stream via DPM/HTTP
with pacsys.dpm() as dpm:
with dpm.subscribe(["M:OUTTMP@p,1000"]) as stream:
for reading, _ in stream.readings(timeout=30):
print(reading.value)
# Or stream via DMQ
with pacsys.dmq(auth=KerberosAuth()) as dmq:
with dmq.subscribe(["M:OUTTMP@p,1000"]) as stream:
for reading, _ in stream.readings(timeout=30):
print(reading.value)