17inline constexpr auto kQueued =
"Queued";
18inline constexpr auto kRunning =
"Running";
19inline constexpr auto kFinished =
"Finished";
20inline constexpr auto kFailed =
"Failed";
21inline constexpr auto kCanceled =
"Canceled";
26 event.
jobId = snapshot.jobId;
27 event.kind = snapshot.kind;
28 event.state = snapshot.state;
29 event.stage = snapshot.stage;
30 event.progress = snapshot.progress;
31 event.message = message.empty() ? snapshot.message : std::move(message);
32 event.pageIndex = snapshot.pageIndex;
33 event.pageCount = snapshot.pageCount;
39 snapshot.
kind =
event.kind;
40 snapshot.state =
event.state;
41 snapshot.stage =
event.stage;
42 snapshot.progress =
event.progress;
43 if (!event.message.empty()) snapshot.message =
event.message;
44 snapshot.pageIndex =
event.pageIndex;
45 snapshot.pageCount =
event.pageCount;
51 std::shared_ptr<core::ports::diagnostics::IErrorReporter> errorReporter)
52 : errorReporter_(std::move(errorReporter)) {}
54JobId JobManager::makeJobId() {
59 auto data = std::make_shared<JobData>();
60 data->snap.jobId = makeJobId();
61 data->snap.kind = kind;
64 data->snap.progress = 0.0;
65 data->snap.message = std::string(kQueued);
66 data->cancel = std::make_shared<std::atomic<bool>>(
false);
67 data->pause = std::make_shared<std::atomic<bool>>(
false);
70 std::lock_guard<std::mutex> g(jobsMutex_);
71 jobs_.emplace(data->snap.jobId, data);
72 order_.push_back(data->snap.jobId);
75 return data->snap.jobId;
80 std::shared_ptr<JobData> job;
82 std::lock_guard<std::mutex> g(jobsMutex_);
83 auto it = jobs_.find(
id);
84 if (it == jobs_.end())
return 0;
88 std::lock_guard<std::mutex> g(job->m);
90 job->subs.emplace(sid, std::move(cb));
95 if (subId == 0)
return;
96 std::shared_ptr<JobData> job;
98 std::lock_guard<std::mutex> g(jobsMutex_);
99 auto it = jobs_.find(
id);
100 if (it == jobs_.end())
return;
104 std::lock_guard<std::mutex> g(job->m);
105 job->subs.erase(subId);
109 std::shared_ptr<JobData> job;
111 std::lock_guard<std::mutex> g(jobsMutex_);
112 auto it = jobs_.find(
id);
113 if (it == jobs_.end())
return;
123 std::lock_guard<std::mutex> g(job->m);
125 job->snap.message = std::string(kCanceled);
126 ev = snapshotToEvent(job->snap);
134 std::shared_ptr<JobData> job;
136 std::lock_guard<std::mutex> g(jobsMutex_);
137 auto it = jobs_.find(
id);
138 if (it == jobs_.end())
return;
148 std::lock_guard<std::mutex> g(job->m);
151 job->snap.message =
"Paused";
152 ev = snapshotToEvent(job->snap);
158 std::shared_ptr<JobData> job;
160 std::lock_guard<std::mutex> g(jobsMutex_);
161 auto it = jobs_.find(
id);
162 if (it == jobs_.end())
return;
172 std::lock_guard<std::mutex> g(job->m);
175 job->snap.message = std::string(kRunning);
176 ev = snapshotToEvent(job->snap);
182 std::shared_ptr<JobData> job;
184 std::lock_guard<std::mutex> g(jobsMutex_);
185 auto it = jobs_.find(
id);
186 if (it == jobs_.end())
return std::nullopt;
190 std::lock_guard<std::mutex> g(job->m);
195 std::lock_guard<std::mutex> g(jobsMutex_);
196 auto it = jobs_.find(
id);
197 if (it == jobs_.end())
return nullptr;
198 return it->second->cancel;
202 std::lock_guard<std::mutex> g(jobsMutex_);
203 auto it = jobs_.find(
id);
204 if (it == jobs_.end())
return nullptr;
205 return it->second->pause;
209 std::shared_ptr<JobData> job;
211 std::lock_guard<std::mutex> g(jobsMutex_);
212 auto it = jobs_.find(ev.
jobId);
213 if (it == jobs_.end())
return;
217 std::vector<JobEventCallback> cbs;
219 std::lock_guard<std::mutex> g(job->m);
220 applyEventToSnapshot(job->snap, ev);
222 cbs.reserve(job->subs.size());
223 for (
auto& kv : job->subs) cbs.push_back(kv.second);
226 for (
auto& cb : cbs) {
233 std::shared_ptr<JobData> job;
235 std::lock_guard<std::mutex> g(jobsMutex_);
236 auto it = jobs_.find(
id);
237 if (it == jobs_.end())
return;
242 std::lock_guard<std::mutex> g(job->m);
244 job->snap.message = std::string(kRunning);
245 ev = snapshotToEvent(job->snap);
255 std::shared_ptr<JobData> job;
257 std::lock_guard<std::mutex> g(jobsMutex_);
258 auto it = jobs_.find(
id);
259 if (it == jobs_.end())
return;
264 std::lock_guard<std::mutex> g(job->m);
266 job->snap.progress = 1.0;
267 job->snap.message = std::string(kFinished);
268 ev = snapshotToEvent(job->snap);
276void JobManager::prune(std::size_t maxJobs) {
277 if (maxJobs < 1) maxJobs = 1;
279 std::lock_guard<std::mutex> g(jobsMutex_);
280 if (jobs_.size() <= maxJobs)
return;
284 std::size_t scanned = 0;
285 const std::size_t limit = order_.size();
286 while (jobs_.size() > maxJobs && scanned < limit && !order_.empty()) {
287 JobId id = std::move(order_.front());
291 auto it = jobs_.find(
id);
292 if (it == jobs_.end())
continue;
293 auto job = it->second;
299 bool evictable =
false;
301 std::lock_guard<std::mutex> gj(job->m);
302 const auto st = job->snap.state;
304 evictable = terminal && job->subs.empty();
313 order_.push_back(std::move(
id));
319 std::shared_ptr<JobData> job;
321 std::lock_guard<std::mutex> g(jobsMutex_);
322 auto it = jobs_.find(
id);
323 if (it == jobs_.end())
return;
328 std::lock_guard<std::mutex> g(job->m);
330 job->snap.error = error;
331 job->snap.message = std::string(kFailed);
332 ev = snapshotToEvent(job->snap, error);
Provides shared helpers for reporting structured errors and exceptions.
Declares the private generic job state manager used behind JobSystem.
Declares private unique identifier helpers for transient import/job artifacts.
std::shared_ptr< std::atomic< bool > > pauseFlag(const JobId &id) const
Retrieve a job pause flag.
void finish(const JobId &id)
Mark a job as finished.
void start(const JobId &id)
Mark a job as running.
void cancel(const JobId &id)
Mark a job as canceled and set its cancellation flag.
void publish(const JobEvent &ev)
Publish an event to subscribers and update the stored snapshot.
void resume(const JobId &id)
Resume a paused job and clear its pause flag.
JobId submit(JobKind kind)
Create a tracked job in the pending state.
std::shared_ptr< std::atomic< bool > > cancelFlag(const JobId &id) const
Retrieve a job cancellation flag.
SubscriptionId subscribe(const JobId &id, JobEventCallback cb)
Subscribe to events for a job.
void fail(const JobId &id, const std::string &error)
Mark a job as failed.
void pause(const JobId &id)
Mark a running job as paused and set its pause flag.
void unsubscribe(const JobId &id, SubscriptionId subId)
Remove a job event subscription.
std::optional< JobSnapshot > snapshot(const JobId &id) const
Retrieve the latest state snapshot for a job.
JobManager(std::shared_ptr< core::ports::diagnostics::IErrorReporter > errorReporter)
Create a manager for generic job state and event delivery.
void reportException(core::ports::diagnostics::IErrorReporter *reporter, ErrorSeverity severity, const char *origin, std::exception_ptr exception)
Report an exception through the reporter's default exception handling.
std::uint64_t SubscriptionId
Identifier for a job event subscription.
std::string JobId
Stable identifier for one tracked job.
JobKind
Classifies the high-level type of job.
std::function< void(const JobEvent &)> JobEventCallback
Callback invoked for published job events.
std::string makeTransientId()
Generates a transient unique identifier for import and job artifacts.
Event emitted when a job changes state or progress.
Snapshot of the latest known job state.