请求隔离如何在CherryPy中工作。我不明白基本概念

时间:2013-08-22 09:55:44

标签: python cherrypy

简而言之,我不明白CherryPy会同时向同一个资源发出两个请求,是变量混合还是发生了什么?

我有这个问题,我正在尝试使用Python 2.7和CherryPy 3.2.2创建一个非常基本的Web服务。

前端使用Web服务,使用jquery / ajax向Web服务发出ajax请求。

现在,我已经创建了一个CherryPy程序,我正在使用它的内置wsgi服务器。我有这样的CherryPy配置:

conf = {
    'global': {
        'server.socket_host': '127.0.0.1',
        'server.socket_port': 8000,
    },
    '/': {
        'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
    }
}
cherrypy.quickstart(root, '/', conf)

然后我有:

root.customers = getCustomers()

实际的课程:

class getCustomers(object):

    def __init__(self):
        pass

    exposed = True

    def GET(self,callback,**kwargs):
        self.callback = callback
        self.cnxn= pyodbc.connect(constr)
        self.cursor = self.cnxn.cursor()

        cherrypy.response.headers['Content-Type']='application/json'
        self.cursor.execute("""select * from customers
            """, self.job_worknumber)
        self.customers = self.cursor.fetchall()

        self.objects_list = []
        for c in self.customers
            r = collections.OrderedDict()
            r['customer_id'] = c.customer_id
            r['customer_name'] = c.customer_name
            self.objects_list.append(r)

        self.cursor.close()
        self.cnxn.close()

        self.w = collections.OrderedDict()
        self.w['data1'] = self.objects_list
        #w['errors'] = 'error'
        self.j = json.dumps(self.w)

        #cursor2.close()
        return  self.callback+'('+self.j+');'

现在当我创建一个GET请求时,我得到了我想要的东西,但是如果我创建的网页在页面加载时向Web服务发送两个GET请求,那么第二个请求几乎总会失败并出现如下错误:

ProgrammingError: Attempt to use a closed cursor.

或其他时间:

ProgrammingError: No results.  Previous SQL was not a query

那么发生了什么,我的请求是否共享相同的变量,它们同时运行?我可以将CherryPy配置为一次只提供一个请求吗?

1 个答案:

答案 0 :(得分:2)

@DanielRoseman注意到你不应该在self上设置变量。您只创建了一个getCustomers类的实例,因此CherryPy将在多个线程的同一实例上调用GET方法(有一个处理请求的线程池)。使用

self.cursor = self.cnxn.cursor()

不是线程安全的,你最终会在

中使用不同的光标
self.cursor.execute("""select * from customers
            """, self.job_worknumber)

self.cursor.fetchall()或任何其他地方(有点随机)。

但是,将所有变量更改为本地(self中根本不使用GET)应该可以解决问题。