feat(workflow): freeze a pinned version as the public copy - #7853
feat(workflow): freeze a pinned version as the public copy#7853yangzhang75 wants to merge 1 commit into
Conversation
Automated Reviewer SuggestionsBased on the
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #7853 +/- ##
============================================
- Coverage 94.03% 94.02% -0.01%
- Complexity 4771 4780 +9
============================================
Files 1196 1197 +1
Lines 48757 48827 +70
Branches 5916 5934 +18
============================================
+ Hits 45850 45912 +62
Misses 1458 1458
- Partials 1449 1457 +8
*This pull request uses carry forward flags. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
| config | throughput | MB/s | latency | max Δ latest / 7d | |
|---|---|---|---|---|---|
| 🔴 | bs=10 sw=10 sl=64 | 455 | 0.278 | 20,549/31,428/31,428 us | 🔴 +17.0% / 🔴 +96.7% |
| 🔴 | bs=100 sw=10 sl=64 | 947 | 0.578 | 103,408/137,471/137,471 us | 🔴 +12.5% / 🔴 +25.8% |
| ⚪ | bs=1000 sw=10 sl=64 | 1,146 | 0.699 | 873,581/924,823/924,823 us | ⚪ within ±5% / 🟢 +13.9% |
Baseline details
Latest main 1cbe857 from same runner
| config | metric | PR | latest main | 7d avg | Δ latest | Δ 7d |
|---|---|---|---|---|---|---|
| bs=10 sw=10 sl=64 | throughput | 455 tuples/sec | 503 tuples/sec | 755.36 tuples/sec | -9.5% | -39.8% |
| bs=10 sw=10 sl=64 | MB/s | 0.278 MB/s | 0.307 MB/s | 0.461 MB/s | -9.4% | -39.7% |
| bs=10 sw=10 sl=64 | p50 | 20,549 us | 17,563 us | 12,938 us | +17.0% | +58.8% |
| bs=10 sw=10 sl=64 | p95 | 31,428 us | 32,035 us | 15,980 us | -1.9% | +96.7% |
| bs=10 sw=10 sl=64 | p99 | 31,428 us | 32,035 us | 19,233 us | -1.9% | +63.4% |
| bs=100 sw=10 sl=64 | throughput | 947 tuples/sec | 1,031 tuples/sec | 976.3 tuples/sec | -8.1% | -3.0% |
| bs=100 sw=10 sl=64 | MB/s | 0.578 MB/s | 0.629 MB/s | 0.596 MB/s | -8.1% | -3.0% |
| bs=100 sw=10 sl=64 | p50 | 103,408 us | 94,541 us | 102,340 us | +9.4% | +1.0% |
| bs=100 sw=10 sl=64 | p95 | 137,471 us | 122,234 us | 109,262 us | +12.5% | +25.8% |
| bs=100 sw=10 sl=64 | p99 | 137,471 us | 122,234 us | 118,827 us | +12.5% | +15.7% |
| bs=1000 sw=10 sl=64 | throughput | 1,146 tuples/sec | 1,156 tuples/sec | 1,006 tuples/sec | -0.9% | +13.9% |
| bs=1000 sw=10 sl=64 | MB/s | 0.699 MB/s | 0.706 MB/s | 0.614 MB/s | -1.0% | +13.8% |
| bs=1000 sw=10 sl=64 | p50 | 873,581 us | 860,324 us | 999,855 us | +1.5% | -12.6% |
| bs=1000 sw=10 sl=64 | p95 | 924,823 us | 952,383 us | 1,042,833 us | -2.9% | -11.3% |
| bs=1000 sw=10 sl=64 | p99 | 924,823 us | 952,383 us | 1,070,722 us | -2.9% | -13.6% |
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,439.28,200,128000,455,0.278,20549.22,31428.44,31428.44
1,100,10,64,20,2111.67,2000,1280000,947,0.578,103408.43,137470.74,137470.74
2,1000,10,64,20,17457.05,20000,12800000,1146,0.699,873581.49,924822.85,924822.85a3c9eee to
a70c881
Compare
A public workflow follows the author's latest content, as publishing has
always done. This adds the other state: the author pins the version they
have now, and the public copy stops moving until they pin again.
`is_public` stays the on/off switch; `published_content` is the pin, NULL
while following. `WorkflowPublishService` owns the two states, and three
endpoints expose them: POST and DELETE `/workflow/pin/{wid}` to pin and
unpin, GET `/workflow/publish-status/{wid}` for what the author is shown.
Publishing and unpublishing move through the same service, so unpublishing
drops the pin rather than leaving a private workflow carrying one.
Two paths are narrowed so a pin can hold. A save wrote the whole row back,
so a publish landing while a save was in flight was silently rolled back,
and a request body could set the publish columns itself; saves now write
only name, description and content. Creating a workflow clears the publish
columns for the same reason.
Nothing reads the pinned copy yet: every workflow is in the following
state it is in today, and nothing on screen changes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
a70c881 to
3f61548
Compare
What changes were proposed in this PR?
A public workflow follows the author's latest content, as publishing has always done: every
save reaches the Hub immediately. This adds the other state — the author pins the version
they have now, and what the public sees stops moving until they pin again.
WorkflowPublishServiceowns the two states and the moves between them:publish,pinLatest,unpin,unpublish,statusOf.is_publicstays the on/off switch;published_contentis the pin, NULL while following.view the workflow opens in — because a copy that froze only its graph would still advertise
a title nobody published. The default view matters because a form's definition rides inside
the content: serving the author's live preference over a frozen graph would open a form on a
copy that has none.
POST /workflow/pin/{wid}DELETE /workflow/pin/{wid}GET /workflow/publish-status/{wid}Publishing and unpublishing move through the same service, so unpublishing drops the pin
rather than leaving a private workflow carrying one. Re-publishing starts in the following
state: coming back should not silently put old public content on show again.
One writer for the publish columns. Three paths could write them by accident, because
each read a whole row (or took a whole
Workflowfrom the client) and wrote it all back:is_publicwould take a pinned workflow private underneath itsown frozen copy, which the CHECK constraint refuses outright — leaving an editor that can
no longer save. It now writes only name, description and content.
earlier, so anything landing in between was silently rewritten to what that read had seen:
a publish undone, a pin dropped, or — worst — a workflow the author had just unpublished
put back on public show under its frozen copy. Each now writes only its own column.
published copy of its own choosing.
Together with
/set-default-view, which already wrote only its column, every endpoint nowwrites what it owns and nothing else: outside creation,
WorkflowPublishServiceis the onlywriter of
is_publicand the frozen copy.Nothing on screen changes. No read path consults the pinned copy yet and there is no UI:
every workflow stays in the following state it is in today. The endpoints answer, and nothing
calls them.
Any related issues, documentation, discussions?
Closes #7938
Part of #7828. Design discussion: #7128. Schema: #7851.
How was this PR tested?
25 cases in
WorkflowPublishSpec:re-publish does not resurrect the previous pin;
and that each of them moving afterwards is reported as an unpublished change;
rename all leave the publish state alone;
drive the interleaving off the statement itself rather than off a thread, so the ordering is
the same on every run.
hasUnpublishedChangescompares the two copies as parsed JSON rather than as strings — thesame graph can come back with its keys in another order, and reporting that as an edit is an
alarm the author cannot clear. One case covers it.
The narrowed write paths were checked by mutation: restoring
is_publicto the save statementturns three cases red, one of them on the CHECK constraint itself, and restoring the
read-modify-write to the rename path turns the two interleaving cases red — one showing the
publish reverted, the other showing the unpublished workflow back on public show.
Was this PR authored or co-authored using generative AI tooling?
Generated-by: Claude Code (claude-opus-5)