@@ -33,6 +33,7 @@ WorkshopQueue::WorkshopQueue(const Logger &parent_logger,
3333 db(event_loop, std::move(_db_config), *this),
3434 check_notify_event(event_loop, BIND_THIS_METHOD(CheckNotify)),
3535 timer_event(event_loop, BIND_THIS_METHOD(OnTimer)),
36+ progress_notify_timer(event_loop, BIND_THIS_METHOD(OnProgressNotifyTimer)),
3637 handler(_handler)
3738{
3839}
@@ -48,6 +49,19 @@ WorkshopQueue::OnTimer() noexcept
4849 Run ();
4950}
5051
52+ void
53+ WorkshopQueue::OnProgressNotifyTimer () noexcept
54+ {
55+ try {
56+ for (std::string_view plan_name : progress_notify_plans)
57+ db.Execute (fmt::format (" NOTIFY \" job_progress:{}\" " , plan_name).c_str ());
58+ } catch (...) {
59+ db.CheckError (std::current_exception ());
60+ }
61+
62+ progress_notify_plans.clear ();
63+ }
64+
5165bool
5266WorkshopQueue::GetNextScheduled (int *span_r)
5367{
@@ -345,14 +359,19 @@ WorkshopQueue::CheckRateLimit(const char *plan_name,
345359
346360bool
347361WorkshopQueue::SetJobProgress (const WorkshopJob &job, unsigned progress,
348- const char *timeout) noexcept
362+ const char *timeout, bool notify ) noexcept
349363{
350364 assert (&job.queue == this );
351365
352366 logger (5 , " job " , job.id , " progress=" , progress);
353367
354368 ScheduleCheckNotify ();
355369
370+ if (notify)
371+ if (auto [it, inserted] = progress_notify_plans.emplace (job.plan_name );
372+ inserted && !progress_notify_timer.IsPending ())
373+ progress_notify_timer.Schedule (std::chrono::milliseconds{250 });
374+
356375 try {
357376 pg_set_job_progress (db, job.id .c_str (), progress, timeout);
358377 return true ;
@@ -497,6 +516,7 @@ WorkshopQueue::OnDisconnect() noexcept
497516{
498517 logger (4 , " disconnected from database" );
499518
519+ progress_notify_timer.Cancel ();
500520 timer_event.Cancel ();
501521 check_notify_event.Cancel ();
502522}
0 commit comments