Topology
picopyn.topology
Client-side view of the Picodata cluster topology.
Based on the topology notifications RFC.
Picodata doesn't push topology changes yet as server-side events. So for now we get this data by periodically polling Picodata's system tables with the Topology Tracker instead.
Once Picodata starts pushing real events, we'll only need to change the source of topology (from Picodata's system tables to NOTIFY messages).
See details in Topology.
Note
Currently this is read-only. The connection pool never changes based on topology --
Pool.connect() decides the pool once, for good. Topology just lets callers look at
the current cluster state.
EventInstance
dataclass
An instance change: status changed, instance added, role changed, etc.
For replace, only set the fields that changed — leave the rest as None
and they won't overwrite what we already know. For delete, only
instance_uuid matters.
A few fields are missing here -- Picodata doesn't send this event yet, so there's nothing real to put in them.
Source code in picopyn/topology.py
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | |
EventReplicaset
dataclass
A replicaset change: replicaset added, master changed, etc.
A few fields are missing here -- Picodata doesn't send this event yet, so there's nothing real to put in them.
Source code in picopyn/topology.py
79 80 81 82 83 84 85 86 87 88 89 | |
Instance
dataclass
A Picodata instance, assembled from _pico_instance and
_pico_peer_address rows.
Source code in picopyn/topology.py
39 40 41 42 43 44 45 46 47 48 | |
Replicaset
dataclass
A Picodata replicaset, assembled from _pico_replicaset rows.
Source code in picopyn/topology.py
51 52 53 54 55 56 | |
Topology
Holds the current view of the cluster topology known to the client.
The Topology Tracker updates the topology on a schedule or when triggered:
---
title: Topology tracking
---
flowchart TD
classDef neutral fill:#f5f5f5,stroke:#9e9e9e,color:#424242
classDef note fill:#fffde7,stroke:#f9a825,stroke-dasharray:4,color:#555
TOPOLOGY[[Topology<br>·instances<br>·replicasets]]
CONNECT["Pool.connect()"] --> CFG[/"Topology tracker settings<br>· update interval"/] --> START["start topology tracker"] --> WAIT
subgraph RefreshLoop["Topology tracker loop"]
direction TB
WAIT{"timer elapsed<br>or triggered?"} --> REFRESH["refresh topology"]
end
REFRESH -.->|next iteration| WAIT
REFRESH -.-> TOPOLOGY
QUERY["Pool.execute / fetch / fetchrow"] --> ERR{"connection error?"}
ERR -->|yes| TRIGGER["call tracker trigger"]
ERR -->|no| RAISE(["do not trigger tracker"])
TRIGGER -.-> WAIT
READ["pool.topology"] -.-> TOPOLOGY
NOTE>"read-only — never<br>changes pool membership"]:::note
NOTE -.-> READ
Currently, the refresh polls Picodata's system tables:
---
title: Topology refresh
---
flowchart TD
classDef neutral fill:#f5f5f5,stroke:#9e9e9e,color:#424242
classDef note fill:#fffde7,stroke:#f9a825,stroke-dasharray:4,color:#555
TOPOLOGY[[Topology<br>instances + replicasets]]
SYS_TABLES[(Picodata system tables)]
FETCH["fetch Picodata system tables"] --> PARSE["parse db rows"]
FETCH <-. read .-> SYS_TABLES
PARSE --> DIFF["compare current topology<br>keys with rows"]
DIFF <-. read .-> TOPOLOGY
DIFF -.-> EVENTS[["- missing entries become delete events<br>- the rest become replace events<br>"]]
EVENTS -.-> APPLY["topology apply<br>instance/replicaset events"]
APPLY <-. write .-> TOPOLOGY
Source code in picopyn/topology.py
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | |
apply_instance(event)
Apply an instance event.
replace only updates the fields that were set — anything left as
None stays as it was. delete removes the instance completely.
Source code in picopyn/topology.py
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | |
apply_replicaset(event)
Apply a replicaset event.
replace only updates the fields that were set -- anything left as
None stays as it was. delete removes the replicaset completely.
Source code in picopyn/topology.py
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | |
clear()
Forget everything we know about the topology.
Do this before reading a fresh snapshot from a new connection -- the new connection may be talking to an instance that's behind or ahead of the one we had before.
Source code in picopyn/topology.py
156 157 158 159 160 161 162 163 164 165 166 | |
online_addresses()
Addresses of instances currently in the Online state.
Source code in picopyn/topology.py
211 212 213 214 215 216 217 | |