Search code examples
python-2.7google-app-enginegoogle-cloud-datastoreapp-engine-ndb

ndb put() work but not update result at the same time just after 15-30 seconds


I have very interesing issue(for me exactly), I have query and in this query i have list row:

class TestList(ndb.Model):
    testing_list = ndb.StringProperty(repeated=True)
    list_id = ndb.IntegerProperty()

Also I have API methods for changing testing_list by PATCH request. Code for this:

@app.route('/list/change', methods=['PATCH'])
def list_change():
    list_id = request.form['id']
    list_elements = request.form['elements']
    query = TestList.query(TestList.list_id == int(list_id))
    try:
        query.fetch()[0].list_id
    except IndexError:
        return 'Error', 400
    new_elements = str(list_elements).replace(' ', '').split(',')
    query.fetch()[0].testing_list = [element for element in new_elements if element in query.fetch()[0].testing_list]
    query.fetch()[0].put()

    testing_list_extend(query.get(), new_elements)
    return 'Success', 200

@ndb.transactional
def testing_list_extend(list_key, new_elements):
    for element in new_elements:
        query = TestList.query(ancestor=list_key.key)
        if element not in query.fetch()[0].testing_list:
            query.fetch()[0].testing_list.append(element)
            query.fetch()[0].put()
    return '200'

On input I get string like 'Element1, Element2' this is elements in body request and id like '1'. So after I parse string and make list. After I want add new unique elements in testing_list. On this part I have bug: sometimes, when I add new elements and get testing_list by GET request I get empty list, but for a 15-30 seconds I get list which I wanted see some time ago. For example in body PATCH request:

id = '1'
elements = 'Element1, Element2'

What response I waiting by getting testing_list:

[Element1, Element2]

What I get very often:

[Element1, Element2]

What I get very rare(bug as I think):

[]

Solution

  • The problem was in ndb caching.

    Writing functional test for this issue and find out that row on Datastore in google.cloud was updated but in the same time a GET request was did and got old date, so in the GET method was put ndb.get_context().clear_cache() and this worked fine.