转换为扭曲异步设计

Zim*_*m3r 3 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
Run Code Online (Sandbox Code Playgroud)

Mat*_*ttH 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))
Run Code Online (Sandbox Code Playgroud)

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

您可以使用twisted.web.client.getPagePOST,您提供的额外参数由HTTPClientFactory处理.

此外,我不打算为会议计时,只需在需要时续订.