Create different number noder when run same code

bug

(Magichan) #1

Hi, I run the same code multiple times in WSL(ubuntu 18.04), but the results are not consistent each time.
The Code is

package main
import (
	"fmt"
	"log"
	"github.com/neo4j/neo4j-go-driver/neo4j"
)

func main() {

	driver, err := neo4j.NewDriver("bolt://localhost:7687",
		neo4j.BasicAuth("name", "password", ""))
	if err != nil {
		log.Fatalln(err)
	}
	session, err := driver.Session(neo4j.AccessModeWrite)
	if err != nil {
		log.Fatalln(err)
	}

	contractName := []string{"1A", "2B", "3C", "4D"}
     // Create four node with name 
	for _, v := range contractName {
		_, err := session.Run("CREATE(c:Contract{name:$name}) RETURN c.name", map[string]interface{}{
			"name": v})
		if err != nil {
			fmt.Println("Error")
		}
	}
}

Some time I only get three node, sometime i get four node

But if I change code like this:

package main

import (
	"fmt"
	"log"

	"github.com/neo4j/neo4j-go-driver/neo4j"
)

func main() {

	driver, err := neo4j.NewDriver("bolt://localhost:7687",
		neo4j.BasicAuth("name", "password![2|690x365](upload://jSeMFfB6Nlu0XbDCyVxcnniyHBs.png) ", ""))
	if err != nil {
		log.Fatalln(err)
	}
	session, err := driver.Session(neo4j.AccessModeWrite)
	if err != nil {
		log.Fatalln(err)
	}
	contractName := []string{"1A", "2B", "3C", "4D"}
     // Create four node with name  and print return
	for _, v := range contractName {
		result, err := session.Run("CREATE(c:Contract{name:$name}) RETURN c.name", map[string]interface{}{
			"name": v})
		if err != nil {
			fmt.Println("Error")
		}
		for result.Next() {
			fmt.Printf("Create Contract Node with name=%s\n", result.Record().GetByIndex(0).(string))
		}
	}
}

the logic is same, but i get four node everytime.


Please tell me what i do wrong.


(Ali Ince) #2

Hi @magichan,

The problem with the inconsistent code is that you don't close open resources. You should be closing all of the resources you've opened, i.e. drivers/sessions and results. In your scenario, you send a statement without waiting for it to be processed by the server and send another one (which implicitly causes the previous one's result stream to be consumed). For the previous ones that seem to be ok but the last one may not even get executed since your function completes as soon as you send the run command.

A correct implementation (just written up here, may include typos) should close/consume all opened resources, like the following;

package main
import (
	"fmt"
	"log"
	"github.com/neo4j/neo4j-go-driver/neo4j"
)

func main() {

	driver, err := neo4j.NewDriver("bolt://localhost:7687",
		neo4j.BasicAuth("name", "password", ""))
	if err != nil {
		log.Fatalln(err)
	}
    defer driver.Close()

	session, err := driver.Session(neo4j.AccessModeWrite)
	if err != nil {
		log.Fatalln(err)
	}
    defer session.Close()

	contractName := []string{"1A", "2B", "3C", "4D"}
     // Create four node with name 
	for _, v := range contractName {
		result, err := session.Run("CREATE(c:Contract{name:$name}) RETURN c.name", map[string]interface{}{
			"name": v})
		if err != nil {
			fmt.Println("Error")
		}

        _, err = result.Consume()
        if err != nil {
			fmt.Println("Error")
		}
	}
}

Thanks.


(Magichan) #3

Thank you, I will check it.