转换为扭曲异步设计

时间:2010-08-11 22:54:30

标签: python asynchronous twisted

好的,我在使用我正在处理的代码表达我的问题时遇到了问题而没有丢弃大量的代码;所以这里是同步的(而不是从它的异步视图中询问它)。

对于何时应该通过方法参数访问变量的类以及何时应该通过实例变量访问它?

同步它看起来像...... 注意:实际的服务器URL和解析是不同的,但只是复杂的事情。同样在以下示例中,get_token方法将会话作为参数,是否应该通过使用self.session来获取会话?

import urllib
import time

class SyncExampleClass(object):

    def __init__(self):
        self.session = None
        self.token = None
        self.session_time = -1


    def get_session(self):
        s = urllib.urlopen("http://example.com/session/").read()
        self.session_time = int(time.time())
        return s

    def get_token(self, session):
        t = urllib.urlopen("http://example.com/token/?session=%s" % session).read()
        return t

    def construct_api_call(self, api_method):
        # if the session is over an hour old (is that the correct sign?)
        if time.time() - 3600 > self.session_time or self.session is None:
            self.session = get_session()
            self.token = get_token(self.session)

        call = urllib.urlopen("http://example.com/api/?method=%s%session=%s&token=%s" % (api_method, self.session, self.token) ).read()
        return call

1 个答案:

答案 0 :(得分:5)

鉴于这种情况,这只是一个很明显的解决方案的框架。似乎违背本能提供一个代码的解决方案,其中暗示和未经测试很多......

但是,如果我正在编写我认为你想要实现的内容,我可能会这样做:

from twisted.internet import defer
from twisted.web import client
from twisted.python import log
from urllib import urlencode
import time

class APIException(Exception):
    pass

class ASyncExampleClass(object):
    def __init__(self):
        self.session = None
        self.token = None

    @defer.inlineCallbacks
    def api_call(self, api_method,tries=3,timeout=10):
        attempt = 1
        while attempt <= tries:
            attempt += 1
            if self.session = None:
                yield sess_data = client.getPage("http://example.com/session/",timeout=timeout)
                self.session = extractSessionFromData(sess_data)
            if self.token = None:
                yield token_data = client.getPage("http://example.com/token/?%s" % urlencode(dict(session=self.session)),timeout=timeout)
                self.token = extractTokenFromData(token_data)
            # Place "the" call
            yield api_result = client.getPage("http://example.com/api/?%s" % urlencode(dict(api_method=api_method,session=self.session,token=self.token)),timeout=timeout)
            #
            if sessionInvalid(api_result):
                log.msg("Request for %s failed because invalid session %s" % (api_method,self.session))
                self.session = None
                self.token = None
                continue
            if tokenInvalid(api_result):
                log.msg("Request for %s failed because invalid token %s" % (api_method,self.token))
                self.token = None
                continue
            # Any other checks for valid result
            returnValue(api_result)
            break # Not sure if this is needed, not in an position to test readily.
        else:
            raise APIException("Tried and failed %s times to do %s" % (attempt - 1, api_method))

使外部api使用inlineCallbacks并处理获取和更新会话和令牌本身的逻辑的方法。我假设当会话无效时,使用它获取的任何令牌也是无效的。它实现了一个重试循环,它还可以包含一个try/except块,以便更好地处理HTTP异常。

您可以在POST中使用twisted.web.client.getPage,您提供的额外参数由HTTPClientFactory处理。

此外,我不打算花时间讨论会议,只需在需要时续订。