从后台线程访问GAE数据存储区

时间:2015-02-04 06:09:17

标签: python multithreading google-app-engine google-cloud-datastore gae-userservice

我正在通过Google App Engine编写Web应用程序,并且我希望脚本能够根据我从XML Feed获取的实时临时信息频繁更新用户配置文件。我使用GAE background_thread执行此操作,以便站点可以在此运行时继续运行。

在此后台线程之外,用户仍然可以浏览网站,从而更改其个人资料。

后台线程完全按照应有的方式执行操作,根据实时XML数据更新用户配置文件,并将配置文件重新输入数据存储区。但是,当用户对其配置文件进行更改时,后台线程无法获取更改。来自ndb数据存储区查询的返回列表不反映用户所做的更改。

奇怪的是,如果将新用户添加到数据存储区,它会反映正确的更改,如果修改了预先存在的用户配置文件,它就不会反映更改。我应该能够从后台线程查询/放置数据存储区吗?

背景线索的肉:

def update_accounts():
    while True:
        # Get data from XML feed.
        info_dict = get_live_data()

        # Get all the users from the GAE database
        gprofiles = mUserStats.query()

            for profile in gprofiles:

                # This isn't the actual condition but there's a condition here.
                if needs_update in profile.m_needsUpdate: 

                    # Modify the current profile. 
                    profile.make_change(info_dict)
                    # Re enter into database.
                    profile.put()

        # Add a sleep time as this doesn't need to run that frequently.
        time.sleep(20)              

class updateAccounts():

def start_thread(self):
    t =background_thread.start_new_background_thread(target=update_accounts())

这是修改配置文件的地方:

def post(self):
        session = get_current_session()
        user_key = mUserStats_key(session['me'].m_email)
        curr_user = mUserStats.get_by_id(session['me'].m_email, user_key)
        curr_user.change_profile() 
        curr_user.put()

1 个答案:

答案 0 :(得分:1)

只是一些随机的想法,不知道哪个最好(如果有的话):

  1. 而不是在循环中执行profile.put()可能您可以在列表中存储已更改的实体并在循环后执行一些ndb.put_multi()调用?这将减少数据存储区调用的数量,减少执行时间mUserStats的实体数量,从而减少执行时间,并减少用户在后台任务运行时更改配置文件的机会。

    < / LI>
  2. 如果gprofiles = mUserStats.query()行实际获取整个实体,您可以尝试执行keys_only=True并在循环内单独获取每个mUserStats实体。这将增加执行时间和数据存储区调用数量mUserStats实体的数量,但是在后台任务获取实体时,用户更改实体的可能性要小得多。

  3. XML Feed更新的属性是否由用户更新了相同的属性?如果不是 - 也许它们可以存储在不同的模型中。

  4. 您还可以查看querycursorsiterators,这可能有助于自动化建议1&amp; 2。