in thrift/compiler/generate/t_py_generator.cc [2860:3040]
void t_py_generator::generate_process_function(
const t_service* /*tservice*/,
const t_function* tfunction,
bool with_context,
bool future) {
const string& fn_name = tfunction->get_name();
// Open function
if (future) {
indent(f_service_) << "def then_" << fn_name
<< "(self, args, handler_ctx):" << endl;
} else {
indent(f_service_) << "@thrift_process_method(" << fn_name << "_args, "
<< "oneway="
<< (tfunction->qualifier() ==
t_function_qualifier::one_way
? "True"
: "False")
<< (gen_asyncio_ ? ", asyncio=True" : "") << ")" << endl;
f_service_ << indent() << "def process_" << fn_name
<< "(self, args, handler_ctx"
<< (gen_asyncio_ ? ", seqid, oprot, fn_name):" : "):") << endl;
}
indent_up();
const t_struct* xs = tfunction->get_xceptions();
const std::vector<t_field*>& xceptions = xs->get_members();
vector<t_field*>::const_iterator x_iter;
// Declare result for non oneway function
if (tfunction->qualifier() != t_function_qualifier::one_way) {
f_service_ << indent() << "result = " << fn_name + "_result()" << endl;
}
if (gen_asyncio_) {
const t_struct* arg_struct = tfunction->get_paramlist();
const std::vector<t_field*>& fields = arg_struct->get_members();
vector<t_field*>::const_iterator f_iter;
string handler =
"self._handler." + rename_reserved_keywords(tfunction->get_name());
string args_list = "";
bool first = true;
if (with_context) {
args_list += "handler_ctx";
first = false;
}
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
if (first) {
first = false;
} else {
args_list += ", ";
}
args_list += "args.";
args_list += rename_reserved_keywords((*f_iter)->get_name());
}
f_service_ << indent() << "if should_run_on_thread(" << handler
<< "):" << endl
<< indent() << " fut = self._loop.run_in_executor(None, "
<< handler << ", " << args_list << ")" << endl
<< indent() << "else:" << endl
<< indent() << " fut = call_as_future(" << handler
<< ", self._loop, " << args_list << ")" << endl;
if (tfunction->qualifier() != t_function_qualifier::one_way) {
string known_exceptions = "{";
int exc_num;
for (exc_num = 0, x_iter = xceptions.begin(); x_iter != xceptions.end();
++x_iter, ++exc_num) {
if (exc_num > 0) {
known_exceptions += ", ";
}
known_exceptions += "'";
known_exceptions += rename_reserved_keywords((*x_iter)->get_name());
known_exceptions += "': ";
known_exceptions += type_name((*x_iter)->get_type());
}
known_exceptions += "}";
f_service_
<< indent() << "fut.add_done_callback("
<< "lambda f: write_results_after_future("
<< "result, self._event_handler, handler_ctx, seqid, oprot, fn_name, "
<< known_exceptions + ", f))" << endl;
}
f_service_ << indent() << "return fut" << endl;
indent_down();
f_service_ << endl;
} else {
// Try block to wrap call to handler
f_service_ << indent() << "try:" << endl;
indent_up();
// Generate the function call
const t_struct* arg_struct = tfunction->get_paramlist();
const std::vector<t_field*>& fields = arg_struct->get_members();
vector<t_field*>::const_iterator f_iter;
string handler = (future ? "self._handler.future_" : "self._handler.") +
rename_reserved_keywords(tfunction->get_name());
f_service_ << indent();
if (tfunction->qualifier() != t_function_qualifier::one_way &&
!tfunction->get_returntype()->is_void()) {
f_service_ << "result.success = ";
}
f_service_ << handler << "(";
bool first = true;
if (with_context) {
f_service_ << "handler_ctx";
first = false;
}
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
if (first) {
first = false;
} else {
f_service_ << ", ";
}
f_service_ << "args." << rename_reserved_keywords((*f_iter)->get_name());
}
f_service_ << ")" << (future ? ".result()" : "") << endl;
indent_down();
int exc_num;
for (exc_num = 0, x_iter = xceptions.begin(); x_iter != xceptions.end();
++x_iter, ++exc_num) {
f_service_ << indent() << "except " << type_name((*x_iter)->get_type())
<< " as exc" << exc_num << ":" << endl;
if (tfunction->qualifier() != t_function_qualifier::one_way) {
indent_up();
f_service_ << indent()
<< "self._event_handler.handlerException(handler_ctx, '"
<< fn_name << "', exc" << exc_num << ")" << endl
<< indent() << "result."
<< rename_reserved_keywords((*x_iter)->get_name())
<< " = exc" << exc_num << endl;
indent_down();
} else {
f_service_ << indent() << "pass" << endl;
}
}
f_service_ << indent() << "except:" << endl
<< indent() << " ex = sys.exc_info()[1]" << endl
<< indent()
<< " self._event_handler.handlerError(handler_ctx, '" << fn_name
<< "', ex)" << endl
<< indent() << " result = Thrift.TApplicationException(message="
<< "repr(ex))" << endl;
if (tfunction->qualifier() != t_function_qualifier::one_way) {
f_service_ << indent() << "return result" << endl;
}
// Close function
indent_down();
if (future) {
f_service_ << endl;
f_service_ << indent() << "@future_process_method(" << fn_name
<< "_args, oneway="
<< (tfunction->qualifier() == t_function_qualifier::one_way
? "True"
: "False")
<< ")" << endl;
f_service_ << indent() << "def future_process_" << fn_name
<< "(self, args, handler_ctx):" << endl;
indent_up();
f_service_ << indent() << "return self._executor.submit(self.then_"
<< fn_name << ", args, handler_ctx)" << endl;
indent_down();
}
f_service_ << endl;
}
}