const auto name = py_module->get_name();
auto active_module = std::make_shared<ActivePyModule>(py_module, clog);
+ pending_modules.insert(name);
// Send all python calls down a Finisher to avoid blocking
// C++ code, and avoid any potential lock cycles.
finisher.queue(new LambdaContext([this, active_module, name](int) {
int r = active_module->load(this);
+ std::lock_guard l(lock);
+ pending_modules.erase(name);
if (r != 0) {
derr << "Failed to run module in active mode ('" << name << "')"
<< dendl;
} else {
- std::lock_guard l(lock);
auto em = modules.emplace(name, active_module);
ceph_assert(em.second); // actually inserted
class ActivePyModules
{
+ // module class instances not yet created
+ std::set<std::string, std::less<>> pending_modules;
+ // module class instances already created
std::map<std::string, std::shared_ptr<ActivePyModule>> modules;
PyModuleConfig &module_config;
std::map<std::string, std::string> store_cache;
const std::string ¬ify_id);
void notify_all(const LogEntry &log_entry);
+ bool is_pending(std::string_view name) const {
+ return pending_modules.count(name) > 0;
+ }
bool module_exists(const std::string &name) const
{
return modules.count(name) > 0;
if (obsolete_modules.count(name)) {
continue;
}
+ if (active_modules->is_pending(name)) {
+ continue;
+ }
if (!active_modules->module_exists(name)) {
if (failed_modules.find(name) == failed_modules.end() &&
dependency_modules.find(name) == dependency_modules.end()) {