Skip to content

Commit

Permalink
new option --import, new api function uwsgi.signal_registered
Browse files Browse the repository at this point in the history
  • Loading branch information
roberto@sirius committed Jul 1, 2011
1 parent 19c567c commit 750bbd6
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 10 deletions.
31 changes: 27 additions & 4 deletions decoratortest.py
@@ -1,28 +1,51 @@
import uwsgi
from uwsgidecorators import *

from uwsgicc import app as application

import time


# register rpc function helloworld
@rpc("helloworld")
def hello_world():
return "Hello World"

# register signal 1
@signal(1)
def what_time_is_it(num):
print(time.asctime())


@timer(2, 3)
# a 3 seconds timer
@timer(3)
def salut(num):
print("Salut !!! 3 seconds elapsed and signal %d raised" % num)

@rbtimer(3, 10)
# a 10 seconds red black timer
@rbtimer(10)
def tenseconds(num):
print("red black timer !!! 10 seconds elapsed and signal %d raised" % num)

@filemon(4, "/tmp")
# monitor /tmp directory
@filemon("/tmp")
def tmpmodified(num):
print("/tmp has been modified")


# spool a long running task
@spool
def a_long_task(vars):
for i in xrange(1,10):
print(i)
time.sleep(1)

# continuosly spool a long task
@spool
def an_infinite_task(vars):
for i in xrange(1,4):
print("infinite: %d" % i)
time.sleep(1)


