#include "base/AsyncCall.h"
#include "base/AsyncJob.h"
#include "base/AsyncJobCalls.h"
+#include "base/PackableStream.h"
#include "base/TextException.h"
#include "cbdata.h"
+#include "mem/PoolingAllocator.h"
#include "MemBuf.h"
+#include "mgr/Registration.h"
+#include "Store.h"
#include <ostream>
+#include <unordered_set>
InstanceIdDefinitions(AsyncJob, "job");
+/// a set of all AsyncJob objects in existence
+static auto &
+AllJobs()
+{
+ static const auto jobs = new std::unordered_set<AsyncJob *, std::hash<AsyncJob *>, std::equal_to<AsyncJob *>, PoolingAllocator<AsyncJob *> >();
+ return *jobs;
+}
+
void
AsyncJob::Start(const Pointer &job)
{
{
debugs(93,5, "AsyncJob constructed, this=" << this <<
" type=" << typeName << " [" << id << ']');
+ AllJobs().insert(this);
}
AsyncJob::~AsyncJob()
debugs(93,5, "AsyncJob destructed, this=" << this <<
" type=" << typeName << " [" << id << ']');
assert(!started_ || swanSang_);
+ AllJobs().erase(this);
}
void AsyncJob::start()
return buf.content();
}
+void
+AsyncJob::ReportAllJobs(StoreEntry *e)
+{
+ PackableStream os(*e);
+ // this loop uses YAML syntax, but AsyncJob::status() still needs to be adjusted to use YAML
+ const char *indent = " ";
+ for (const auto job: AllJobs()) {
+ os << indent << job->id << ":\n";
+ os << indent << indent << "type: '" << job->typeName << "'\n";
+ os << indent << indent << "status:" << job->status() << '\n';
+ if (!job->started_)
+ os << indent << indent << "started: false\n";
+ if (job->stopReason)
+ os << indent << indent << "stopped: '" << job->stopReason << "'\n";
+ }
+}
+
+void
+AsyncJob::RegisterWithCacheManager()
+{
+ Mgr::RegisterAction("jobs", "All AsyncJob objects", &AsyncJob::ReportAllJobs, 0, 1);
+}
+
/// successfully (i.e. without throwing).
static void Start(const Pointer &job);
+ static void RegisterWithCacheManager();
+
protected:
// XXX: temporary method to replace "delete this" in jobs-in-transition.
// Will be replaced with calls to mustStop() when transition is complete.
// external destruction prohibited to ensure swanSong() is called
~AsyncJob() override;
+ /// writes a cache manager report about all jobs existing in this worker
+ static void ReportAllJobs(StoreEntry *);
+
const char *stopReason; ///< reason for forcing done() to be true
const char *typeName; ///< kid (leaf) class name, for debugging
AsyncCall::Pointer inCall; ///< the asynchronous call being handled, if any