python epoll模型实现类似redis缓存

python epoll模型实现类似redis缓存数据库,先把功能实现了。争用问题暂没弄,看代码。server.py:

import socketimport selectimport reimport urllib2from py_db import auth as auth_infoEOL1 = b'exit'EOL2 = b'quit'EOL3 = b'\n'class Database():    def __init__(self):        self.data = {}    def get(self, key):        if key in self.data.keys():            return self.data[key]        else:            return None    def set(self, key, value):        if key in self.data.keys():            self.data[key] = value        else:            self.data.setdefault(key, value)        return 'ok'def fetch(url):    request = urllib2.Request(url)    request.get_method = lambda: 'HEAD'    response = urllib2.urlopen(request)    return response.code, response.info()["Content-Length"]class Server():    def __init__(self, host='localhost', port=5678):        self.host = host        self.port = port        self.username = auth_info["username"]        self.password = auth_info["password"]        self.authenticated = False    def auth(self, username, password):        if username == self.username and password == self.password:            self.authenticated = True            return True        else:            self.authenticated = False            return False    def start(self):        serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)        serversocket.bind((self.host, self.port))        serversocket.listen(1)        serversocket.setblocking(0)        epoll = select.epoll()        epoll.register(serversocket.fileno(), select.EPOLLIN)        try:            connections = {}            requests = {}            responses = {}            while True:                events = epoll.poll(1)                for fileno, event in events:                    if fileno == serversocket.fileno():                        connection, address = serversocket.accept()                        connection.setblocking(0)                        epoll.register(connection.fileno(), select.EPOLLIN)                        connections[connection.fileno()] = connection                        requests[connection.fileno()] = b''                        responses[connection.fileno()] = 'hello'                    elif event & select.EPOLLIN:                        requests[fileno] = connections[fileno].recv(1024)                        if EOL3 in requests[fileno] and re.search("[set \w+ \w+|get \w+|AUTH \w+ \w+|URL \w+ \w+]",                                                                  requests[fileno]):                            try:                                data = requests[fileno].decode()[:-2].split()                                method = data[0].strip()                                ret = None                                if method == "set":                                    ret = db.set(data[1], data[2])                                if method == "get":                                    ret = db.get(data[1])                                if method == "AUTH":                                    username, password = data[1], data[2]                                    if self.auth(username, password):                                        ret = 'ok'                                    else:                                        ret = 'bad'                                if method == "URL":                                    name, url = data[1], data[2]                                    if self.authenticated:                                        if name in db.data.keys():                                            ret = db.data[name]                                        else:                                            code, size = fetch(url)                                            db.data[name] = {"code": code, "size": size}                                            ret = "ok"                                    else:                                        ret = "unauthenticated user"                                byteswritten = connections[fileno].send(bytes('%s\n' % ret))                                responses[fileno] = responses[fileno][byteswritten:]                            except:                                byteswritten = connections[fileno].send(bytes('bad\n'))                            finally:                                print db.data                        if EOL1 in requests[fileno] or EOL2 in requests[fileno]:                            epoll.modify(fileno, select.EPOLLOUT)                    elif event & select.EPOLLOUT:                        responses[fileno] = responses[fileno][byteswritten:]                        if len(responses[fileno]) == 0:                            epoll.modify(fileno, 0)                            connections[fileno].shutdown(socket.SHUT_RDWR)                    elif event & select.EPOLLHUP:                        epoll.unregister(fileno)                        connections[fileno].close()                        del connections[fileno]        finally:            epoll.unregister(serversocket.fileno())            epoll.close()            serversocket.close()if __name__ == "__main__":    db = Database()    ss = Server()    ss.start()

auth.py

#!/usr/bin/env python# -*- coding: utf-8 -*- #  tanyewei@gmail.com#  2014/03/18 21:15auth = {    "username" : "redis",    "password" : "redis123"}

效果图:

python epoll模型实现类似redis缓存

相关文章:

你感兴趣的文章:

标签云: