문제

그래서 나는 Stackless Python과 함께 놀아요 매우 간단합니다 Webserver는 Microthreads/Tasklets를 사용하여 자신에게 프로그래밍을 가르칩니다. 하지만 이제 내 문제에 대해 ab -n 100000 -c 50 http://192.168.0.192/ (100k 요청, 50 동시성) Apache Bench에서 6k req/s와 같은 것을 얻습니다. 또는 뭔가.

그래도 파이썬 스크립트를 다시 시작하면 문제가 사라집니다.

이제 내 질문은 왜? 작업권을 삭제하는 것을 잊고 있습니까? 나는 stackless.getRuncount ()를 확인했으며 (어떤 이유로 든 항상 1 번 반환하는 것 같습니다). 완료된 모든 작업 글렛에서 .kill ()을 호출하려고했지만 도움이되지 않았습니다. 나는 이것을 알아낼 수 없다.

import socket
import select
import stackless
import time

class socket_wrapper(object):
    def __init__(self, sock, sockets):
        super(socket_wrapper, self).__init__()
        self.sock = sock
        self.fileno = sock.fileno
        self.sockets_list = sockets
        self.channel = stackless.channel()
        self.writable = False
        self.error = False

    def remove(self):
        self.sock.close()
        self.sockets_list.remove(self)

    def send(self, data):
        self.sock.send(data)

    def push(self, bytes):
        self.channel.send(self.sock.recv(bytes))

def stackless_accept(accept, handler, recv_size=1024, timeout=0):
    sockets = [accept]

    while True:
        read, write, error = select.select(sockets, sockets, sockets, timeout)

        for sock in read:
            if sock is accept:
                # Accept socket and create wrapper
                sock = socket_wrapper(sock.accept()[0], sockets)

                # Create tasklett for this connection
                tasklet = stackless.tasklet(handler)
                tasklet.setup(sock)

                # Store socket
                sockets.append(sock)

            else:
                # Send data to handler
                sock.push(recv_size)

        # Tag all writable sockets
        for sock in write:
            if sock is not accept:
                sock.writable = True

        # Tag all faulty sockets
        for sock in error:
            if sock is not accept:
                sock.error = True
            else:
                pass # should do something here if the main socket is faulty

        timeout = 0 if socket else 1
        stackless.schedule() 

def simple_handler(tsock):
    data = ""

    while data[-4:] != "\r\n\r\n":
        data += tsock.channel.receive()

    while not tsock.writable and not tsock.error:
        stackless.schedule()

    if not tsock.error:
        tsock.send("HTTP/1.1 200 OK\r\nContent-length: 8\r\n\r\nHi there")
        tsock.remove()

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(("192.168.0.192", 8000))
sock.listen(5)

stackless.tasklet(stackless_accept)(sock, simple_handler)
stackless.run()
도움이 되었습니까?

해결책

두가지.

먼저, 클래스 이름을 대문자로 시작하게하십시오. 더 일반적이고 읽기가 더 쉽습니다.

더 중요한 것은 stackless_accept 당신이 축적하는 기능 a listSock 이름이 지정된 개체 sockets. 이 목록은 끝없이 성장하는 것으로 보입니다. 예, 당신은 a remove, 그러나 그렇지 않습니다 언제나 호출. 소켓에 오류가 발생하면 컬렉션에 영원히 남아있는 것으로 보입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top