Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix(GraphQL): This PR fix multi cors and multi schema nodes issue by selecting one of the latest added nodes, and add dgraph type to cors. #7270

Merged
merged 16 commits into from
Jan 14, 2021

Conversation

JatinDev543
Copy link
Contributor

@JatinDev543 JatinDev543 commented Jan 11, 2021

Fixes GRAPHQL-948
We already fixed the issue which causes dgraph to have multiple schema or cores nodes. But there are some cases in which this bug can occur again, for example, someone restored a backup that was taken before the fix. This bug continuously fill the logs on alpha and blocks graphql layer. Then we can't do mutate/query or add schema.

Now, we are changing this behavior, if we have multiple schema or cores nodes then we will select the one which was added last.
In addition to it, we are adding dgraph.type.cors type to to the dgraph.cors node, which allow us to use delete (S * *) type mutation on it, in case we want to delete extra node manually.


This change is Reviewable

@github-actions github-actions bot added area/graphql Issues related to GraphQL support on Dgraph. area/schema Issues related to the schema language and capabilities. labels Jan 11, 2021
Copy link
Contributor

@abhimanyusinghgaur abhimanyusinghgaur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's discuss with @pawanrawal if we should use the max node in case we encounter more than one node.

Reviewed 10 of 15 files at r1.
Reviewable status: 10 of 15 files reviewed, 3 unresolved discussions (waiting on @jatindevdg, @manishrjain, @pawanrawal, and @vvbalaji-dgraph)


edgraph/graphql.go, line 150 at r1 (raw file):

glog.Infof("

Errorf
and again I don't feel we should do this. If this happens that means there is some other issue, which we should fix. Or if it happens due to older backups we should have a way to migrate from those which we already have. So, this feels like it should still return an error if we get either 0 or more than 1 node.


edgraph/server.go, line 177 at r1 (raw file):

if uidMax < schNode.Uid {

uid here is a string. Shouldn't we first convert it to int and then compare?
Because, even the difference of A and a can make it go wrong right now.


edgraph/server.go, line 182 at r1 (raw file):

		}
	}
	glog.Infof("Multiple schema node found,returning last added node")

This is supposed to be an error state, so we should use glog.Errorf.

But, it doesn't feel like we should make it return the max node instead of giving an error. Such states should never be achieved and we also haven't seen any evidence for GraphQL schema case where two nodes have been seen after the fixes done long back.
So, I believe that we should still return an error because we need to know if such thing happens, instead of just ignoring it.

@JatinDev543
Copy link
Contributor Author

JatinDev543 commented Jan 12, 2021

Let's discuss with @pawanrawal if we should use the max node in case we encounter more than one node.

Reviewed 10 of 15 files at r1.
Reviewable status: 10 of 15 files reviewed, 3 unresolved discussions (waiting on @jatindevdg, @manishrjain, @pawanrawal, and @vvbalaji-dgraph)

edgraph/graphql.go, line 150 at r1 (raw file):

glog.Infof("

Errorf
and again I don't feel we should do this. If this happens that means there is some other issue, which we should fix. Or if it happens due to older backups we should have a way to migrate from those which we already have. So, this feels like it should still return an error if we get either 0 or more than 1 node.

edgraph/server.go, line 177 at r1 (raw file):

if uidMax < schNode.Uid {

uid here is a string. Shouldn't we first convert it to int and then compare?
Because, even the difference of A and a can make it go wrong right now.

edgraph/server.go, line 182 at r1 (raw file):

		}
	}
	glog.Infof("Multiple schema node found,returning last added node")

This is supposed to be an error state, so we should use glog.Errorf.

But, it doesn't feel like we should make it return the max node instead of giving an error. Such states should never be achieved and we also haven't seen any evidence for GraphQL schema case where two nodes have been seen after the fixes done long back.
So, I believe that we should still return an error because we need to know if such thing happens, instead of just ignoring it.

Changed uid comparison. Also log errors using Errorf.

Copy link
Contributor

@pawanrawal pawanrawal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 0 of 15 files reviewed, 8 unresolved discussions (waiting on @jatindevdg, @manishrjain, and @vvbalaji-dgraph)


