parse-community / parse-server

Parse Server for Node.js / Express
https://parseplatform.org
Apache License 2.0
20.9k stars 4.78k forks source link

`User` changes take significant time to propagate between threads #7313

Open MobileVet opened 3 years ago

MobileVet commented 3 years ago

New Issue Checklist

Issue Description

Making a change to a User in one thread, does not show up immediately in another worker thread. For instance, if you create a super simple cloud function (see below) that changes a property on the User object and another cloud function that reads back that value (after having it hydrated from the request)... even if you await the change function, if you call the readUser function immediately after you will get the original value back.

If you add an async wait and THEN call the readUser function, the value will be updated properly. Even running locally the wait must be several seconds to be effective.

Steps to reproduce

Actual Outcome

Expected Outcome

Failing Test Case / Pull Request

Will look at this... not sure if test env has ability to utilize clustering.

Environment

Server

Database

Client

Functions

Parse.Cloud.define('updateUser', async (req: Parse.Cloud.FunctionRequest) => {
    const user = req.user
    if (!user) {
        throw 'no user'
    }
    const token = user.getSessionToken()
    const updatedThing = await user.save({ testVal: String(new Date().getTime()) }, { sessionToken: token })
    console.log('updatedThing:', JSON.stringify(updatedThing.toJSON(), null, 4))
    console.log('pid:', JSON.stringify(process.pid, null, 4))
    console.log('testVal (after updating):', user.get('testVal'))
})
Parse.Cloud.define('fetchUser', async (req: Parse.Cloud.FunctionRequest) => {
    const user = req.user
    if (!user) {
        throw 'no user'
    }
    console.log('pid:', JSON.stringify(process.pid, null, 4))
    console.log('testVal:', user.get('testVal'))
})

Client Test function

async clickTestThign () {
    await this.fetchUserTest()
    await this.updateUserTest()
    this.fetchUserTest()
    this.fetchUserTest()
    this.fetchUserTest()
    this.fetchUserTest()
    this.fetchUserTest()
    await new Promise<void>(res => setTimeout(async () => {
        this.fetchUserTest()
        this.fetchUserTest()
        this.fetchUserTest()
        this.fetchUserTest()
        res()
    }, 2000))
}

Logs

mtrezza commented 3 years ago

Thanks for reporting.

Would you open a PR with a failing test case? I think we have node cluster configuration built into Parse Server, so it may be possible to write a test.

MobileVet commented 3 years ago

@mtrezza Will take a look. I didn't realize the cluster configuration was possible with Parse Server setup. We have been using Throng outside of our PS setup.

mtrezza commented 3 years ago

Yes, not only is it possible, it should be conveniently configurable with a single option.