【问题标题】:Django tests: how to test concurrent users on SQLite?Django 测试:如何在 SQLite 上测试并发用户?
【发布时间】:2014-12-20 15:23:12
【问题描述】:

我的 Django webapps 是多人策略游戏,其中涉及玩家浏览一系列页面并在每个页面上提交一个 ModelForm。它们通常是来回游戏,因此玩家 1 做出决定,而玩家 2 看到等待屏幕,反之亦然,依此类推。游戏可以有可变数量的玩家。

我已经使用 Django 的 HTTP 测试客户端实现了测试,其中测试被设计为从单个用户的角度编写,具有分支的条件逻辑,无论客户端播放为 P1 还是 P2,并且抽象了等待屏幕:

def play(self):

    self.submit(views.Introduction)
    self.submit(views.Question1, {'answer': random.choice([True,False])})

    if self.player.id_in_group == 1:
        self.submit(views.Send, {"sent_amount": 4})
    else:
        self.submit(views.SendBack, {'sent_back_amount': 8})

    self.submit(views.Results)
    self.submit(views.Question2, dict(feedback=4))

然后,为了模拟 N 个玩家,我实例化了 N 个线程,每个线程都执行上面的代码。

这种方法适用于 Postgres,但不适用于 SQLite,由于外部原因,SQLite 是我们需要用于本地开发的引擎。我得到:OperationalError: Database is locked

有什么方法可以避免锁吗?像任务队列一样,还是在 SQlite DB 解锁之前一直处于休眠状态?或者以某种方式以随机顺序循环测试客户端并在给定时间从每个客户端执行几行?如果我们在 SQLite 上稍微降低性能也没关系。

注意:我可以内联编写多个播放器的代码,以便它们都在 1 个线程中执行,但是 (1) 我发现该代码更难阅读,(2) 它是人为的,因为它硬编码了动作的确切顺序将被执行,并且 (3) 当我们将 10 人游戏更改为 20 人游戏时,它不能很好地扩展。

【问题讨论】:

标签: python django sqlite integration-testing


【解决方案1】:

SQLite 支持multi threaded mode。在这种模式下,SQLite 可以被多个线程安全地使用,前提是没有在两个或多个线程中同时使用单个数据库连接。

Celery 提供了一种确保only one task runs at a time 的方法。如果您使用 celery 进行数据库事务,那么 celery 会确保一次只允许一个事务运行,这可以解决您的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-10
    • 2016-08-01
    • 2011-09-15
    • 1970-01-01
    • 1970-01-01
    • 2016-09-24
    • 2010-10-11
    • 1970-01-01
    相关资源
    最近更新 更多