a_long_task.spool(foo='bar')
an_infinite_task.spool(foo='bar')
19 changes: 19 additions & 0 deletions plugins/python/python_plugin.c
Expand Up @@ -21,6 +21,10 @@ struct option uwsgi_python_options[] = {
{"pythonpath", required_argument, 0, LONG_ARGS_PYTHONPATH},
{"python-path", required_argument, 0, LONG_ARGS_PYTHONPATH},
{"pymodule-alias", required_argument, 0, LONG_ARGS_PYMODULE_ALIAS},
{"import", required_argument, 0, LONG_ARGS_PYIMPORT},
{"pyimport", required_argument, 0, LONG_ARGS_PYIMPORT},
{"py-import", required_argument, 0, LONG_ARGS_PYIMPORT},
{"python-import", required_argument, 0, LONG_ARGS_PYIMPORT},
{"pp", required_argument, 0, LONG_ARGS_PYTHONPATH},
{"pyargv", required_argument, 0, LONG_ARGS_PYARGV},
{"optimize", required_argument, 0, 'O'},
Expand Down Expand Up @@ -720,6 +724,9 @@ int uwsgi_python_manage_options(int i, char *optarg) {
uwsgi_log("you can specify at most %d --pymodule-alias options\n", MAX_PYMODULE_ALIAS);
}
return 1;
case LONG_ARGS_PYIMPORT:
uwsgi_string_new_list(&up.import_list, optarg);
return 1;
case LONG_ARGS_PYTHONPATH:
if (glob(optarg, GLOB_MARK, NULL, &g)) {
uwsgi_string_new_list(&up.python_path, optarg);
Expand Down Expand Up @@ -813,6 +820,18 @@ void uwsgi_python_init_apps() {
up.loaders[LOADER_CALLABLE] = uwsgi_callable_loader;
up.loaders[LOADER_STRING_CALLABLE] = uwsgi_string_callable_loader;

struct uwsgi_string_list *upli = up.import_list;
while(upli) {
if (strchr(upli->value, '/') || uwsgi_endswith(upli->value, ".py")) {
uwsgi_pyimport_by_filename("uwsgi_imported_file", upli->value);
}
else {
if (PyImport_ImportModule(upli->value) == NULL) {
PyErr_Print();
}
}
upli = upli->next;
}

if (up.wsgi_config != NULL) {
init_uwsgi_app(LOADER_UWSGI, up.wsgi_config, uwsgi.wsgi_req, up.main_thread);
Expand Down
17 changes: 17 additions & 0 deletions plugins/python/uwsgi_pymodule.c
Expand Up @@ -460,6 +460,22 @@ PyObject *py_uwsgi_attach_daemon(PyObject * self, PyObject * args) {
return Py_True;
}

PyObject *py_uwsgi_signal_registered(PyObject * self, PyObject * args) {
uint8_t uwsgi_signal;

if (!PyArg_ParseTuple(args, "B:signal_registered", &uwsgi_signal)) {
return NULL;
}

if (uwsgi_signal_registered(uwsgi_signal)) {
Py_INCREF(Py_True);
return Py_True;
}

Py_INCREF(Py_None);
return Py_None;
}

PyObject *py_uwsgi_register_signal(PyObject * self, PyObject * args) {

uint8_t uwsgi_signal;
Expand Down Expand Up @@ -2393,6 +2409,7 @@ static PyMethodDef uwsgi_advanced_methods[] = {
{"register_signal", py_uwsgi_register_signal, METH_VARARGS, ""},
{"signal", py_uwsgi_signal, METH_VARARGS, ""},
{"signal_wait", py_uwsgi_signal_wait, METH_VARARGS, ""},
{"signal_registered", py_uwsgi_signal_registered, METH_VARARGS, ""},
{"signal_received", py_uwsgi_signal_received, METH_VARARGS, ""},
{"add_file_monitor", py_uwsgi_add_file_monitor, METH_VARARGS, ""},
{"add_timer", py_uwsgi_add_timer, METH_VARARGS, ""},
Expand Down
2 changes: 2 additions & 0 deletions plugins/python/uwsgi_python.h
Expand Up @@ -13,6 +13,7 @@
#define LONG_ARGS_PYARGV LONG_ARGS_PYTHON_BASE + 3
#define LONG_ARGS_PYMODULE_ALIAS LONG_ARGS_PYTHON_BASE + 4
#define LONG_ARGS_RELOAD_OS_ENV LONG_ARGS_PYTHON_BASE + 5
#define LONG_ARGS_PYIMPORT LONG_ARGS_PYTHON_BASE + 6

#if PY_MINOR_VERSION == 4 && PY_MAJOR_VERSION == 2
#define Py_ssize_t ssize_t
Expand Down Expand Up @@ -99,6 +100,7 @@ struct uwsgi_python {
char *test_module;

struct uwsgi_string_list *python_path;
struct uwsgi_string_list *import_list;

PyObject *loader_dict;
PyObject* (*loaders[LOADER_MAX]) (void *);
Expand Down
8 changes: 8 additions & 0 deletions signal.c
Expand Up @@ -15,6 +15,14 @@ int uwsgi_signal_handler(uint8_t sig) {
return uwsgi.p[use->modifier1]->signal_handler(sig, use->handler);
}

int uwsgi_signal_registered(uint8_t sig) {

if (uwsgi.shared->signal_table[sig].handler != NULL)
return 1;

return 0;
}

int uwsgi_register_signal(uint8_t sig, char *receiver, void *handler, uint8_t modifier1) {

struct uwsgi_signal_entry *use = NULL;
Expand Down
19 changes: 19 additions & 0 deletions utils.c
Expand Up @@ -2434,3 +2434,22 @@ int *uwsgi_attach_fd(int fd, int count, char *code, size_t code_len) {

return ret;
}

int uwsgi_endswith(char *str1, char *str2) {

size_t i;
size_t str1len = strlen(str1);
size_t str2len = strlen(str2);
char *ptr;

if (str2len > str1len) return 0;

ptr = (str1 + str1len) - str2len;

for(i=0;i<str2len;i++) {
if (*ptr != str2[i]) return 0;
ptr++;
}

return 1;
}
4 changes: 4 additions & 0 deletions uwsgi.h
Expand Up @@ -2060,3 +2060,7 @@ int *uwsgi_attach_fd(int, int, char *, size_t);

int uwsgi_count_sockets(struct uwsgi_socket *);
int uwsgi_file_exists(char *);

int uwsgi_signal_registered(uint8_t);

int uwsgi_endswith(char *, char *);
57 changes: 51 additions & 6 deletions uwsgidecorators.py
Expand Up @@ -6,6 +6,42 @@
if uwsgi.opt.get('lazy'):
raise Exception("uWSGI lazy mode is not supporte by this module")

spooler_functions = {}

def get_free_signal():
for signum in xrange(0, 256):
if not uwsgi.signal_registered(signum):
return signum

raise Exception("No free uwsgi signal available")

def manage_spool_request(vars):
spooler_functions[vars['ud_spool_func']](vars)
return spooler_functions[vars['ud_spool_func']].ret

uwsgi.spooler = manage_spool_request


class spool(object):

def spool(self, *args, **kwargs):
self.f.ret = uwsgi.SPOOL_OK
return uwsgi.spool(ud_spool_func=self.f.__name__)

def __init__(self, f):
if not uwsgi.spooler_pid:
raise Exception("you have to enable the uWSGI spooler to use the @spool decorator")
spooler_functions[f.__name__] = f
f.spool = self.spool
self.f = f

class spoolforever(spool):

def spool(self, *args, **kwargs):
self.f.ret = uwsgi.SPOOL_RETRY
return uwsgi.spool(ud_spool_func=self.f.__name__)


class rpc(object):

def __init__(self, name):
Expand All @@ -26,8 +62,11 @@ def __call__(self, f):

class timer(object):

def __init__(self, num, secs):
self.num = num
def __init__(self, secs, num=None):
if num:
self.num = num
else:
self.num = get_free_signal()
self.secs = secs

def __call__(self, f):
Expand All @@ -37,8 +76,11 @@ def __call__(self, f):

class rbtimer(object):

def __init__(self, num, secs):
self.num = num
def __init__(self, secs, num=None):
if num:
self.num = num
else:
self.num = get_free_signal()
self.secs = secs

def __call__(self, f):
Expand All @@ -48,8 +90,11 @@ def __call__(self, f):

class filemon(object):

def __init__(self, num, fsobj):
self.num = num
def __init__(self, fsobj, num=None):
if num:
self.num = num
else:
self.num = get_free_signal()
self.fsobj = fsobj

def __call__(self, f):
Expand Down

0 comments on commit 750bbd6

Please sign in to comment.