0

我正在使用 tornado 框架,并且我的所有功能都是同步编写的。我将如何使这些异步?

class AuthLoginHandler(BaseHandler):
    @tornado.web.asynchronous
    def get(self):

        self.render("login.html")

    def post(self):
        username = self.get_argument("UserName",strip = True)
        password = self.get_argument("Password",strip = True)
        user = auth_actions.login(username,password)
        if not user:
            self.redirect("/auth/login")
            return

        #user = user_actions.get_my_data(self.db,user['_id'])

        self.set_secure_cookie("userdata", tornado.escape.json_encode(dumps(user.to_mongo())))
        self.redirect("/")


def login(username,password,callback=None):
    m = hashlib.md5()
    m.update(password)
    hashed = m.hexdigest()
    login = User.objects(UserName=username.lower(),Password=hashed).exclude("Password","Wall","FriendsRequested","Friends","FriendsRequesting")
    if login.first() is None:
        login = User.objects(Email=username.lower(),Password=hashed).exclude("Password","Wall","FriendsRequested","Friends","FriendsRequesting")
        if login.first() is None:
            return None
    logger.info(username + " has logged in")
    if callback != None:
        return callback(login.first())

    return login.first()
4

2 回答 2

2

正如 andy boot 所提到的,您将需要一个单独的线程。下面的代码使用来自tornado-gengenerator的-coroutine方法。另请注意,它将您的功能包装在自己的线程中。run_async decorator

import tornado.ioloop
import tornado.web
import tornado.gen
import time
from threading import Thread
from functools import wraps

def run_async(func):
  @wraps(func)
  def async_func(*args, **kwargs):
    func_hl = Thread(target = func, args = args, kwargs = kwargs)
    func_hl.start()
    return func_hl

  return async_func

@run_async
def login(username,password,callback=None):
  m = hashlib.md5()
  m.update(password)
  hashed = m.hexdigest()
  login = User.objects(UserName=username.lower(),Password=hashed).exclude("Password","Wall","FriendsRequested","Friends","FriendsRequesting")
  if login.first() is None:
    login = User.objects(Email=username.lower(),Password=hashed).exclude("Password","Wall","FriendsRequested","Friends","FriendsRequesting")
    if login.first() is None:
      return None
  logger.info(username + " has logged in")
  if callback != None:
    return callback(login.first())
  return login.first()


class AuthLoginHandler(BaseHandler):
  @tornado.web.asynchronous
  def get(self):
    self.render("login.html")

  @tornado.web.asynchronous
  @tornado.gen.coroutine
  def post(self):
    username = self.get_argument("UserName",strip = True)
    password = self.get_argument("Password",strip = True)
    user = yield tornado.gen.Task(auth_actions.login, username, password)
    if not user:
      self.redirect("/auth/login")
      return
    self.set_secure_cookie("userdata", tornado.escape.json_encode(dumps(user.to_mongo())))
    self.redirect("/")
于 2013-04-12T14:18:44.620 回答
1

如果您要对密码进行哈希处理,最好在单独的线程中进行。这是因为散列需要很长时间才能执行并且会阻塞主线程。

这是在单独线程上散列的示例

请注意,Tornado 的维护者 Ben Darnell 建议使用单独的线程来进行密码哈希:请参阅这个 google 组

于 2013-04-12T13:58:35.833 回答