attempt to merge #726

This commit is contained in:
Unbit
2014-09-23 12:07:15 +02:00
8 changed files with 148 additions and 14 deletions
@@ -2,9 +2,10 @@
socket = /tmp/temporary_socket
; Spooler!
spooler-import = %d/spooler_handler.py
spooler-import = %d/spooler_handlers.py
; Specify the spooler
spooler = %d/temporary_spooler
spooler = $(SPOOLER_DIR)
; And the number of processes
spooler-processes = 1
; Spooler ordered scanning (only works with "numbered" dirs)
@@ -12,6 +13,6 @@ spooler-ordered = 1
; Spooler frequency
spooler-frequency = 1
pyrun = %d/spooler.py
pyrun = %d/spooler_decorator_tests.py
master = 1
@@ -0,0 +1,31 @@
# run it with:
# export SPOOLER_DIR=t/python/spooler_priority/temporary_spooler; # or your spooler dir
# ./uwsgi t/python/spooler_decorators/spooler_decorator_test.ini
import unittest
import uwsgi
import spooler_handlers
from os import remove, path
class BitmapTest(unittest.TestCase):
def setUp(self):
try:
remove(spooler_handlers.ghostpath)
except OSError: # file does not exist
pass
spooler_handlers.controlled_task.spool(arg='alive', ghost='world')
spooler_handlers.controlled_task.spool(arg='barbis')
spooler_handlers.controlled_raw_task.spool(arg='alive', ghost='world')
spooler_handlers.controlled_raw_task.spool(arg='barbis')
for i in range(4):
uwsgi.signal_wait(20)
print("Signal received!")
def test_spooler(self):
self.assertFalse(path.exists(spooler_handlers.ghostpath))
unittest.main()
@@ -0,0 +1,23 @@
# See spooler_decorator_tests
from uwsgidecorators import *
import uwsgi
ghostpath = "/tmp/ghost"
@spool
def controlled_task(arguments):
if arguments['arg'] != 'alive' and 'ghost' in arguments:
print("We have a problem!")
open(ghostpath, 'w').close()
uwsgi.signal(20)
@spoolraw
def controlled_raw_task(arguments):
if arguments['arg'] != 'alive' and 'ghost' in arguments:
print("We have a problem!")
open(ghostpath, 'w').close()
uwsgi.signal(20)
return uwsgi.SPOOL_OK
@@ -0,0 +1,33 @@
#! /usr/bin/env python
# coding = utf-8
from __future__ import print_function
from constants import tasks, LOGFILE
from os import remove
import uwsgi
counter = 0
def spoolerHandler(env):
global counter
# Spooler is handling a task
with open(LOGFILE, "a") as log:
print("%s" % (env['name']), file=log)
counter += 1
if counter == len(tasks):
# Each task has been processed.
uwsgi.signal(17)
# Spooler has done handling the task
return uwsgi.SPOOL_OK
uwsgi.spooler = spoolerHandler
# Clear the logfile
try:
remove(LOGFILE)
except OSError, e: # log does not exist
print(e)
@@ -0,0 +1,17 @@
[uwsgi]
socket = /tmp/temporary-socket
; Specify the spooler
spooler = %d/temporary_spooler
; Spooler handler
spooler-import = %d/spooler_priority_handler.py
; And the number of processes
spooler-processes = 1
; Spooler ordered scanning (only works with "numbered" dirs)
spooler-ordered = 1
; Spooler scans folder each second
spooler-frequency = 1
pyrun = %d/spooler_priority_test.py
master = 1
@@ -1,4 +1,4 @@
#! /usr/bin/env python2
#! /usr/bin/env python
# coding = utf-8
import uwsgi
@@ -7,8 +7,7 @@ import os
import fcntl
from shutil import rmtree
import time
import constants
from signal import *
import spooler_priority_constants
def spoolersTaskList():
@@ -62,8 +61,7 @@ def cleanTasks():
class BitmapTest(unittest.TestCase):
def setUp(self):
self.addCleanup(cleanTasks)
for priority, name in constants.tasks:
for priority, name in spooler_priority_constants.tasks:
task = {'name': name, 'at': int(time.time() + 10)}
if priority is not None:
task['priority'] = str(priority)
@@ -73,10 +71,10 @@ class BitmapTest(unittest.TestCase):
uwsgi.signal_wait(17)
print("Signal received.")
with open(constants.LOGFILE, "r") as log:
with open(spooler_priority_constants.LOGFILE, "r") as log:
# Check logging ordering.
loglines = [line.rstrip() for line in log]
self.assertEqual(loglines, constants.ordered_tasks)
self.assertEqual(loglines, spooler_priority_constants.ordered_tasks)
signal(SIGINT, cleanTasks)
unittest.main()
+35 -4
View File
@@ -18,6 +18,29 @@ mule_functions = {}
postfork_chain = []
# Python3 compatibility
def _encode1(val):
if sys.version_info >= (3, 0) and isinstance(val, str):
return val.encode('utf-8')
else:
return val
def _decode1(val):
if sys.version_info >= (3, 0) and isinstance(val, bytes):
return val.decode('utf-8')
else:
return val
def _encode_to_spooler(vars):
return dict((_encode1(K), _encode1(V)) for (K, V) in vars.items())
def _decode_from_spooler(vars):
return dict((_decode1(K), _decode1(V)) for (K, V) in vars.items())
def get_free_signal():
for signum in range(0, 256):
if not uwsgi.signal_registered(signum):
@@ -27,6 +50,7 @@ def get_free_signal():
def manage_spool_request(vars):
vars = _decode_from_spooler(vars)
f = spooler_functions[vars['ud_spool_func']]
if 'args' in vars:
args = pickle.loads(vars.pop('args'))
@@ -48,6 +72,7 @@ uwsgi.post_fork_hook = postfork_chain_hook
class postfork(object):
def __init__(self, f):
if callable(f):
self.wid = 0
@@ -56,6 +81,7 @@ class postfork(object):
self.f = None
self.wid = f
postfork_chain.append(self)
def __call__(self, *args, **kwargs):
if self.f:
if self.wid > 0 and self.wid != uwsgi.worker_id():
@@ -67,7 +93,7 @@ class postfork(object):
class _spoolraw(object):
def __call__(self, *args, **kwargs):
arguments = self.base_dict
arguments = self.base_dict.copy()
if not self.pass_arguments:
if len(args) > 0:
arguments.update(args[0])
@@ -79,8 +105,9 @@ class _spoolraw(object):
if key in kwargs:
spooler_args.update({key: kwargs.pop(key)})
arguments.update(spooler_args)
arguments.update({'args': pickle.dumps(args), 'kwargs': pickle.dumps(kwargs)})
return uwsgi.spool(arguments)
arguments.update(
{'args': pickle.dumps(args), 'kwargs': pickle.dumps(kwargs)})
return uwsgi.spool(_encode_to_spooler(arguments))
# For backward compatibility (uWSGI < 1.9.13)
def spool(self, *args, **kwargs):
@@ -234,6 +261,7 @@ class mule_brainloop(mule_brain):
class mule(object):
def __init__(self, num):
self.num = num
@@ -242,6 +270,7 @@ class mule(object):
class muleloop(mule):
def __call__(self, f):
postfork_chain.append(mule_brainloop(f, self.num))
@@ -261,6 +290,7 @@ class mulemsg_loop(object):
class mulemsg(object):
def __init__(self, num):
self.num = num
@@ -306,7 +336,7 @@ class cron(object):
def __call__(self, f):
uwsgi.register_signal(self.num, self.target, f)
uwsgi.add_cron(self.num, self.minute, self.hour,
self.day, self.month, self.dayweek)
self.day, self.month, self.dayweek)
return f
@@ -347,6 +377,7 @@ class erlang(object):
class lock(object):
def __init__(self, f):
self.f = f