edgraph/graphql.go, line 150 at r1 (raw file):

		}
	}
	glog.Infof("Multiple nodes of type dgraph.type.cors found,returning last added node")

space after ,

Multiple nodes of type dgraph.type.cors found, using the latest one.


edgraph/graphql.go, line 143 at r2 (raw file):

		return corsRes.Me[0].Uid, corsRes.Me[0].DgraphCors, nil
	}
	cors := corsRes.Me[0].DgraphCors

Add a comment here that if there are multiple nodes for cors we pick the one with the max uid.


edgraph/graphql.go, line 144 at r2 (raw file):

	}
	cors := corsRes.Me[0].DgraphCors
	uidMax := corsRes.Me[0].Uid

maxUid


edgraph/graphql.go, line 145 at r2 (raw file):

	cors := corsRes.Me[0].DgraphCors
	uidMax := corsRes.Me[0].Uid
	uidMaxInt, err := gql.ParseUid(uidMax)

maxUidInt


edgraph/graphql.go, line 150 at r2 (raw file):

	}
	for _, me := range corsRes.Me[1:] {
		cUidInt, err := gql.ParseUid(me.Uid)
sort.Slice(corsRes.Me, func(i, j int) bool {
  // parse the uids into integer and then compare
  return corsRes.Me[i].uidInt < corsResMe[j].uidInt 
})

edgraph/graphql.go, line 155 at r2 (raw file):

		}
		if uidMaxInt < cUidInt {
			uidMaxInt = cUidInt

instead of doing all this why not sort them and then pick the last value?


edgraph/server.go, line 187 at r2 (raw file):

		if uidMaxInt < cUidInt {
			uidMaxInt = cUidInt
			uidMax = schNode.Uid

use sort here


worker/graphql_schema.go, line 109 at r2 (raw file):

		// there seems to be multiple nodes for GraphQL schema,Ideally we should never reach here
		// But if by any bug we reach here then return the schema node which is added last
		uidMax := res.GetUidMatrix()[0].GetUids()[0]

the list should already be sorted but you can anyways sort and just pick last value

Copy link
Contributor Author

@JatinDev543 JatinDev543 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 0 of 15 files reviewed, 8 unresolved discussions (waiting on @manishrjain, @pawanrawal, and @vvbalaji-dgraph)


edgraph/graphql.go, line 150 at r1 (raw file):

Previously, pawanrawal (Pawan Rawal) wrote…

space after ,

Multiple nodes of type dgraph.type.cors found, using the latest one.

done.


edgraph/graphql.go, line 143 at r2 (raw file):

Previously, pawanrawal (Pawan Rawal) wrote…

Add a comment here that if there are multiple nodes for cors we pick the one with the max uid.

added.


edgraph/graphql.go, line 144 at r2 (raw file):

Previously, pawanrawal (Pawan Rawal) wrote…

maxUid

not needed now.


edgraph/graphql.go, line 145 at r2 (raw file):

Previously, pawanrawal (Pawan Rawal) wrote…

maxUidInt

not needed now.


edgraph/graphql.go, line 150 at r2 (raw file):

Previously, pawanrawal (Pawan Rawal) wrote…
sort.Slice(corsRes.Me, func(i, j int) bool {
  // parse the uids into integer and then compare
  return corsRes.Me[i].uidInt < corsResMe[j].uidInt 
})

added.


edgraph/graphql.go, line 155 at r2 (raw file):

Previously, pawanrawal (Pawan Rawal) wrote…

instead of doing all this why not sort them and then pick the last value?

sort was costly in terms of performance and we need an extra loop for parsing of values also. But after having with abhimanyu that this case will occur in rare scenarios and we should focus on code readability, i changed this to sort.


edgraph/server.go, line 187 at r2 (raw file):

Previously, pawanrawal (Pawan Rawal) wrote…

use sort here

done.


worker/graphql_schema.go, line 109 at r2 (raw file):

Previously, pawanrawal (Pawan Rawal) wrote…

the list should already be sorted but you can anyways sort and just pick last value

done.

Copy link
Contributor

@pawanrawal pawanrawal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 3 of 3 files at r3.
Reviewable status: 3 of 15 files reviewed, 8 unresolved discussions (waiting on @jatindevdg, @manishrjain, @pawanrawal, and @vvbalaji-dgraph)


edgraph/graphql.go, line 131 at r3 (raw file):

	type corsResponse struct {
		Me []struct {
			Uid        string `json:"uid"`

uid


edgraph/graphql.go, line 147 at r3 (raw file):

	// Multiple nodes for cors found, returning the one that is added last
	for i, _ := range corsRes.Me {
		UidInt, err := gql.ParseUid(corsRes.Me[i].Uid)

iuid


edgraph/server.go, line 176 at r3 (raw file):

	// returning the schema node which is added last
	for i, _ := range result.ExistingGQLSchema {
		UidInt, err := gql.ParseUid(result.ExistingGQLSchema[i].Uid)

iuid


edgraph/server.go, line 187 at r3 (raw file):

	})
	glog.Errorf("Multiple schema node found, using the last one")
	lastIndex := len(result.ExistingGQLSchema) - 1

res := result.ExistingGQLSchema[len(result.ExistingGQLSchema)-1]


edgraph/server.go, line 188 at r3 (raw file):

	glog.Errorf("Multiple schema node found, using the last one")
	lastIndex := len(result.ExistingGQLSchema) - 1
	return result.ExistingGQLSchema[lastIndex].Uid, result.ExistingGQLSchema[lastIndex].Schema, nil

return res.Uid, res.Schema, nil


worker/graphql_schema.go, line 110 at r3 (raw file):

		// there seems to be multiple nodes for GraphQL schema,Ideally we should never reach here
		// But if by any bug we reach here then return the schema node which is added last
		sort.Slice(res.GetUidMatrix()[0].GetUids(), func(i, j int) bool {

uidList := res.GetUidMatrix()[0].GetUids()

and then use the uidList everywhere

@netlify
Copy link

netlify bot commented Jan 14, 2021

✔️ Deploy preview for dgraph-docs ready!

🔨 Explore the source changes: 8e02dd6

🔍 Inspect the deploy logs: https://app.netlify.com/sites/dgraph-docs/deploys/60000de68f440e0008a1579e

😎 Browse the preview: https://deploy-preview-7270--dgraph-docs.netlify.app

@JatinDev543 JatinDev543 merged commit fde1031 into master Jan 14, 2021
@JatinDev543 JatinDev543 deleted the jatin.GRAPHQL-948 branch January 14, 2021 10:34
JatinDev543 added a commit that referenced this pull request Jan 15, 2021
…selecting one of the latest added nodes, and add dgraph type to cors. (#7270)

Fixes GRAPHQL-948
We already fixed the issue which causes dgraph to have multiple schema or cores nodes. But there are some cases in which this bug can occur again, for example, someone restored a backup that was taken before the fix. This bug continuously fill the logs on alpha and blocks graphql layer. Then we can't do mutate/query or add schema.

Now, we are changing this behavior, if we have multiple schema or cores nodes then we will select the one which was added last.
In addition to it, we are adding dgraph.type.cors type to to the dgraph.cors node, which allow us to use delete (S * *) type mutation on it, in case we want to delete extra node manually.

(cherry picked from commit fde1031)
JatinDev543 added a commit that referenced this pull request Jan 15, 2021
…selecting one of the latest added nodes, and add dgraph type to cors. (#7270) (#7302)

* Fix(GraphQL): This PR fix multi cors and multi schema nodes issue by selecting one of the latest added nodes, and add dgraph type to cors. (#7270)

Fixes GRAPHQL-948
We already fixed the issue which causes dgraph to have multiple schema or cores nodes. But there are some cases in which this bug can occur again, for example, someone restored a backup that was taken before the fix. This bug continuously fill the logs on alpha and blocks graphql layer. Then we can't do mutate/query or add schema.

Now, we are changing this behavior, if we have multiple schema or cores nodes then we will select the one which was added last.
In addition to it, we are adding dgraph.type.cors type to to the dgraph.cors node, which allow us to use delete (S * *) type mutation on it, in case we want to delete extra node manually.

(cherry picked from commit fde1031)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/graphql Issues related to GraphQL support on Dgraph. area/schema Issues related to the schema language and capabilities.
Development

Successfully merging this pull request may close these issues.

3 participants