forked from ClickHouse/walshadow
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathoracle.dot
More file actions
109 lines (96 loc) · 8.2 KB
/
Copy pathoracle.dot
File metadata and controls
109 lines (96 loc) · 8.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// walshadow, PgPending decode oracle
// PgPending resolver path over a unix socket into shadow PG's preloaded
// worker. Per-item and transport fallback stay visible.
//
// regeneration spec:
// sources of truth: plans/oracle.md · pgext/ · src/ oracle-path module (grep src/ for oracle|pending)
// subsumes: plans/oracle.md § resolver flow + worker surface + failure semantics
// quality bar:
// - required bridge path stays legible
// - batched socket round-trip reads as one canonical orange edge
// - fallback path visually distinct from main path
// shared style: palette.md
digraph oracle {
rankdir=TB;
compound=true;
graph [fontname="Helvetica", labelloc="t", label="walshadow oracle, PgPending decode bridge", fontsize=14, splines=spline, nodesep=0.35, ranksep=0.9, bgcolor="#272623", fontcolor="#ECE1D7"];
node [fontname="Helvetica", fontsize=10, shape=box, style="rounded,filled", color="#6E6963", fontcolor="#ECE1D7"];
edge [fontname="Helvetica", fontsize=9, color="#c1a78e", fontcolor="#ECE1D7"];
// ════════ ① decoder hand-off ════════
subgraph cluster_decoder {
label="① decoder — ColumnValue (heap_decoder.rs)"; style="rounded,filled"; color="#4c4641"; fillcolor="#34302c"; fontcolor="#ECE1D7";
tier12 [label="ColumnValue::Tier 1/2\nfixed-width / varlena\nlocally rendered\n(no raw bytes kept)", fillcolor="#4D4128"];
tier3 [label="ColumnValue::Tier 3\nnumeric / inet / cidr /\ninterval (codecs.rs)\nlocal decode only\n(raw bytes discarded)", fillcolor="#4D4128"];
pend [label="ColumnValue::PgPending\n{ type_oid, raw }\njsonb / array / range /\ntsvector / domain / vendor", fillcolor="#5D3F40"];
unsup [label="ColumnValue::Unsupported\n{ type_oid, raw }\nfail-closed backstop\nunless oracle resolves", fillcolor="#5D3F40"];
}
// ════════ ② oracle decode path ════════
subgraph cluster_oracle {
label="② oracle path, post-plan; metrics-only runs skip it"; style="rounded,filled"; color="#4c4641"; fillcolor="#34302c"; fontcolor="#ECE1D7";
resolve [label="resolve_pending_tuple\ncollect PgPending | Unsupported\none DECODE batch per tuple\nswap each text answer to Text\nbest effort: shadow may lag\nrow's catalog interval", fillcolor="#5D3F40"];
stats [label="OracleStats\nresolved / fallback_raw / errors\n\nBridgeStats\nup / requests / errors /\nlatency / reconnects / items", fillcolor="#5D3F40", shape=note];
}
// ════════ ③ bridge client ════════
client [label="Bridge\ntokio::net::UnixStream\nHELLO version gate\nframed DECODE request\nreconnect + retry on\ntransport failure", fillcolor="#4D4D28"];
// ════════ ④ shadow PG + preloaded worker ════════
subgraph cluster_shadow {
label="④ shadow PG"; style="rounded,filled"; color="#4c4641"; fillcolor="#34302c"; fontcolor="#ECE1D7";
worker [label="walshadow background worker\n(pgext/worker.c)\nunix socket, mode 0600\none transaction per request\none subtransaction per item\nerror frame or connection close", fillcolor="#3D4128"];
decode [label="ws_decode_datum_text\n(pgext/decode.c)\nSearchSysCache1(TYPEOID)\nDatum reconstruct ×4 branches:\n typlen=−1 varlena\n typlen=−2 cstring\n typbyval fixed (memcpy)\n fixed by-ref (palloc)\nOidOutputFunctionCall(typoutput)", fillcolor="#3D4128"];
env [label="pinned output environment\nTimeZone = UTC\nDateStyle = ISO, MDY\nIntervalStyle = postgres\nextra_float_digits = 1\nbytea_output = hex", fillcolor="#3D4128", shape=note];
}
// ════════ ⑤ pgext build artifact ════════
subgraph cluster_pgext {
label="⑤ pgext/ (PGXS build)"; style="rounded,filled"; color="#4c4641"; fillcolor="#34302c"; fontcolor="#ECE1D7";
artifact [label="walshadow.so\ndecode.o + overlay.o + worker.o\nno control file\nno SQL script\nno pg_proc row", fillcolor="#4D3850", shape=note];
}
// ════════ ⑥ emit sinks (downstream branch off oracle) ════════
subgraph cluster_emit {
label="⑥ downstream — emit-time disposition"; style="rounded,filled"; color="#4c4641"; fillcolor="#34302c"; fontcolor="#ECE1D7";
emit_text [label="ColumnValue::Text\n→ CH String\n(encode_value)", fillcolor="#5D4628"];
emit_raw [label="PgPending raw bytes\n→ append_string_bytes(raw)\nbest-effort verbatim body", fillcolor="#5D4628"];
emit_fail [label="Unsupported unresolved\n→ EmitterError::\nUnsupportedValue (fatal)", fillcolor="#5D4628", shape=note];
}
// ─── main flow edges (LR spine, high weight) ───
pend -> resolve [color="#A1A9CC", penwidth=2, label="required bridge", weight=10];
unsup -> resolve [color="#A1A9CC", style=dashed, label="required bridge", weight=5];
resolve -> client [color="#CBA85E", penwidth=2, label="one DECODE batch\nper tuple", weight=10];
client -> worker [color="#CBA85E", penwidth=2, dir=both, arrowtail=open, lhead=cluster_shadow, label="framed unix\nsocket request", weight=10];
// ─── local tiers never reach the oracle ───
tier12 -> emit_text [color="#BF8C5F", style=dotted, constraint=false, label="local render"];
tier3 -> emit_text [color="#BF8C5F", style=dotted, constraint=false, label="local render"];
// ─── shadow internal: worker calls decode under pinned output GUCs ───
worker -> decode [color="#6E6963", label="each item"];
decode -> env [style=dashed, color="#6E6963", constraint=false];
// ─── pgext preload edge ───
artifact -> worker [style=dashed, color="#6E6963", lhead=cluster_shadow, ltail=cluster_pgext, label="$libdir or build tree\nshared_preload_libraries\n+ walshadow.* GUCs"];
// ─── stats fan-in (off-axis, constraint=false) ───
resolve -> stats [style=dashed, color="#CBA85E", constraint=false, label="resolved++ /\nfallback_raw++ /\nerrors++"];
client -> stats [style=dashed, color="#CBA85E", constraint=false, label="request /\ntransport counters"];
// ─── emit disposition (off-axis fan-out from oracle) ───
resolve -> emit_text [color="#BF8C5F", penwidth=2, constraint=false, label="text item\n→ Text"];
resolve -> emit_raw [color="#BF8C5F", style=dashed, constraint=false, label="item or transport error\n(PgPending)"];
resolve -> emit_fail [color="#BF8C5F", style=dotted, constraint=false, label="item or transport error\n(Unsupported)"];
// ─── Legend ───
legend [shape=plaintext, label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">
<TR><TD COLSPAN="2" BGCOLOR="#34302c"><B>node fill</B></TD></TR>
<TR><TD BGCOLOR="#4D4128" WIDTH="20"></TD><TD>decoder ColumnValue</TD></TR>
<TR><TD BGCOLOR="#5D3F40"></TD><TD>oracle (src/ops/oracle.rs)</TD></TR>
<TR><TD BGCOLOR="#4D4D28"></TD><TD>bridge client</TD></TR>
<TR><TD BGCOLOR="#3D4128"></TD><TD>shadow PG worker</TD></TR>
<TR><TD BGCOLOR="#4D3850"></TD><TD>pgext/ build artifact</TD></TR>
<TR><TD BGCOLOR="#5D4628"></TD><TD>emit sink</TD></TR>
<TR><TD COLSPAN="2" BGCOLOR="#34302c"><B>edge colour</B></TD></TR>
<TR><TD><FONT COLOR="#A1A9CC"><B>━━</B></FONT></TD><TD>pending → resolver</TD></TR>
<TR><TD><FONT COLOR="#CBA85E"><B>━━</B></FONT></TD><TD>unix socket (MAIN wire)</TD></TR>
<TR><TD><FONT COLOR="#BF8C5F"><B>━━</B></FONT></TD><TD>emit-time disposition</TD></TR>
<TR><TD><FONT COLOR="#6E6963"><B>┄┄</B></FONT></TD><TD>pgext preload (filesystem)</TD></TR>
<TR><TD COLSPAN="2" BGCOLOR="#34302c"><B>policy</B></TD></TR>
<TR><TD COLSPAN="2" ALIGN="LEFT">Best effort: resolution runs post-plan;<BR ALIGN="LEFT"/>shadow's catalog may lag the row's<BR ALIGN="LEFT"/>interval in DDL edge cases — accepted<BR ALIGN="LEFT"/>to mostly support unknown types.</TD></TR>
<TR><TD COLSPAN="2" BGCOLOR="#34302c"><B>bridge absence</B></TD></TR>
<TR><TD COLSPAN="2" ALIGN="LEFT">Unset socket or boot connect failure<BR ALIGN="LEFT"/>means no Oracle. PgPending reaches<BR ALIGN="LEFT"/>emitter unchanged and writes raw<BR ALIGN="LEFT"/>bytes. Unsupported remains fatal.<BR ALIGN="LEFT"/>Runtime transport failure retries<BR ALIGN="LEFT"/>once, then uses same disposition.</TD></TR>
</TABLE>
>];
worker -> legend [style=invis];
}