Use one freshness barrier for code blobs

894bdfb85f31 · AtlantisPleb · · parent 097cb33a22e8

Use one freshness barrier for code blobs

Deploy story

What this commit did to the running system — joined from the forge receipt chain, the part a commit page elsewhere cannot show.

pushed
by user · WAL seq 471 · 2026-08-27T06:17:15.988172Z
built
1 modules in 26.5 s
deployed
live · 1 module on 3 nodes · push→live 678.7 s

Changed files

  • modified lib/openagents/forge/browse.ex
  • modified test/openagents_web/live/code_live_test.exs
  • added test/support/forge_wal_probe.ex

Diff

3 files changed, +91 -24

lib/openagents/forge/browse.ex modified +32 -24

@@ -273,39 +273,47 @@ defmodule OpenAgents.Forge.Browse do

273 273
    end
274 274
  end
275 275
276
  @doc "Read the data for a file page after one cache-freshness check."
276
  @doc "Read file-page data from one locked projection after one freshness check."
277 277
  def blob_page(repo, ref, path) do
278 278
    with :ok <- check(repo, ref),
279 279
         :ok <- check_path(path) do
280
      _ = freshen(repo)
280
      Sync.with_repo_lock(storage_key(repo), fn ->
281
        _ = freshen(repo)
281 282
282
      with {:ok, sha} <- resolve_commit_from_cache(repo, ref),
283
           {:ok, blob} <- blob_from_cache(repo, sha, path) do
284
        head = with {:ok, current} <- head_from_cache(repo), do: current
285
        {:ok, %{sha: sha, head: head, blob: blob}}
286
      end
283
        with {:ok, sha} <- resolve_commit_from_cache(repo, ref) do
284
          head = with {:ok, current} <- head_from_cache(repo), do: current
285
286
          with {:ok, blob} <- blob_at_commit_from_cache(repo, sha, path) do
287
            {:ok, %{sha: sha, head: head, blob: blob}}
288
          end
289
        end
290
      end)
287 291
    end
288 292
  end
289 293
290 294
  defp blob_from_cache(repo, ref, path) do
291 295
    with {:ok, full} <- resolve_commit_from_cache(repo, ref) do
292
      spec = full <> ":" <> path
293
294
      with {size_out, 0} <- git(repo, ["cat-file", "-s", spec]),
295
           {size, _} <- Integer.parse(String.trim(size_out)),
296
           {output, 0} <- git(repo, ["cat-file", "blob", spec]) do
297
        content = truncate(output, @blob_cap)
298
299
        {:ok,
300
         %{
301
           content: content,
302
           truncated: size > @blob_cap,
303
           binary: binary_content?(content),
304
           size: size
305
         }}
306
      else
307
        _ -> {:error, :not_found}
308
      end
296
      blob_at_commit_from_cache(repo, full, path)
297
    end
298
  end
299
300
  defp blob_at_commit_from_cache(repo, commit, path) do
301
    spec = commit <> ":" <> path
302
303
    with {size_out, 0} <- git(repo, ["cat-file", "-s", spec]),
304
         {size, _} <- Integer.parse(String.trim(size_out)),
305
         {output, 0} <- git(repo, ["cat-file", "blob", spec]) do
306
      content = truncate(output, @blob_cap)
307
308
      {:ok,
309
       %{
310
         content: content,
311
         truncated: size > @blob_cap,
312
         binary: binary_content?(content),
313
         size: size
314
       }}
315
    else
316
      _ -> {:error, :not_found}
309 317
    end
310 318
  end
311 319
test/openagents_web/live/code_live_test.exs modified +22

@@ -11,6 +11,7 @@ defmodule OpenAgentsWeb.CodeLiveTest do

11 11
  import Phoenix.LiveViewTest
12 12
13 13
  alias OpenAgents.Forge.{DeployReceipt, Repos}
14
  alias OpenAgents.Forge.WAL.Probe
14 15
  alias OpenAgents.Repo
15 16
16 17
  @audit_heading "Transparency audit fixture"

@@ -585,6 +586,27 @@ defmodule OpenAgentsWeb.CodeLiveTest do

585 586
  end
586 587
587 588
  describe "/code/:repo/blob/:ref/*path" do
589
    test "performs one freshness barrier for a code blob request", %{conn: conn} do
590
      previous_adapter = Application.fetch_env!(:openagents, :forge_wal_adapter)
591
      previous_probe = Application.get_env(:openagents, :forge_wal_probe_pid)
592
      Application.put_env(:openagents, :forge_wal_adapter, Probe)
593
      Application.put_env(:openagents, :forge_wal_probe_pid, self())
594
595
      on_exit(fn ->
596
        Application.put_env(:openagents, :forge_wal_adapter, previous_adapter)
597
598
        if previous_probe,
599
          do: Application.put_env(:openagents, :forge_wal_probe_pid, previous_probe),
600
          else: Application.delete_env(:openagents, :forge_wal_probe_pid)
601
      end)
602
603
      conn = get(conn, "/OpenAgentsInc/openagents.com/blob/main/docs/audit.md")
604
      assert html_response(conn, 200)
605
606
      assert_receive {Probe, :read_index, "openagents.com"}
607
      refute_receive {Probe, :read_index, "openagents.com"}
608
    end
609
588 610
    test "renders markdown as HTML, not source", %{conn: conn} do
589 611
      {:ok, _view, html} = live(conn, "/OpenAgentsInc/openagents.com/blob/main/docs/audit.md")
590 612
test/support/forge_wal_probe.ex added +37

@@ -0,0 +1,37 @@

1
defmodule OpenAgents.Forge.WAL.Probe do
2
  @moduledoc false
3
4
  @behaviour OpenAgents.Forge.WAL
5
6
  alias OpenAgents.Forge.WAL.Local
7
8
  @impl true
9
  def read_index(repo) do
10
    if pid = Application.get_env(:openagents, :forge_wal_probe_pid) do
11
      send(pid, {__MODULE__, :read_index, repo})
12
    end
13
14
    Local.read_index(repo)
15
  end
16
17
  @impl true
18
  defdelegate cas_index(repo, expected, index), to: Local
19
20
  @impl true
21
  defdelegate put_entry(repo, seq, payload), to: Local
22
23
  @impl true
24
  defdelegate put_entry_file(repo, seq, path), to: Local
25
26
  @impl true
27
  defdelegate get_entry(repo, object_key), to: Local
28
29
  @impl true
30
  defdelegate get_entry_file(repo, object_key, path), to: Local
31
32
  @impl true
33
  defdelegate put_object(repo, object_key, payload), to: Local
34
35
  @impl true
36
  defdelegate delete_repo(repo), to: Local
37
end

This page updates live while a promote is in flight · changelog