Generate snapshot via Exq worker

ex-snapshot
Marcin Kulik 7 years ago
parent 1102164e56
commit d43ed62eb3

@ -1,11 +0,0 @@
class AsciicastProcessor
def process(asciicast)
AsciicastSnapshotUpdater.new.update(asciicast)
if asciicast.version == 0
AsciicastFramesFileUpdater.new.update(asciicast)
end
end
end

@ -4,7 +4,10 @@ class AsciicastWorker
def perform(asciicast_id)
asciicast = Asciicast.find(asciicast_id)
AsciicastProcessor.new.process(asciicast)
if asciicast.version == 0
AsciicastFramesFileUpdater.new.update(asciicast)
end
rescue ActiveRecord::RecordNotFound
# oh well...

@ -51,7 +51,19 @@ config :asciinema, Asciinema.PngGenerator.A2png,
config :asciinema, :redis_url, System.get_env("REDIS_URL") || "redis://redis:6379"
config :asciinema, :poster_generator, Asciinema.Asciicasts.PosterGenerator.Sidekiq
config :asciinema, :snapshot_updater, Asciinema.Asciicasts.SnapshotUpdater.Exq
config :asciinema, :frames_generator, Asciinema.Asciicasts.FramesGenerator.Sidekiq
config :exq,
name: Exq,
start_on_application: false,
url: System.get_env("REDIS_URL") || "redis://redis:6379",
namespace: "exq",
concurrency: 10,
queues: ["default"],
scheduler_enable: true,
max_retries: 25,
shutdown_timeout: 5000
# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.

@ -23,4 +23,5 @@ config :asciinema, Asciinema.Repo,
config :asciinema, :file_store, Asciinema.FileStore.Local
config :asciinema, Asciinema.FileStore.Local, path: "uploads/test/"
config :asciinema, :poster_generator, Asciinema.Asciicasts.PosterGenerator.Noop
config :asciinema, :snapshot_updater, Asciinema.Asciicasts.SnapshotUpdater.Sync
config :asciinema, :frames_generator, Asciinema.Asciicasts.FramesGenerator.Noop

@ -18,6 +18,7 @@ defmodule Asciinema do
# worker(Asciinema.Worker, [arg1, arg2, arg3]),
:poolboy.child_spec(:worker, Asciinema.PngGenerator.A2png.poolboy_config(), []),
supervisor(Asciinema.Vt.Pool, []),
supervisor(Exq, []),
worker(Redix, [redis_url, [name: :redix]])
]

@ -1,7 +1,7 @@
defmodule Asciinema.Asciicasts do
import Ecto.Query, warn: false
alias Asciinema.{Repo, Asciicast, FileStore, StringUtils, Vt}
alias Asciinema.Asciicasts.PosterGenerator
alias Asciinema.Asciicasts.{SnapshotUpdater, FramesGenerator}
def get_asciicast!(id) when is_integer(id) do
Repo.get!(Asciicast, id)
@ -36,7 +36,7 @@ defmodule Asciinema.Asciicasts do
attrs = Map.merge(attrs, overrides),
changeset = Asciicast.create_changeset(asciicast, attrs),
{:ok, %Asciicast{} = asciicast} <- do_create_asciicast(changeset, files) do
generate_poster(asciicast)
:ok = SnapshotUpdater.update_snapshot(asciicast)
{:ok, asciicast}
else
{:error, :invalid} ->
@ -62,7 +62,8 @@ defmodule Asciinema.Asciicasts do
case do_create_asciicast(changeset, files) do
{:ok, %Asciicast{} = asciicast} ->
generate_poster(asciicast)
:ok = FramesGenerator.generate_frames(asciicast)
:ok = SnapshotUpdater.update_snapshot(asciicast)
{:ok, asciicast}
otherwise ->
otherwise
@ -117,10 +118,6 @@ defmodule Asciinema.Asciicasts do
:ok = FileStore.put_file(file_store_path, tmp_file_path, content_type)
end
defp generate_poster(asciicast) do
PosterGenerator.generate(asciicast)
end
def stdout_stream(%Asciicast{version: 0} = asciicast) do
{:ok, tmp_dir_path} = Briefly.create(directory: true)
local_timing_path = tmp_dir_path <> "/timing"

