|
|
|
@ -70,7 +70,7 @@ static PyObject *metadata_event_kind; |
|
|
|
|
static PyObject *finish_event_kind; |
|
|
|
|
|
|
|
|
|
static PyObject *pygrpc_as_py_time(gpr_timespec *timespec) { |
|
|
|
|
return Py_BuildValue("f", |
|
|
|
|
return PyFloat_FromDouble( |
|
|
|
|
timespec->tv_sec + ((double)timespec->tv_nsec) / 1.0E9); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -116,67 +116,82 @@ static PyObject *pygrpc_status_code(grpc_status_code c_status_code) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static PyObject *pygrpc_stop_event_args(grpc_event *c_event) { |
|
|
|
|
return Py_BuildValue("(OOOOOOO)", stop_event_kind, Py_None, Py_None, Py_None, |
|
|
|
|
Py_None, Py_None, Py_None); |
|
|
|
|
return PyTuple_Pack(7, stop_event_kind, Py_None, Py_None, Py_None, |
|
|
|
|
Py_None, Py_None, Py_None); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static PyObject *pygrpc_write_event_args(grpc_event *c_event) { |
|
|
|
|
PyObject *write_accepted = |
|
|
|
|
c_event->data.write_accepted == GRPC_OP_OK ? Py_True : Py_False; |
|
|
|
|
return Py_BuildValue("(OOOOOOO)", write_event_kind, (PyObject *)c_event->tag, |
|
|
|
|
write_accepted, Py_None, Py_None, Py_None, Py_None); |
|
|
|
|
return PyTuple_Pack(7, write_event_kind, (PyObject *)c_event->tag, |
|
|
|
|
write_accepted, Py_None, Py_None, Py_None, Py_None); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static PyObject *pygrpc_complete_event_args(grpc_event *c_event) { |
|
|
|
|
PyObject *complete_accepted = |
|
|
|
|
c_event->data.finish_accepted == GRPC_OP_OK ? Py_True : Py_False; |
|
|
|
|
return Py_BuildValue("(OOOOOOO)", complete_event_kind, |
|
|
|
|
(PyObject *)c_event->tag, Py_None, complete_accepted, |
|
|
|
|
Py_None, Py_None, Py_None); |
|
|
|
|
return PyTuple_Pack(7, complete_event_kind, (PyObject *)c_event->tag, |
|
|
|
|
Py_None, complete_accepted, Py_None, Py_None, Py_None); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static PyObject *pygrpc_service_event_args(grpc_event *c_event) { |
|
|
|
|
if (c_event->data.server_rpc_new.method == NULL) { |
|
|
|
|
return Py_BuildValue("(OOOOOOO)", service_event_kind, c_event->tag, |
|
|
|
|
Py_None, Py_None, Py_None, Py_None, Py_None); |
|
|
|
|
return PyTuple_Pack(7, service_event_kind, c_event->tag, |
|
|
|
|
Py_None, Py_None, Py_None, Py_None, Py_None); |
|
|
|
|
} else { |
|
|
|
|
PyObject *method = PyBytes_FromString(c_event->data.server_rpc_new.method); |
|
|
|
|
PyObject *host = PyBytes_FromString(c_event->data.server_rpc_new.host); |
|
|
|
|
PyObject *service_deadline = |
|
|
|
|
PyObject *method = NULL; |
|
|
|
|
PyObject *host = NULL; |
|
|
|
|
PyObject *service_deadline = NULL; |
|
|
|
|
Call *call = NULL; |
|
|
|
|
PyObject *service_acceptance = NULL; |
|
|
|
|
PyObject *event_args = NULL; |
|
|
|
|
|
|
|
|
|
method = PyBytes_FromString(c_event->data.server_rpc_new.method); |
|
|
|
|
if (method == NULL) { |
|
|
|
|
goto error; |
|
|
|
|
} |
|
|
|
|
host = PyBytes_FromString(c_event->data.server_rpc_new.host); |
|
|
|
|
if (host == NULL) { |
|
|
|
|
goto error; |
|
|
|
|
} |
|
|
|
|
service_deadline = |
|
|
|
|
pygrpc_as_py_time(&c_event->data.server_rpc_new.deadline); |
|
|
|
|
|
|
|
|
|
Call *call; |
|
|
|
|
PyObject *service_acceptance_args; |
|
|
|
|
PyObject *service_acceptance; |
|
|
|
|
PyObject *event_args; |
|
|
|
|
if (service_deadline == NULL) { |
|
|
|
|
goto error; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
call = PyObject_New(Call, &pygrpc_CallType); |
|
|
|
|
if (call == NULL) { |
|
|
|
|
goto error; |
|
|
|
|
} |
|
|
|
|
call->c_call = c_event->call; |
|
|
|
|
|
|
|
|
|
service_acceptance_args = |
|
|
|
|
Py_BuildValue("(OOOO)", call, method, host, service_deadline); |
|
|
|
|
Py_DECREF(call); |
|
|
|
|
Py_DECREF(method); |
|
|
|
|
Py_DECREF(host); |
|
|
|
|
Py_DECREF(service_deadline); |
|
|
|
|
|
|
|
|
|
service_acceptance = |
|
|
|
|
PyObject_CallObject(service_acceptance_class, service_acceptance_args); |
|
|
|
|
Py_DECREF(service_acceptance_args); |
|
|
|
|
PyObject_CallFunctionObjArgs(service_acceptance_class, call, method, |
|
|
|
|
host, service_deadline, NULL); |
|
|
|
|
if (service_acceptance == NULL) { |
|
|
|
|
goto error; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
event_args = PyTuple_Pack(7, service_event_kind, |
|
|
|
|
(PyObject *)c_event->tag, Py_None, Py_None, |
|
|
|
|
service_acceptance, Py_None, Py_None); |
|
|
|
|
|
|
|
|
|
event_args = Py_BuildValue("(OOOOOOO)", service_event_kind, |
|
|
|
|
(PyObject *)c_event->tag, Py_None, Py_None, |
|
|
|
|
service_acceptance, Py_None, Py_None); |
|
|
|
|
Py_DECREF(service_acceptance); |
|
|
|
|
error: |
|
|
|
|
Py_XDECREF(call); |
|
|
|
|
Py_XDECREF(method); |
|
|
|
|
Py_XDECREF(host); |
|
|
|
|
Py_XDECREF(service_deadline); |
|
|
|
|
|
|
|
|
|
return event_args; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static PyObject *pygrpc_read_event_args(grpc_event *c_event) { |
|
|
|
|
if (c_event->data.read == NULL) { |
|
|
|
|
return Py_BuildValue("(OOOOOOO)", read_event_kind, |
|
|
|
|
(PyObject *)c_event->tag, Py_None, Py_None, Py_None, |
|
|
|
|
Py_None, Py_None); |
|
|
|
|
return PyTuple_Pack(7, read_event_kind, (PyObject *)c_event->tag, |
|
|
|
|
Py_None, Py_None, Py_None, Py_None, Py_None); |
|
|
|
|
} else { |
|
|
|
|
size_t length; |
|
|
|
|
size_t offset; |
|
|
|
@ -198,9 +213,11 @@ static PyObject *pygrpc_read_event_args(grpc_event *c_event) { |
|
|
|
|
grpc_byte_buffer_reader_destroy(reader); |
|
|
|
|
bytes = PyBytes_FromStringAndSize(c_bytes, length); |
|
|
|
|
gpr_free(c_bytes); |
|
|
|
|
event_args = |
|
|
|
|
Py_BuildValue("(OOOOOOO)", read_event_kind, (PyObject *)c_event->tag, |
|
|
|
|
Py_None, Py_None, Py_None, bytes, Py_None); |
|
|
|
|
if (bytes == NULL) { |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
event_args = PyTuple_Pack(7, read_event_kind, (PyObject *)c_event->tag, |
|
|
|
|
Py_None, Py_None, Py_None, bytes, Py_None); |
|
|
|
|
Py_DECREF(bytes); |
|
|
|
|
return event_args; |
|
|
|
|
} |
|
|
|
@ -208,15 +225,13 @@ static PyObject *pygrpc_read_event_args(grpc_event *c_event) { |
|
|
|
|
|
|
|
|
|
static PyObject *pygrpc_metadata_event_args(grpc_event *c_event) { |
|
|
|
|
/* TODO(nathaniel): Actual transmission of metadata. */ |
|
|
|
|
return Py_BuildValue("(OOOOOOO)", metadata_event_kind, |
|
|
|
|
(PyObject *)c_event->tag, Py_None, Py_None, Py_None, |
|
|
|
|
Py_None, Py_None); |
|
|
|
|
return PyTuple_Pack(7, metadata_event_kind, (PyObject *)c_event->tag, |
|
|
|
|
Py_None, Py_None, Py_None, Py_None, Py_None); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static PyObject *pygrpc_finished_event_args(grpc_event *c_event) { |
|
|
|
|
PyObject *code; |
|
|
|
|
PyObject *details; |
|
|
|
|
PyObject *status_args; |
|
|
|
|
PyObject *status; |
|
|
|
|
PyObject *event_args; |
|
|
|
|
|
|
|
|
@ -230,19 +245,26 @@ static PyObject *pygrpc_finished_event_args(grpc_event *c_event) { |
|
|
|
|
} else { |
|
|
|
|
details = PyBytes_FromString(c_event->data.finished.details); |
|
|
|
|
} |
|
|
|
|
status_args = Py_BuildValue("(OO)", code, details); |
|
|
|
|
if (details == NULL) { |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
status = PyObject_CallFunctionObjArgs(status_class, code, details, NULL); |
|
|
|
|
Py_DECREF(details); |
|
|
|
|
status = PyObject_CallObject(status_class, status_args); |
|
|
|
|
Py_DECREF(status_args); |
|
|
|
|
event_args = |
|
|
|
|
Py_BuildValue("(OOOOOOO)", finish_event_kind, (PyObject *)c_event->tag, |
|
|
|
|
Py_None, Py_None, Py_None, Py_None, status); |
|
|
|
|
if (status == NULL) { |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
event_args = PyTuple_Pack(7, finish_event_kind, (PyObject *)c_event->tag, |
|
|
|
|
Py_None, Py_None, Py_None, Py_None, status); |
|
|
|
|
Py_DECREF(status); |
|
|
|
|
return event_args; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int pygrpc_completion_queue_init(CompletionQueue *self, PyObject *args, |
|
|
|
|
PyObject *kwds) { |
|
|
|
|
static char *kwlist[] = {NULL}; |
|
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, ":CompletionQueue", kwlist)) { |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
self->c_completion_queue = grpc_completion_queue_create(); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
@ -262,7 +284,7 @@ static PyObject *pygrpc_completion_queue_get(CompletionQueue *self, |
|
|
|
|
PyObject *event_args; |
|
|
|
|
PyObject *event; |
|
|
|
|
|
|
|
|
|
if (!(PyArg_ParseTuple(args, "O", &deadline))) { |
|
|
|
|
if (!(PyArg_ParseTuple(args, "O:get", &deadline))) { |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -270,6 +292,9 @@ static PyObject *pygrpc_completion_queue_get(CompletionQueue *self, |
|
|
|
|
deadline_timespec = gpr_inf_future; |
|
|
|
|
} else { |
|
|
|
|
double_deadline = PyFloat_AsDouble(deadline); |
|
|
|
|
if (PyErr_Occurred()) { |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
deadline_timespec = gpr_time_from_nanos((long)(double_deadline * 1.0E9)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -339,7 +364,7 @@ static PyMethodDef methods[] = { |
|
|
|
|
{NULL}}; |
|
|
|
|
|
|
|
|
|
PyTypeObject pygrpc_CompletionQueueType = { |
|
|
|
|
PyObject_HEAD_INIT(NULL)0, /*ob_size*/ |
|
|
|
|
PyVarObject_HEAD_INIT(NULL, 0) |
|
|
|
|
"_gprc.CompletionQueue", /*tp_name*/ |
|
|
|
|
sizeof(CompletionQueue), /*tp_basicsize*/ |
|
|
|
|
0, /*tp_itemsize*/ |
|
|
|
@ -375,6 +400,8 @@ PyTypeObject pygrpc_CompletionQueueType = { |
|
|
|
|
0, /* tp_descr_set */ |
|
|
|
|
0, /* tp_dictoffset */ |
|
|
|
|
(initproc)pygrpc_completion_queue_init, /* tp_init */ |
|
|
|
|
0, /* tp_alloc */ |
|
|
|
|
PyType_GenericNew, /* tp_new */ |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static int pygrpc_get_status_codes(PyObject *datatypes_module) { |
|
|
|
@ -503,7 +530,6 @@ int pygrpc_add_completion_queue(PyObject *module) { |
|
|
|
|
char *datatypes_module_path = "grpc._adapter._datatypes"; |
|
|
|
|
PyObject *datatypes_module = PyImport_ImportModule(datatypes_module_path); |
|
|
|
|
if (datatypes_module == NULL) { |
|
|
|
|
PyErr_SetString(PyExc_ImportError, datatypes_module_path); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
status_class = PyObject_GetAttrString(datatypes_module, "Status"); |
|
|
|
@ -512,29 +538,21 @@ int pygrpc_add_completion_queue(PyObject *module) { |
|
|
|
|
event_class = PyObject_GetAttrString(datatypes_module, "Event"); |
|
|
|
|
if (status_class == NULL || service_acceptance_class == NULL || |
|
|
|
|
event_class == NULL) { |
|
|
|
|
PyErr_SetString(PyExc_ImportError, "Missing classes in _datatypes module!"); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
if (pygrpc_get_status_codes(datatypes_module) == -1) { |
|
|
|
|
PyErr_SetString(PyExc_ImportError, "Status codes import broken!"); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
if (pygrpc_get_event_kinds(event_class) == -1) { |
|
|
|
|
PyErr_SetString(PyExc_ImportError, "Event kinds import broken!"); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
Py_DECREF(datatypes_module); |
|
|
|
|
|
|
|
|
|
pygrpc_CompletionQueueType.tp_new = PyType_GenericNew; |
|
|
|
|
if (PyType_Ready(&pygrpc_CompletionQueueType) < 0) { |
|
|
|
|
PyErr_SetString(PyExc_RuntimeError, |
|
|
|
|
"Error defining pygrpc_CompletionQueueType!"); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
if (PyModule_AddObject(module, "CompletionQueue", |
|
|
|
|
(PyObject *)&pygrpc_CompletionQueueType) == -1) { |
|
|
|
|
PyErr_SetString(PyExc_ImportError, |
|
|
|
|
"Couldn't add CompletionQueue type to module!"); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|