Skip to content
Browse files

Fix process greenelt

  • Loading branch information...
1 parent 40b48ae commit b95ec114f8132be984af777b908d6ec48f9da0b2 @mopemope committed
View
3 example/chat/chatdemo.py
@@ -38,7 +38,7 @@ def message_update():
waiters.remove(c)
raise
-
+ print("suspend->resume %s" % c)
assert cursor != cache[-1]['id'], cursor
try:
for index, m in enumerate(cache):
@@ -66,6 +66,7 @@ def message_new():
for c in waiters:
c.resume()
+ print("resume %s" % c)
waiters = []
return jsonify(msg)
View
2 example/django_chat/chat/views.py
@@ -43,7 +43,7 @@ def message_updates(self, request):
try:
c.suspend(60)
except:
- self,waiters.remove(c)
+ self.waiters.remove(c)
raise
assert cursor != self.cache[-1]['id'], cursor
View
1 example/django_chat/settings.py
@@ -23,7 +23,6 @@
'django.template.loaders.app_directories.load_template_source',
)
MIDDLEWARE_CLASSES = (
- 'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
)
ROOT_URLCONF = 'django_chat.urls'
View
2 meinheld/server/client.c
@@ -80,7 +80,7 @@ ClientObject_New(client_t* client)
o->args = NULL;
o->kwargs = NULL;
o->suspended = 0;
- o->resumed = 0;
+ /* o->resumed = 0; */
GDEBUG("ClientObject_New pyclient:%p client:%p fd:%d", o, o->client, o->client->fd);
return (PyObject *)o;
View
2 meinheld/server/client.h
@@ -45,7 +45,7 @@ typedef struct {
PyObject *args; //greenlet.switch value
PyObject *kwargs; //greenlet.switch value
uint8_t suspended;
- uint8_t resumed;
+ //uint8_t resumed;
} ClientObject;
extern PyTypeObject ClientObjectType;
View
8 meinheld/server/http_request_parser.c
@@ -232,7 +232,7 @@ set_query(PyObject *env, char *buf, int len)
if(slen > 1){
obj = PyBytes_FromStringAndSize(s0, slen -1);
- DEBUG("query:%.*s", len, PyBytes_AS_STRING(obj));
+ /* DEBUG("query:%.*s", len, PyBytes_AS_STRING(obj)); */
if(unlikely(obj == NULL)){
return -1;
}
@@ -293,7 +293,7 @@ set_path(PyObject *env, char *buf, int len)
slen = urldecode(s0, slen);
obj = PyBytes_FromStringAndSize(s0, slen);
- DEBUG("path:%.*s", (int)slen, PyBytes_AS_STRING(obj));
+ /* DEBUG("path:%.*s", (int)slen, PyBytes_AS_STRING(obj)); */
if(likely(obj != NULL)){
#ifdef PY3
@@ -427,7 +427,7 @@ header_field_cb(http_parser *p, const char *buf, size_t len)
request *req = client->req;
PyObject *env = NULL, *obj;
- DEBUG("field key:%.*s", (int)len, buf);
+ /* DEBUG("field key:%.*s", (int)len, buf); */
if(req->last_header_element != FIELD){
env = req->env;
@@ -483,7 +483,7 @@ header_value_cb(http_parser *p, const char *buf, size_t len)
request *req = client->req;
PyObject *obj;
- DEBUG("field value:%.*s", (int)len, buf);
+ /* DEBUG("field value:%.*s", (int)len, buf); */
if(likely(req->value== NULL)){
obj = PyBytes_FromStringAndSize(buf, len);
}else{
View
25 meinheld/server/response.c
@@ -214,6 +214,20 @@ add_header(write_bucket *bucket, char *key, size_t keylen, char *val, size_t val
set2bucket(bucket, CRLF, 2);
}
+#ifdef DEVELOP
+static void
+writev_log(write_bucket *data)
+{
+ int i = 0;
+ char *c;
+ size_t len;
+ for(; i < data->iov_cnt; i++){
+ c = data->iov[i].iov_base;
+ len = data->iov[i].iov_len;
+ printf("%.*s", (int)len, c);
+ }
+}
+#endif
static response_status
writev_bucket(write_bucket *data)
@@ -221,6 +235,12 @@ writev_bucket(write_bucket *data)
size_t w;
int i = 0;
Py_BEGIN_ALLOW_THREADS
+#ifdef DEVELOP
+ RDEBUG("writev_bucket");
+ printf("\x1B[34m");
+ writev_log(data);
+ printf("\x1B[0m");
+#endif
w = writev(data->fd, data->iov, data->iov_cnt);
Py_END_ALLOW_THREADS
if(w == -1){
@@ -408,6 +428,7 @@ add_status_line(write_bucket *bucket, client_t *client)
object = client->http_status;
//TODO ERROR CHECK
if(object){
+ DEBUG("add_status_line client %p", client);
PyBytes_AsStringAndSize(object, &value, &valuelen);
//write status code
@@ -416,6 +437,8 @@ add_status_line(write_bucket *bucket, client_t *client)
add_header(bucket, "Server", 6, SERVER, sizeof(SERVER) -1);
cache_time_update();
add_header(bucket, "Date", 4, (char *)http_time, 29);
+ }else{
+ DEBUG("missing status_line %p", client);
}
return 1;
}
@@ -964,6 +987,8 @@ ResponseObject_call(PyObject *obj, PyObject *args, PyObject *kw)
}else{
self->cli->http_status = PyBytes_FromFormat("HTTP/1.0 %s\r\n", PyBytes_AS_STRING(bytes));
}
+
+ DEBUG("set http_status %p", self->cli);
Py_XDECREF(bytes);
Py_RETURN_NONE;
}
View
96 meinheld/server/server.c
@@ -84,8 +84,10 @@ static int client_numfree = 0;
static void
read_callback(picoev_loop* loop, int fd, int events, void* cb_arg);
+#ifndef WITH_GREENLET
static void
write_callback(picoev_loop* loop, int fd, int events, void* cb_arg);
+#endif
static void
trampoline_callback(picoev_loop* loop, int fd, int events, void* cb_arg);
@@ -357,10 +359,12 @@ app_handler(PyObject *self, PyObject *args)
if(!start){
return NULL;
}
-
+
+ DEBUG("call wsgi app");
wsgi_args = Py_BuildValue("(OO)", env, start);
res = PyObject_CallObject(wsgi_app, wsgi_args);
Py_DECREF(wsgi_args);
+ DEBUG("called wsgi app");
//check response & PyErr_Occurred
if (res && res == Py_None){
@@ -437,6 +441,35 @@ get_app_handler(void)
}
static void
+resume_wsgi_handler(ClientObject *pyclient)
+{
+ PyObject *res = NULL;
+ PyObject *err_type, *err_val, *err_tb;
+ client_t *old_client;
+ client_t *client = pyclient->client;
+
+ //swap bind client_t
+
+ old_client = start_response->cli;
+ start_response->cli = client;
+
+ current_client = (PyObject *)pyclient;
+ if(PyErr_Occurred()){
+ PyErr_Fetch(&err_type, &err_val, &err_tb);
+ PyErr_Clear();
+ //set error
+ res = greenlet_throw(pyclient->greenlet, err_type, err_val, err_tb);
+ }else{
+ res = greenlet_switch(pyclient->greenlet, pyclient->args, pyclient->kwargs);
+ }
+ start_response->cli = old_client;
+
+ Py_CLEAR(pyclient->args);
+ Py_CLEAR(pyclient->kwargs);
+ Py_XDECREF(res);
+}
+
+static void
call_wsgi_handler(client_t *client)
{
PyObject *handler, *greenlet, *args, *res;
@@ -549,7 +582,7 @@ switch_wsgi_app(picoev_loop* loop, int fd, PyObject *obj)
pyclient->resumed = 0;
}*/
-
+/*
static void
resume_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
{
@@ -563,26 +596,22 @@ resume_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
}
//switch_wsgi_app(loop, client->fd, (PyObject *)pyclient);
}
+*/
static void
-timeout_erroread_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
+timeout_error_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
{
ClientObject *pyclient = (ClientObject *)(cb_arg);
client_t *client = pyclient->client;
- PyObject *res, *err_type, *err_val, *err_tb;
if ((events & PICOEV_TIMEOUT) != 0) {
- DEBUG("timeout_erroread_callback pyclient:%p client:%p fd:%d", pyclient, pyclient->client, pyclient->client->fd);
+ DEBUG("timeout_error_callback pyclient:%p client:%p fd:%d", pyclient, pyclient->client, pyclient->client->fd);
picoev_del(loop, fd);
pyclient->suspended = 0;
- pyclient->resumed = 1;
+ /* pyclient->resumed = 1; */
PyErr_SetString(timeout_error, "timeout");
set_so_keepalive(client->fd, 0);
- PyErr_Fetch(&err_type, &err_val, &err_tb);
- PyErr_Clear();
- res = greenlet_throw(pyclient->greenlet, err_type, err_val, err_tb);
- Py_XDECREF(res);
- //switch_wsgi_app(loop, client->fd, (PyObject *)pyclient);
+ resume_wsgi_handler(pyclient);
}
}
@@ -591,7 +620,6 @@ timeout_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
{
ClientObject *pyclient = (ClientObject *)(cb_arg);
client_t *client = pyclient->client;
- PyObject *res, *err_type, *err_val, *err_tb;
if ((events & PICOEV_TIMEOUT) != 0) {
DEBUG("timeout_callback pyclient:%p client:%p fd:%d", pyclient, pyclient->client, pyclient->client->fd);
@@ -602,15 +630,11 @@ timeout_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
picoev_del(loop, fd);
//resume
pyclient->suspended = 0;
- pyclient->resumed = 1;
+ /* pyclient->resumed = 1; */
PyErr_SetFromErrno(PyExc_IOError);
DEBUG("closed");
set_so_keepalive(client->fd, 0);
- PyErr_Fetch(&err_type, &err_val, &err_tb);
- PyErr_Clear();
- res = greenlet_throw(pyclient->greenlet, err_type, err_val, err_tb);
- Py_XDECREF(res);
- //switch_wsgi_app(loop, client->fd, (PyObject *)pyclient);
+ resume_wsgi_handler(pyclient);
}
}
}
@@ -621,27 +645,20 @@ trampoline_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
{
ClientObject *pyclient = (ClientObject*)cb_arg;
client_t *client = pyclient->client;
- PyObject *res, *err_type, *err_val, *err_tb;
picoev_del(loop, fd);
- DEBUG("call trampoline_callback");
+ RDEBUG("call trampoline_callback pyclient %p", pyclient);
if ((events & PICOEV_TIMEOUT) != 0) {
- DEBUG("** trampoline_callback timeout **");
-
+ RDEBUG("** trampoline_callback timeout **");
//timeout
client->keep_alive = 0;
PyErr_SetString(timeout_error, "timeout");
- PyErr_Fetch(&err_type, &err_val, &err_tb);
- PyErr_Clear();
- res = greenlet_throw(pyclient->greenlet, err_type, err_val, err_tb);
- //close_conn(client, loop);
- }else{
- res = greenlet_switch(pyclient->greenlet, pyclient->args, pyclient->kwargs);
}
- Py_XDECREF(res);
+ resume_wsgi_handler(pyclient);
}
+#ifndef WITH_GREENLET
static void
write_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
{
@@ -668,6 +685,7 @@ write_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
}
}
}
+#endif
/*
static void
@@ -1727,26 +1745,28 @@ meinheld_suspend_client(PyObject *self, PyObject *args)
PyErr_SetString(PyExc_ValueError, "greenlet is not set");
return NULL;
}
-
+
+ /*
if(pyclient->resumed == 1){
//call later
PyErr_SetString(PyExc_IOError, "not called resume");
return NULL;
}
+ */
if(client && !(pyclient->suspended)){
pyclient->suspended = 1;
parent = greenlet_getparent(pyclient->greenlet);
set_so_keepalive(client->fd, 1);
- DEBUG("meinheld_suspend_client pyclient:%p client:%p fd:%d", pyclient, client, client->fd);
- DEBUG("meinheld_suspend_client active ? %d", picoev_is_active(main_loop, client->fd));
+ RDEBUG("meinheld_suspend_client pyclient:%p client:%p fd:%d", pyclient, client, client->fd);
+ RDEBUG("meinheld_suspend_client active ? %d", picoev_is_active(main_loop, client->fd));
//clear event
picoev_del(main_loop, client->fd);
if(timeout > 0){
- picoev_add(main_loop, client->fd, PICOEV_TIMEOUT, timeout, timeout_erroread_callback, (void *)pyclient);
+ picoev_add(main_loop, client->fd, PICOEV_TIMEOUT, timeout, timeout_error_callback, (void *)pyclient);
}else{
- picoev_add(main_loop, client->fd, PICOEV_TIMEOUT, 300, timeout_callback, (void *)pyclient);
+ picoev_add(main_loop, client->fd, PICOEV_TIMEOUT, 3, timeout_callback, (void *)pyclient);
}
return greenlet_switch(parent, hub_switch_value, NULL);
}else{
@@ -1790,7 +1810,7 @@ meinheld_resume_client(PyObject *self, PyObject *args)
return NULL;
}
- if(pyclient->client && !pyclient->resumed){
+ if(pyclient->client && pyclient->suspended){
set_so_keepalive(pyclient->client->fd, 0);
pyclient->args = switch_args;
Py_XINCREF(pyclient->args);
@@ -1799,12 +1819,12 @@ meinheld_resume_client(PyObject *self, PyObject *args)
Py_XINCREF(pyclient->kwargs);
pyclient->suspended = 0;
- pyclient->resumed = 1;
- DEBUG("meinheld_resume_client pyclient:%p client:%p fd:%d \n", pyclient, pyclient->client, pyclient->client->fd);
+ /* pyclient->resumed = 1; */
+ DEBUG("meinheld_resume_client pyclient:%p client:%p fd:%d", pyclient, pyclient->client, pyclient->client->fd);
DEBUG("meinheld_resume_client active ? %d", picoev_is_active(main_loop, pyclient->client->fd));
//clear event
picoev_del(main_loop, client->fd);
- picoev_add(main_loop, client->fd, PICOEV_WRITE, 0, resume_callback, (void *)pyclient);
+ picoev_add(main_loop, client->fd, PICOEV_WRITE, 0, trampoline_callback, (void *)pyclient);
}else{
PyErr_SetString(PyExc_Exception, "already resumed");
return NULL;

0 comments on commit b95ec11

Please sign in to comment.
Something went wrong with that request. Please try again.