@ -0,0 +1,10 @@
defmodule Asciinema.Asciicasts.FramesGenerator do
alias Asciinema.Asciicast
@doc "Generates frames file for given asciicast"
@callback generate_frames(asciicast :: %Asciicast{}) :: :ok | {:error, term}
def generate_frames(asciicast) do
Application.get_env(:asciinema, :frames_generator).generate_frames(asciicast)
end
end

@ -0,0 +1,5 @@
defmodule Asciinema.Asciicasts.FramesGenerator.Noop do
def generate_frames(_asciicast) do
:ok
end
end

@ -1,8 +1,8 @@
defmodule Asciinema.Asciicasts.PosterGenerator.Sidekiq do
defmodule Asciinema.Asciicasts.FramesGenerator.Sidekiq do
alias Asciinema.Asciicast
alias Asciinema.SidekiqClient
def generate(%Asciicast{id: id}) do
def generate_frames(%Asciicast{id: id}) do
SidekiqClient.enqueue("AsciicastWorker", [id])
end
end

@ -1,10 +0,0 @@
defmodule Asciinema.Asciicasts.PosterGenerator do
alias Asciinema.Asciicast
@doc "Generates poster for given asciicast"
@callback generate(asciicast :: %Asciicast{}) :: :ok | {:error, term}
def generate(asciicast) do
Application.get_env(:asciinema, :poster_generator).generate(asciicast)
end
end

@ -1,5 +0,0 @@
defmodule Asciinema.Asciicasts.PosterGenerator.Noop do
def generate(_asciicast) do
:ok
end
end

@ -0,0 +1,10 @@
defmodule Asciinema.Asciicasts.SnapshotUpdater do
alias Asciinema.Asciicast
@doc "Generates poster for given asciicast"
@callback update_snapshot(asciicast :: %Asciicast{}) :: :ok | {:error, term}
def update_snapshot(asciicast) do
Application.get_env(:asciinema, :snapshot_updater).update_snapshot(asciicast)
end
end

@ -0,0 +1,14 @@
defmodule Asciinema.Asciicasts.SnapshotUpdater.Exq do
alias Asciinema.{Repo, Asciicasts, Asciicast}
def update_snapshot(%Asciicast{id: id}) do
{:ok, _jid} = Exq.enqueue(Exq, "default", __MODULE__, [id])
:ok
end
def perform(asciicast_id) do
if asciicast = Repo.get(Asciicast, asciicast_id) do
{:ok, _} = Asciicasts.update_snapshot(asciicast)
end
end
end

@ -0,0 +1,8 @@
defmodule Asciinema.Asciicasts.SnapshotUpdater.Sync do
alias Asciinema.{Asciicast, Asciicasts}
def update_snapshot(%Asciicast{} = asciicast) do
{:ok, _} = Asciicasts.update_snapshot(asciicast)
:ok
end
end

@ -36,6 +36,7 @@ defmodule Asciinema.Mixfile do
:redix,
:timex,
:timex_ecto,
:exq,
]]
end
@ -51,6 +52,7 @@ defmodule Asciinema.Mixfile do
{:briefly, "~> 0.3"},
{:cowboy, "~> 1.0"},
{:ex_aws, "~> 1.0"},
{:exq, "~> 0.9.0"},
{:gettext, "~> 0.11"},
{:phoenix, "~> 1.2.1"},
{:phoenix_ecto, "~> 3.0"},

@ -10,6 +10,7 @@
"earmark": {:hex, :earmark, "1.2.2", "f718159d6b65068e8daeef709ccddae5f7fdc770707d82e7d126f584cd925b74", [:mix], [], "hexpm"},
"ecto": {:hex, :ecto, "2.0.4", "03fd3b9aa508b1383eb38c00ac389953ed22af53811aa2e504975a3e814a8d97", [:mix], [{:db_connection, "~> 1.0-rc.2", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.7.7", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 1.5 or ~> 2.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.11.2", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0-beta", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
"ex_aws": {:hex, :ex_aws, "1.1.2", "b78416d0a84efe92c22e5df8ba7ca028d63b2b4228f95871a1ecf10324b6493b", [:mix], [{:configparser_ex, "~> 0.2.1", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "1.6.3 or 1.6.5 or 1.7.1", [hex: :hackney, repo: "hexpm", optional: true]}, {:jsx, "~> 2.8", [hex: :jsx, repo: "hexpm", optional: true]}, {:poison, ">= 1.2.0", [hex: :poison, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}, {:xml_builder, "~> 0.0.6", [hex: :xml_builder, repo: "hexpm", optional: true]}], "hexpm"},
"exq": {:hex, :exq, "0.9.0", "3feeb085fcd94a687033211e10c78cf9dca1de062aac3fa9a4b1f808cdcea522", [:mix], [{:poison, ">= 1.2.0 or ~> 2.0", [hex: :poison, repo: "hexpm", optional: false]}, {:redix, ">= 0.5.0", [hex: :redix, repo: "hexpm", optional: false]}, {:uuid, ">= 1.0.0", [hex: :uuid, repo: "hexpm", optional: false]}], "hexpm"},
"fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], [], "hexpm"},
"gettext": {:hex, :gettext, "0.11.0", "80c1dd42d270482418fa158ec5ba073d2980e3718bacad86f3d4ad71d5667679", [:mix], [], "hexpm"},
"hackney": {:hex, :hackney, "1.7.1", "e238c52c5df3c3b16ce613d3a51c7220a784d734879b1e231c9babd433ac1cb4", [:rebar3], [{:certifi, "1.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "4.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
@ -36,4 +37,5 @@
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"},
"timex": {:hex, :timex, "3.1.15", "94abaec8fef2436ced4d0e1b4ed50c8eaa5fb9138fc0699946ddee7abf5aaff2", [:mix], [{:combine, "~> 0.7", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"},
"timex_ecto": {:hex, :timex_ecto, "3.0.5", "3ec6c25e10d2c0020958e5df64d2b5e690e441faa2c2259da8bc6bd3d7f39256", [:mix], [{:ecto, "~> 2.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:timex, "~> 3.0", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm"},
"tzdata": {:hex, :tzdata, "0.5.12", "1c17b68692c6ba5b6ab15db3d64cc8baa0f182043d5ae9d4b6d35d70af76f67b", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}}
"tzdata": {:hex, :tzdata, "0.5.12", "1c17b68692c6ba5b6ab15db3d64cc8baa0f182043d5ae9d4b6d35d70af76f67b", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
"uuid": {:hex, :uuid, "1.1.7", "007afd58273bc0bc7f849c3bdc763e2f8124e83b957e515368c498b641f7ab69", [:mix], [], "hexpm"}}

@ -10,4 +10,6 @@
# We recommend using the bang functions (`insert!`, `update!`
# and so on) as they will fail if something goes wrong.
Application.put_env(:asciinema, :snapshot_updater, Asciinema.Asciicasts.SnapshotUpdater.Sync)
Asciinema.Users.create_asciinema_user!()

@ -1,32 +0,0 @@
require 'rails_helper'
describe AsciicastProcessor do
let(:processor) { described_class.new }
describe '#process' do
let(:asciicast) { double('asciicast', version: 0) }
let(:snapshot_updater) { double('snapshot_updater', :update => nil) }
let(:frames_file_updater) { double('frames_file_updater', :update => nil) }
subject { processor.process(asciicast) }
before do
allow(AsciicastSnapshotUpdater).to receive(:new) { snapshot_updater }
allow(AsciicastFramesFileUpdater).to receive(:new) { frames_file_updater }
end
it 'generates a snapshot' do
subject
expect(snapshot_updater).to have_received(:update).with(asciicast)
end
it 'generates animation frames' do
subject
expect(frames_file_updater).to have_received(:update).with(asciicast)
end
end
end

@ -1,24 +0,0 @@
require 'rails_helper'
describe AsciicastWorker do
let(:worker) { described_class.new }
describe '#perform' do
let(:asciicast) { double('asciicast') }
let(:asciicast_processor) { double('asciicast_processor', :process => nil) }
before do
allow(Asciicast).to receive(:find).with(123) { asciicast }
allow(AsciicastProcessor).to receive(:new).
with(no_args) { asciicast_processor }
end
it 'processes given asciicast with AsciicastProcessor' do
worker.perform(123)
expect(asciicast_processor).to have_received(:process).with(asciicast)
end
end
end
Loading…
Cancel
Save