LoginSignup
0
0

More than 3 years have passed since last update.

Djangoのリクエストを非同期で処理

Posted at
[Views.py]
import time
import json
import logging
import requests
import queue

from rest_framework import generics
from rest_framework.views import APIView
from rest_framework.response import Response

import api.myutils as myutils
from books.models import Book

SLEEP_TIME = 10

class BookApiView(APIView):
    def get(self, request):
        resp = {'API': ''}
        return Response(resp, status = '200', content_type='application/json')

class BooksView(APIView):
    def get(self, request):
        resp_books = []
        resp = {}
        for book in Book.objects.all():
            resp_book = {'isbn': book.isbn, 'title': book.title, 'subtitle': book.subtitle, 'author': book.author}
            resp_books.append(resp_book)
        resp['Books'] = resp_books
        return Response(resp, status = '200', content_type='application/json')

    def post(self, request):
        try:
            data = json.loads(request.body)
            new_isbn = data["isbn"]
            new_title = data["title"]
            new_subtitle = data["subtitle"]
            new_author = data["author"]

        except KeyError:
            return Response(None, status = '400')

        if Book.objects.filter(isbn = new_isbn):
            return Response(None, status = '400')

        book = Book(isbn=new_isbn, title=new_title, subtitle=new_subtitle, author=new_author)
        if myutils.submit_task(new_isbn, BooksView.post_task, book):
            resp = {'id': new_isbn}
            return Response(resp, status = '200', content_type='application/json')
        else:
            resp = {'code': '409'}
            return Response(resp, status = '409', content_type='application/json')

    def post_task(book:Book):
        print('[post_task] start: ' + str(book))
        time.sleep(SLEEP_TIME)
        book.save()
        print('[post_task] end ' + str(book))
        return True

    def delete(self, request):
        Book.objects.all().delete()
        resp = {}
        return Response(resp, status = '200', content_type='application/json')

class BookView(APIView):
    def get(self, request, isbn):
        if not Book.objects.filter(isbn = isbn):
            return Response(None, status = '404')
        book = Book.objects.get(isbn = isbn)
        resp = {'isbn': book.isbn, 'title': book.title, 'subtitle': book.subtitle, 'author': book.author}
        return Response(resp, status = '200', content_type='application/json')

    def delete(self, request, isbn):
        if not Book.objects.filter(isbn = isbn):
            return Response(None, status = '404')
        Book.objects.get(isbn = isbn).delete()
        resp = {}
        return Response(resp, status = '200', content_type='application/json')
[myutils.py]
import json
import time
import datetime
import logging
import queue

from queue import Queue
from threading import Thread
from datetime import datetime

THREAD_MAX_SIZE = 2

task_queue = Queue(maxsize = THREAD_MAX_SIZE)
worker_threads = []
logger = None

class TaskEvent:
    def __init__(self, task_id, task, task_args):
        self.id = task_id
        self.task = task
        self.args = task_args

class WorkerThread(Thread):
    def __init__(self, tq:Queue, logger:logging.Logger):
        super().__init__()
        self.tq = tq
        self.logger = logger
        self.working = True

    def run(self):
        while self.working:
            task_event = self.tq.get()
            self.logger.info('task[' + task_event.id + '] start')
            result = task_event.task(task_event.args)
            self.logger.info('task[' + task_event.id + '] end: result = %s', result)

def initialize():
    formatter = '%(levelname)s : %(asctime)s : %(message)s'
    logging.basicConfig(level=logging.DEBUG, format = formatter)
    logger = logging.getLogger(__name__)

    for i in range(THREAD_MAX_SIZE):
        wt = WorkerThread(task_queue, logger)
        worker_threads.append(wt)
        wt.start()

def submit_task(task_id, task, task_args):
    try:
        task_event = TaskEvent(task_id, task, task_args)
        task_queue.put_nowait(task_event)
        return True
    except queue.Full:
        return False
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0