// Python.h comes first because otherwise it clobbers ceph's assert
-#include "Python.h"
+#include "PythonCompat.h"
+
+#include "PyModule.h"
#include "common/debug.h"
#include "mgr/Gil.h"
#define dout_subsys ceph_subsys_mgr
-std::string handle_pyerror();
-
PyModuleRunner::~PyModuleRunner()
{
- Gil gil(pMyThreadState, true);
+ Gil gil(py_module->pMyThreadState, true);
if (pClassInstance) {
Py_XDECREF(pClassInstance);
pClassInstance = nullptr;
}
-
- Py_DECREF(pClass);
- pClass = nullptr;
}
int PyModuleRunner::serve()
{
- assert(pClassInstance != nullptr);
+ ceph_assert(pClassInstance != nullptr);
// This method is called from a separate OS thread (i.e. a thread not
// created by Python), so tell Gil to wrap this in a new thread state.
- Gil gil(pMyThreadState, true);
+ Gil gil(py_module->pMyThreadState, true);
auto pValue = PyObject_CallMethod(pClassInstance,
const_cast<char*>("serve"), nullptr);
// This is not a very informative log message because it's an
// unknown/unexpected exception that we can't say much about.
- // Peek at the exception for the cluster log, before
- // dumping the backtrace to log log next.
- PyObject *ptype, *pvalue, *ptraceback;
- PyErr_Fetch(&ptype, &pvalue, &ptraceback);
- assert(ptype);
- assert(pvalue);
- PyObject *pvalue_str = PyObject_Str(pvalue);
- std::string exc_msg = PyString_AsString(pvalue_str);
- Py_DECREF(pvalue_str);
- PyErr_Restore(ptype, pvalue, ptraceback);
+
+ // Get short exception message for the cluster log, before
+ // dumping the full backtrace to the local log.
+ std::string exc_msg = peek_pyerror();
- clog->error() << "Unhandled exception from module '" << module_name
- << "' while running on mgr." << g_conf->name.get_id()
+ clog->error() << "Unhandled exception from module '" << get_name()
+ << "' while running on mgr." << g_conf()->name.get_id()
<< ": " << exc_msg;
- derr << module_name << ".serve:" << dendl;
+ derr << get_name() << ".serve:" << dendl;
derr << handle_pyerror() << dendl;
+
+ py_module->fail(exc_msg);
+
return -EINVAL;
}
void PyModuleRunner::shutdown()
{
- assert(pClassInstance != nullptr);
+ ceph_assert(pClassInstance != nullptr);
- Gil gil(pMyThreadState, true);
+ Gil gil(py_module->pMyThreadState, true);
auto pValue = PyObject_CallMethod(pClassInstance,
const_cast<char*>("shutdown"), nullptr);
if (pValue != NULL) {
Py_DECREF(pValue);
} else {
- derr << "Failed to invoke shutdown() on " << module_name << dendl;
+ derr << "Failed to invoke shutdown() on " << get_name() << dendl;
derr << handle_pyerror() << dendl;
}
}
void PyModuleRunner::log(int level, const std::string &record)
{
#undef dout_prefix
-#define dout_prefix *_dout << "mgr[" << module_name << "] "
- dout(level) << record << dendl;
+#define dout_prefix *_dout << "mgr[" << get_name() << "] "
+ dout(ceph::dout::need_dynamic(level)) << record << dendl;
#undef dout_prefix
#define dout_prefix *_dout << "mgr " << __func__ << " "
}