hult1989 / wsProj

0 stars 1 forks source link

重构2 #2

Open hult1989 opened 9 years ago

hult1989 commented 9 years ago

遇到一个棘手的问题,通常数据库操作要以异步的方式实现。假如现在要调用changeUserName(),首先要调用isUserExists,但isUserExists作为一个数据库操作,本身也是异步的。一方面,我希望检测用户存在与否能够被尽可能复用,这意味着我希望将这个isUserExists封装成可被调用的独立函数,而不是在changeUserName中或其他任何需要检查用户是否存在的函数中重新定义实现一遍;另一方面,我无法在一个异步的函数本身中再次调用一个异步的函数。这导致在调用changeUserName()这个函数本身要先调用isUserExists,如d.addCallback(isUserExists).addCallback(changeUserName),但这意味着把检查用户存在与否的底层逻辑上报给了调用者,让上层调用者在修改用户名之前检查用户名。这肯定是不好的变成习惯

解决的问题是,由于在twisted框架中,异步函数是封装了阻塞操作的函数,可以将阻塞的函数部分独立处理,不放在异步处理的框架下。


def _isUserExist(username):
    ...

def changeUserName(name):
    return wsdbpool.runIntergation(_changeName, name)

def _changeName(txn, name):
    if isUserExist == True:
        txn.runChangeName()
hult1989 commented 9 years ago

实现一个单例模式,这个单例主要数据内一个哈希表,用来暂时存数验证码、绑定的中间信息等内容。希望这个单例能够定期删除自身的数据,如每隔两分钟删除掉超时的数据

使用ActiveMQ之类的东西,或python自带的队列?

观察者模式?

hult1989 commented 9 years ago

定时器可以这样实现,启动一个新的线程,然后睡眠,每隔两分钟唤醒一次,清理没用的对象

可以把队列设计成环形,清理就是将一个变量赋值为None

hult1989 commented 9 years ago

把数据库操作分解两个部分,外层函数是将阻塞的数据库操作异步化的封装,内层函数是阻塞的数据库操作。这样分离的好处是,内层函数可以被其他数据库操作调用。当其他数据库操作函数无法直接调用handleUnsubscribeSql操作时,可以直接调用_handleUnsubscribe,这样就无需在函数内部重新实现全部或部分_handleUnsubscribe的工作

def handleUnsubscribeSql(wsdbpool, username, imei):
    return wsdbpool.runInteraction(_handleUnsubscribe, username, imei)

def _handleUnsubscribe(txn, username, imei):
    txn.execute('select * from userinfo where username = %s', (username,))
    if len(txn.fetchall()) == 0:
        raise NoUserException
    txn.execute('select * from wsinfo where imei = %s', (imei,))
    if len(txn.fetchall()) == 0:
        raise NoImeiException
    txn.execute('select * from user_ws where username = %s and imei = %s', (username, 
imei))
    if len(txn.fetchall()) == 0:
        raise NoSubException
    return txn.execute('delete from user_ws where username = %s and imei = %s', (usern
ame, imei))
hult1989 commented 9 years ago

将request封装成不同的类,并在类的内部放置处理函数?或者将['delnumber']放到一个数据类中?

在类的内部内置请求处理函数的好处是,这个函数自动地获得了需要的参数,无需进行额外的传递

if request.args['action'] == ['addnumber']:
        elif request.args['action'] == ['delnumber']:
        elif request.args['action'] == ['varifyadd']:
        elif request.args['action'] == ['varifydel']:
        elif request.args['action'] == ['getnumber']:
        elif request.args['action'] == ['updatepassword']:
hult1989 commented 9 years ago

最底层封装数据库操作函数,作为纯粹的数据操作函数 在上一层通过函数调名,指明某个或某些数据库操作函数的含义 第三层函数使用第二次的函数调用,通过不同的组合表示不同的业务逻辑

让任意一层函数都只接触下一层函数,并能任意调用下一层函数 在第三层实现异步调用

hult1989 commented 9 years ago

要不要以类来传递数据?这个数据类应该按照响应报文的字段来制定,还是按照数据库内表的字段来制定?

可以分别实现两种类,然后让类与类之间的关系呈关联关系