diff --git a/app/services/asciicast_processor.rb b/app/services/asciicast_processor.rb deleted file mode 100644 index a2d3c89..0000000 --- a/app/services/asciicast_processor.rb +++ /dev/null @@ -1,11 +0,0 @@ -class AsciicastProcessor - - def process(asciicast) - AsciicastSnapshotUpdater.new.update(asciicast) - - if asciicast.version == 0 - AsciicastFramesFileUpdater.new.update(asciicast) - end - end - -end diff --git a/app/workers/asciicast_worker.rb b/app/workers/asciicast_worker.rb index fe373d2..c9b176c 100644 --- a/app/workers/asciicast_worker.rb +++ b/app/workers/asciicast_worker.rb @@ -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... diff --git a/config/config.exs b/config/config.exs index 4015833..490c72d 100644 --- a/config/config.exs +++ b/config/config.exs @@ -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. diff --git a/config/test.exs b/config/test.exs index 5a1e3cc..a5f7c19 100644 --- a/config/test.exs +++ b/config/test.exs @@ -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 diff --git a/lib/asciinema.ex b/lib/asciinema.ex index 2c8f281..bcf5362 100644 --- a/lib/asciinema.ex +++ b/lib/asciinema.ex @@ -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]]) ] diff --git a/lib/asciinema/asciicasts.ex b/lib/asciinema/asciicasts.ex index 19ab749..4ebfd49 100644 --- a/lib/asciinema/asciicasts.ex +++ b/lib/asciinema/asciicasts.ex @@ -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" diff --git a/lib/asciinema/asciicasts/frames_generator.ex b/lib/asciinema/asciicasts/frames_generator.ex new file mode 100644 index 0000000..b742e94 --- /dev/null +++ b/lib/asciinema/asciicasts/frames_generator.ex @@ -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 diff --git a/lib/asciinema/asciicasts/frames_generator/noop.ex b/lib/asciinema/asciicasts/frames_generator/noop.ex new file mode 100644 index 0000000..16c097c --- /dev/null +++ b/lib/asciinema/asciicasts/frames_generator/noop.ex @@ -0,0 +1,5 @@ +defmodule Asciinema.Asciicasts.FramesGenerator.Noop do + def generate_frames(_asciicast) do + :ok + end +end diff --git a/lib/asciinema/asciicasts/poster_generator/sidekiq.ex b/lib/asciinema/asciicasts/frames_generator/sidekiq.ex similarity index 54% rename from lib/asciinema/asciicasts/poster_generator/sidekiq.ex rename to lib/asciinema/asciicasts/frames_generator/sidekiq.ex index c69f457..06b3e35 100644 --- a/lib/asciinema/asciicasts/poster_generator/sidekiq.ex +++ b/lib/asciinema/asciicasts/frames_generator/sidekiq.ex @@ -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 diff --git a/lib/asciinema/asciicasts/poster_generator.ex b/lib/asciinema/asciicasts/poster_generator.ex deleted file mode 100644 index 0ed2dad..0000000 --- a/lib/asciinema/asciicasts/poster_generator.ex +++ /dev/null @@ -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 diff --git a/lib/asciinema/asciicasts/poster_generator/noop.ex b/lib/asciinema/asciicasts/poster_generator/noop.ex deleted file mode 100644 index 338daa4..0000000 --- a/lib/asciinema/asciicasts/poster_generator/noop.ex +++ /dev/null @@ -1,5 +0,0 @@ -defmodule Asciinema.Asciicasts.PosterGenerator.Noop do - def generate(_asciicast) do - :ok - end -end diff --git a/lib/asciinema/asciicasts/snapshot_updater.ex b/lib/asciinema/asciicasts/snapshot_updater.ex new file mode 100644 index 0000000..fc6f6c2 --- /dev/null +++ b/lib/asciinema/asciicasts/snapshot_updater.ex @@ -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 diff --git a/lib/asciinema/asciicasts/snapshot_updater/exq.ex b/lib/asciinema/asciicasts/snapshot_updater/exq.ex new file mode 100644 index 0000000..af5bad8 --- /dev/null +++ b/lib/asciinema/asciicasts/snapshot_updater/exq.ex @@ -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 diff --git a/lib/asciinema/asciicasts/snapshot_updater/sync.ex b/lib/asciinema/asciicasts/snapshot_updater/sync.ex new file mode 100644 index 0000000..699ecfe --- /dev/null +++ b/lib/asciinema/asciicasts/snapshot_updater/sync.ex @@ -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 diff --git a/mix.exs b/mix.exs index aa7406a..964f3db 100644 --- a/mix.exs +++ b/mix.exs @@ -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"}, diff --git a/mix.lock b/mix.lock index 4432d88..510ef59 100644 --- a/mix.lock +++ b/mix.lock @@ -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"}} diff --git a/priv/repo/seeds.exs b/priv/repo/seeds.exs index 71d0563..11a5946 100644 --- a/priv/repo/seeds.exs +++ b/priv/repo/seeds.exs @@ -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!() diff --git a/spec/services/asciicast_processor_spec.rb b/spec/services/asciicast_processor_spec.rb deleted file mode 100644 index 01061ee..0000000 --- a/spec/services/asciicast_processor_spec.rb +++ /dev/null @@ -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 diff --git a/spec/workers/asciicast_worker_spec.rb b/spec/workers/asciicast_worker_spec.rb deleted file mode 100644 index 29d3805..0000000 --- a/spec/workers/asciicast_worker_spec.rb +++ /dev/null @@ -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