@@ -7,7 +7,7 @@ defmodule Reencodarr.Media.VideoQueries do
77 """
88
99 import Ecto.Query
10- alias Reencodarr . { Media.Video , Media.Vmaf , Repo }
10+ alias Reencodarr . { Media.DashboardQueueCache , Media. Video, Media.Vmaf , Repo }
1111
1212 @ doc """
1313 Gets videos ready for CRF search (state: analyzed).
@@ -76,22 +76,8 @@ defmodule Reencodarr.Media.VideoQueries do
7676 Gets a lightweight preview of videos needing analysis for dashboard display.
7777 """
7878 @ spec videos_needing_analysis_preview ( integer ( ) , keyword ( ) ) :: [ map ( ) ]
79- def videos_needing_analysis_preview ( limit \\ 10 , opts \\ [ ] ) do
80- Repo . all (
81- from ( v in Video ,
82- where: v . state == :needs_analysis ,
83- order_by: [
84- desc: v . priority ,
85- desc: v . size ,
86- desc: v . inserted_at ,
87- desc: v . updated_at
88- ] ,
89- limit: ^ limit ,
90- select: % { id: v . id , path: v . path }
91- ) ,
92- opts
93- )
94- end
79+ def videos_needing_analysis_preview ( limit \\ 10 , opts \\ [ ] ) ,
80+ do: cached_dashboard_queue_preview ( :analyzer , limit , opts )
9581
9682 @ doc """
9783 Atomically claims videos for analysis by transitioning them from
@@ -146,17 +132,8 @@ defmodule Reencodarr.Media.VideoQueries do
146132 Gets a lightweight preview of videos ready for CRF search for dashboard display.
147133 """
148134 @ spec videos_for_crf_search_preview ( integer ( ) , keyword ( ) ) :: [ map ( ) ]
149- def videos_for_crf_search_preview ( limit \\ 10 , opts \\ [ ] ) do
150- Repo . all (
151- from ( v in Video ,
152- where: v . state == :analyzed ,
153- order_by: [ desc: v . priority , desc: v . bitrate , desc: v . size , asc: v . updated_at ] ,
154- limit: ^ limit ,
155- select: % { id: v . id , path: v . path }
156- ) ,
157- opts
158- )
159- end
135+ def videos_for_crf_search_preview ( limit \\ 10 , opts \\ [ ] ) ,
136+ do: cached_dashboard_queue_preview ( :crf_searcher , limit , opts )
160137
161138 @ doc """
162139 Gets videos ready for encoding with complex alternation logic between services and libraries.
@@ -184,18 +161,72 @@ defmodule Reencodarr.Media.VideoQueries do
184161 Gets a lightweight preview of videos ready for encoding for dashboard display.
185162 """
186163 @ spec videos_ready_for_encoding_preview ( integer ( ) , keyword ( ) ) :: [ map ( ) ]
187- def videos_ready_for_encoding_preview ( limit , opts \\ [ ] ) do
164+ def videos_ready_for_encoding_preview ( limit , opts \\ [ ] ) ,
165+ do: cached_dashboard_queue_preview ( :encoder , limit , opts )
166+
167+ @ doc """
168+ Returns all cached dashboard queue preview items.
169+
170+ The dashboard uses this single cache-backed query so queue previews no longer
171+ hit the live `videos` table during refresh.
172+ """
173+ @ spec dashboard_queue_preview_items ( keyword ( ) ) :: [ DashboardQueueCache . t ( ) ]
174+ def dashboard_queue_preview_items ( opts \\ [ ] ) do
188175 Repo . all (
189- from ( v in Video ,
190- where: v . state == :crf_searched and not is_nil ( v . chosen_vmaf_id ) ,
191- order_by: [ desc: v . priority , desc: v . updated_at ] ,
192- limit: ^ limit ,
193- select: % { id: v . id , path: v . path }
176+ from ( q in DashboardQueueCache ,
177+ where: q . queue_type in [ :analyzer , :crf_searcher , :encoder ] ,
178+ select: q
194179 ) ,
195180 opts
196181 )
197182 end
198183
184+ defp queue_preview_items ( queue_type , opts ) do
185+ dashboard_queue_preview_items ( opts )
186+ |> Enum . filter ( & ( & 1 . queue_type == queue_type ) )
187+ |> Enum . sort_by ( & queue_preview_sort_key ( queue_type , & 1 ) )
188+ end
189+
190+ defp cached_dashboard_queue_preview ( queue_type , limit , opts ) do
191+ queue_preview_items ( queue_type , opts )
192+ |> Enum . take ( limit )
193+ |> Enum . map ( & queue_preview_item / 1 )
194+ end
195+
196+ defp queue_preview_sort_key ( :analyzer , row ) do
197+ {
198+ - normalize_int ( row . priority ) ,
199+ - normalize_int ( row . size ) ,
200+ - timestamp ( row . inserted_at ) ,
201+ - timestamp ( row . updated_at )
202+ }
203+ end
204+
205+ defp queue_preview_sort_key ( :crf_searcher , row ) do
206+ {
207+ - normalize_int ( row . priority ) ,
208+ - normalize_int ( row . bitrate ) ,
209+ - normalize_int ( row . size ) ,
210+ timestamp ( row . updated_at )
211+ }
212+ end
213+
214+ defp queue_preview_sort_key ( :encoder , row ) do
215+ {
216+ - normalize_int ( row . priority ) ,
217+ - normalize_int ( row . savings ) ,
218+ - timestamp ( row . updated_at )
219+ }
220+ end
221+
222+ defp normalize_int ( nil ) , do: 0
223+ defp normalize_int ( value ) when is_integer ( value ) , do: value
224+
225+ defp timestamp ( nil ) , do: 0
226+ defp timestamp ( % DateTime { } = dt ) , do: DateTime . to_unix ( dt , :microsecond )
227+
228+ defp queue_preview_item ( row ) , do: % { id: row . video_id , path: row . path }
229+
199230 @ doc """
200231 Counts total videos ready for encoding.
201232 """
0 commit comments