Skip to content

Commit

Permalink
Cache command output locally
Browse files Browse the repository at this point in the history
We currently only persist command output per-line, which works except that a lot of commands have very long pauses per-line.  Use in-memory caching to save overusing the database for this, and have a fallback when the cache misses to what's currently persisted to approximate a continuous db-write.
  • Loading branch information
michaeljguarino committed Jan 7, 2023
1 parent 1aff045 commit 4ab7cb2
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 8 deletions.
3 changes: 2 additions & 1 deletion lib/console/commands/command.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ defmodule Console.Commands.Command do
end

defp complete(%Command{} = command, exit_code) do
with {:ok, command} <- Builds.complete(command, exit_code) do
with {:ok, command} <- Builds.complete(command, exit_code),
:ok <- Builds.clear_cache(command) do
case exit_code do
0 -> {:ok, command}
_ -> {:error, command}
Expand Down
5 changes: 4 additions & 1 deletion lib/console/graphql/schema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ defmodule Console.GraphQl.Schema do
field :id, non_null(:id)
field :command, non_null(:string)
field :exit_code, :integer
field :stdout, :string
field :stdout, :string, resolve: fn
%{completed_at: nil} = cmd, _, _ -> Core.Services.Builds.get_line(cmd)
%{stdout: stdo}, _, _ -> stdo
end
field :completed_at, :datetime
field :build, :build, resolve: dataloader(Build)

Expand Down
5 changes: 3 additions & 2 deletions lib/console/schema/command.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ defmodule Console.Schema.Command do
do: from(c in query, order_by: ^order)

defimpl Collectable, for: __MODULE__ do
alias Console.Services.Base
alias Console.Services.{Base, Builds}

def into(command) do
{command, fn
Expand All @@ -39,7 +39,8 @@ defmodule Console.Schema.Command do

defp maybe_persist(%{stdout: stdo} = cmd, line) do
stdo = safe_concat(stdo, line)
with true <- String.contains?(line, "\n"),
with _ <- Builds.cache_line(cmd, stdo),
true <- String.contains?(line, "\n"),
{:ok, command} <- Ecto.Changeset.change(cmd, %{stdout: stdo})
|> Console.Repo.update() do
command
Expand Down
9 changes: 9 additions & 0 deletions lib/console/services/builds.ex
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,15 @@ defmodule Console.Services.Builds do
|> notify(:complete)
end

def cache_line(%Command{id: id}, stdo), do: Console.Cache.put({:command, id}, stdo, ttl: 360_000)

def get_line(%Command{id: id, stdout: stdo}) do
with nil <- Console.Cache.get({:command, id}),
do: stdo
end

def clear_cache(%Command{id: id}), do: Console.Cache.delete({:command, id})

def poll(id) do
start_transaction()
|> add_operation(:lock, fn _ -> lock("deployer", id) end)
Expand Down
11 changes: 11 additions & 0 deletions test/console/commands/command_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,15 @@ defmodule Console.Commands.CommandTest do
assert command.completed_at
end
end

describe "Collectible" do
test "commands implement the collectible protocol and caches the contents" do
command = insert(:command)
command = Enum.into(["one", "two", "three", "four\n"], command)

assert command.stdout == "onetwothreefour\n"
assert refetch(command).stdout == "onetwothreefour\n"
assert Console.Services.Builds.get_line(%{command | stdout: nil}) == "onetwothreefour\n"
end
end
end
5 changes: 1 addition & 4 deletions test/console/commands/tee_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ defmodule Console.Commands.TeeTest do

describe "Collectible" do
test "tee implements the collectible protocol for strings" do
res =
~w(one two three)
|> Enum.into(Tee.new())

res = Enum.into(~w(one two three), Tee.new())
assert Tee.output(res) == "onetwothree"
end

Expand Down

0 comments on commit 4ab7cb2

Please sign in to comment.