Update mutation removing connection between nodes in one field and setting the connection on a different field fails


Report a GraphQL Bug

What edition and version of Dgraph are you using?

Edition:

  • SlashGraphQL
  • Dgraph (community edition/Dgraph Cloud)

If you are using the community edition or enterprise edition of Dgraph, please list the version:

Dgraph Version
$ dgraph version
 
v21.03.0

Have you tried reproducing the issue with the latest release?

yes

Steps to reproduce the issue (paste the query/schema if possible)

Using docker-compose:

version: "3.8"
services:
  zero1:
    image: dgraph/dgraph:v21.03.0 # latest release
    working_dir: /data/zero1
    ports:
      - 5080:5080
      - 6080:6080
    labels:
      cluster: test
      service: zero1
    volumes:
      - ~/dgraph:/dgraph
    restart: on-failure
    command: dgraph zero
      --logtostderr -v=2
      --bindall
      --expose_trace
      --profile_mode block
      --block_rate 10
      --my=zero1:5080
  alpha1:
    image: dgraph/dgraph:v21.03.0 # latest release
    working_dir: /data/alpha1
    volumes:
      - ~/dgraph:/dgraph
    ports:
      - 8080:8080
      - 9080:9080
    labels:
      cluster: test
      service: alpha1
    restart: on-failure
    command: dgraph alpha 
      --zero=zero1:5080
      --expose_trace
      --profile_mode block
      --block_rate 10
      --logtostderr 
      -v=2
      --my=alpha1:7080
      --bindall
      --security whitelist=0.0.0.0/0
      --graphql lambda_url=http://lambda:8686/graphql-worker

  lambda:
    image: dgraph/dgraph-lambda
    labels:
      cluster: test
    ports:
      - 8686:8686
    depends_on:
      - alpha1
    environment:
      DGRAPH_URL: http://alpha1:8080
    volumes:
      - type: bind
        source: ./dist/src/dgraph/lambdas/lambdas.js
        target: /app/script/script.js
        read_only: true

Simplified schema

interface NodeBase {
  id: ID!
  description: String
}
type Person implements NodeBase  {
  attempted: [PersonalActivityType]
  plannedConversations: [Conversation]
}
type PersonalActivity implements NodeBase {
  name: String
}
type Convo1 implements NodeBase {
  type: String!
}
type Convo2 implements NodeBase {
  thing: String!
}
union Conversation = Convo1 | Convo2
union PersonalActivityType = Convo1 | Convo2 | PersonalActivity

Add Person with plannedConversations, return person with their plannedConversations:

mutation ($person: AddPersonInput!) {
  addPerson (input: [$person]) {
    person {
      id
      plannedConversations { ...on Convo1 {id __typename} ...on Convo2 {id __typename} }
      attempted { ...on Convo1 {id __typename} ...on Convo2 {id __typename} }
    }
  }
}

with $person variable:

  "person": {
    "plannedConversations": [
      { "convo1Ref": { "type": "yes" } },
      { "convo2Ref": { "thing": "no" } }
    ]
  }

Remove plannedConversations, and set them as attempted:

mutation ($patch: UpdatePersonInput!) {
  updatePerson (input: $patch) {
    person {
      id
      plannedConversations { ...on Convo1 {id __typename} ...on Convo2 {id __typename} }
      attempted { ...on Convo1 {id __typename} ...on Convo2 {id __typename} }
    }
  }
}

with $patch variable:

  "patch": {
    "filter": { "id": ["0x3de23dd12"] },
    "set": { "attempted": [{ "convo1Ref": { "id": "CONVO1_ID" } }, { "convo2Ref": { "id": "CONVO2_ID" } }] },
    "remove": { "plannedConversations": [{ "convo1Ref": { "id": "CONVO1_ID" } }, { "convo2Ref": { "id": "CONVO2_ID" } }] }
  }

Expected behaviour and actual result.

Expected Behavior:
This should result in the Person’s plannedConversations being an empty array. The Person’s attempted should have both conversations.

Actual Result:
The request just drags on for minutes on end without receiving a response. And future queryPerson operations requesting the same return as that which is in the mutations above stall out in the same way. No error. Just no response.

And this happens anytime thereafter that I try to query that person’s attempted field.

Other Important Notes:

  • Running the update with only set OR only remove works as expected. However, running one after the other results in the same no-response problem on the second update (no matter which was first).
  • Simultaneously setting both conversations as attempted and removing one (either one) from plannedConversations works just fine as well. But if another update removes the final conversation from plannedConversations, the same problem arises.
  • This behavior is the same regardless of how many conversations are added. If there are 5, up to 4 can be removed from planned and put into attempted with no issues. But when the last one is removed from planned, the problem arises.
  • After running into this problem, when I run docker-compose down, the logs say there was a MEMORY LEAK detected:

Update:

It does appear to work with Dgraph Cloud. I don’t understand why it wouldn’t work with the local docker spinup. I’ve restarted everything multiple times, even updated Docker Desktop. It breaks with my actual, complicated schema and with this simplified schema.

The error is FetchError: request to http://localhost:8080/graphql failed, reason: socket hang up.

1 Like