ws.py 2.4 KB
Newer Older
baltery's avatar
baltery 已提交
1
import time
baltery's avatar
baltery 已提交
2
import os
baltery's avatar
baltery 已提交
3
import threading
baltery's avatar
baltery 已提交
4 5
import json

6
from common.utils import get_logger
baltery's avatar
baltery 已提交
7 8 9 10

from .celery.utils import get_celery_task_log_path
from channels.generic.websocket import JsonWebsocketConsumer

11 12
logger = get_logger(__name__)

baltery's avatar
baltery 已提交
13 14 15 16 17

class CeleryLogWebsocket(JsonWebsocketConsumer):
    disconnected = False

    def connect(self):
baltery's avatar
baltery 已提交
18 19 20 21 22
        user = self.scope["user"]
        if user.is_authenticated and user.is_org_admin:
            self.accept()
        else:
            self.close()
baltery's avatar
baltery 已提交
23

baltery's avatar
baltery 已提交
24 25 26 27 28 29
    def receive(self, text_data=None, bytes_data=None, **kwargs):
        data = json.loads(text_data)
        task_id = data.get("task")
        if task_id:
            self.handle_task(task_id)

baltery's avatar
baltery 已提交
30
    def wait_util_log_path_exist(self, task_id):
baltery's avatar
baltery 已提交
31
        log_path = get_celery_task_log_path(task_id)
baltery's avatar
baltery 已提交
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
        while not self.disconnected:
            if not os.path.exists(log_path):
                self.send_json({'message': '.', 'task': task_id})
                time.sleep(0.5)
                continue
            self.send_json({'message': '\r\n'})
            try:
                logger.debug('Task log path: {}'.format(log_path))
                task_log_f = open(log_path, 'rb')
                return task_log_f
            except OSError:
                return None

    def read_log_file(self, task_id):
        task_log_f = self.wait_util_log_path_exist(task_id)
        if not task_log_f:
baltery's avatar
baltery 已提交
48
            logger.debug('Task log file is None: {}'.format(task_id))
baltery's avatar
baltery 已提交
49 50 51 52 53 54 55 56
            return

        task_end_mark = []
        while not self.disconnected:
            data = task_log_f.read(4096)
            if data:
                data = data.replace(b'\n', b'\r\n')
                self.send_json(
baltery's avatar
baltery 已提交
57 58
                    {'message': data.decode(errors='ignore'), 'task': task_id}
                )
baltery's avatar
baltery 已提交
59 60 61 62 63 64 65 66 67
                if data.find(b'succeeded in') != -1:
                    task_end_mark.append(1)
                if data.find(bytes(task_id, 'utf8')) != -1:
                    task_end_mark.append(1)
            elif len(task_end_mark) == 2:
                logger.debug('Task log end: {}'.format(task_id))
                break
            time.sleep(0.2)
        task_log_f.close()
baltery's avatar
baltery 已提交
68

baltery's avatar
baltery 已提交
69 70 71
    def handle_task(self, task_id):
        logger.info("Task id: {}".format(task_id))
        thread = threading.Thread(target=self.read_log_file, args=(task_id,))
baltery's avatar
baltery 已提交
72
        thread.start()
baltery's avatar
baltery 已提交
73 74 75 76 77 78

    def disconnect(self, close_code):
        self.disconnected = True
        self.close()