Projet

Général

Profil

0001-improve-generic-timeout-handling-14913.patch

Josué Kouka, 08 février 2017 09:29

Télécharger (4,08 ko)

Voir les différences:

Subject: [PATCH] improve generic timeout handling (#14913)

 mandayejs/mandaye/utils.py | 90 ++++++++++++++++++++++++++--------------------
 tests/settings.py          |  2 +-
 2 files changed, 52 insertions(+), 40 deletions(-)
mandayejs/mandaye/utils.py
16 16
import os
17 17
import re
18 18
import json
19
import signal
19 20
import subprocess
20 21
import logging
21
import multiprocessing
22 22

  
23 23
from django.conf import settings
24 24

  
......
29 29
logger = logging.getLogger(__name__)
30 30

  
31 31

  
32
class Timeout(object):
33

  
34
    class TimeoutError(Exception):
35
        pass
36

  
37
    def __init__(self, timeout):
38
        self.timeout = timeout
39

  
40
    def __enter__(self):
41
        signal.signal(signal.SIGALRM, self.raise_timeout)
42
        signal.alarm(self.timeout)
43

  
44
    def __exit__(self, *args):
45
        signal.alarm(0)
46

  
47
    def raise_timeout(self, *args):
48
        raise Timeout.TimeoutError
49

  
50

  
32 51
def exec_phantom(data, script='do_login.js'):
33 52

  
34
    def run(send_end):
35
        phantom = subprocess.Popen([
36
            settings.PHANTOM_JS_BINARY,
37
            '--ignore-ssl-errors=yes', '--ssl-protocol=any',
38
            os.path.join(settings.BASE_DIR, 'mandayejs', script)],
39
            close_fds=True,
40
            stdin=subprocess.PIPE,
41
            stdout=subprocess.PIPE
42
        )
43
        stdout, stderr = phantom.communicate(json.dumps(data))
44

  
45
        try:
46
            output = re.search('<mandayejs>(.*?)</mandayejs>', stdout, re.DOTALL)
47
            if not output:
48
                raise ValueError
49
            stdout = output.group(1)
50
            result = json.loads(stdout)
51
        except (ValueError,):
52
            result = {"result": "json_error"}
53
            logger.error("invalid json: %s" % stdout)
54

  
55
        if result.get('stderr'):
56
            logger.warning(result['stderr'])
57
        if result.get('error'):
58
            logger.error('Error occured: %s' % result.get('reason'))
59

  
60
        send_end.send(result)
61

  
62
    recv_end, send_end = multiprocessing.Pipe(False)
63
    process = multiprocessing.Process(target=run, args=(send_end,))
64
    process.start()
65
    process.join(settings.PHANTOM_JS_TIMEOUT)
66

  
67
    if process.is_alive():
68
        process.terminate()
53
    phantom = subprocess.Popen([
54
        settings.PHANTOM_JS_BINARY,
55
        '--ignore-ssl-errors=yes', '--ssl-protocol=any',
56
        os.path.join(settings.BASE_DIR, 'mandayejs', script)],
57
        close_fds=True,
58
        stdin=subprocess.PIPE,
59
        stdout=subprocess.PIPE
60
    )
61

  
62
    # terminate subprocess if timeout
63
    try:
64
        with Timeout(settings.PHANTOM_JS_TIMEOUT):
65
            stdout, stderr = phantom.communicate(json.dumps(data))
66
    except (Timeout.TimeoutError,):
69 67
        # Don't log locators, they may contain credentials (passwords)
68
        phantom.terminate()
70 69
        context = {k: v for k, v in data.items() if k != 'locators'}
71 70
        logger.error("PhantomJS process timeout, context: %s" % context)
72
        result = {'result': 'timeout'}
73
    else:
74
        result = recv_end.recv()
71
        return {'result': 'timeout'}
72

  
73
    try:
74
        output = re.search('<mandayejs>(.*?)</mandayejs>', stdout, re.DOTALL)
75
        if not output:
76
            raise ValueError
77
        stdout = output.group(1)
78
        result = json.loads(stdout)
79
    except (ValueError,):
80
        result = {"result": "json_error"}
81
        logger.error("invalid json: %s" % stdout)
82

  
83
    if result.get('stderr'):
84
        logger.warning(result['stderr'])
85
    if result.get('error'):
86
        logger.error('Error occured: %s' % result.get('reason'))
75 87

  
76 88
    return result
77 89

  
tests/settings.py
49 49
})
50 50

  
51 51

  
52
PHANTOM_JS_TIMEOUT = 0.25
52
PHANTOM_JS_TIMEOUT = 1
53
-