schwartzmx / gremtune

Golang Gremlin Tinkerpop client with AWS Neptune compatibility
MIT License
26 stars 19 forks source link

Pool of 5 connections is taking longer to execute than 1 client connection. #8

Open kalpanathakur08 opened 4 years ago

kalpanathakur08 commented 4 years ago

I am trying to use the gremtune pool. I did POC using single client connection vs pool. My understanding was pool must perform better given there's pool of connections but seen single client connection is operating better than pool.

here's my code, please suggest if I am missing anything

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "time"

    "github.com/schwartzmx/gremtune"
)

const (
    userName              = ""
    password              = ""
    timeout               = 5
    pingInterval          = 60
    writingWait           = 15
    readingWait           = 15
    maxActiveConnection   = 5
    connectionIdleTimeout = 30
)

func main() {

    client := oneConnection()
    pool := poolNew()

    for i := 0; i < 10; i++ {
        fmt.Printf("----%d-----\n", i)
        profileOneConnection(client)
        profilePoolconnection(pool)

    }

}

func oneConnection() *gremtune.Client {
    errs := make(chan error)
    go func(chan error) {
        err := <-errs
        log.Fatal("Lost connection to the database: " + err.Error())
    }(errs) // Example of connection error handling logic

    dialer := gremtune.NewDialer("ws://localhost:8182") // Returns a WebSocket dialer to connect to Gremlin Server
    g, err := gremtune.Dial(dialer, errs)               // Returns a gremtune client to interact with
    if err != nil {
        fmt.Println(err)
    }
    return &g

}

func profileOneConnection(client *gremtune.Client) {
    t1 := time.Now()
    getByOneConn(client)
    t2 := time.Now()
    diff := t2.Sub(t1)
    fmt.Printf("Single connection time :: %s\n", diff)
    time.Sleep(1 * time.Second)
}

func getByOneConn(client *gremtune.Client) {
    count := 100
    chanWait := make(chan int, count)
    for i := 0; i < count; i++ {
        go func() {
            res, err := client.Execute( // Sends a query to Gremlin Server
                "g.V('b1492039-eb11-517c-8d2a-a34d2059188e')",
            )
            if err != nil {
                fmt.Println(err)

            }

            _, err = json.Marshal(res[0].Result.Data) // res will return a list of resultsets,  where the data is a json.RawMessage
            if err != nil {
                fmt.Println(err)

            }
            chanWait <- i

        }()

    }
    for i := 0; i < count; i++ {
        <-chanWait
    }

}

func poolNew() *gremtune.Pool {

    var gperrs = make(chan error)
    go func(chan error) {
        err := <-gperrs
        log.Fatal("Lost connection to the database: " + err.Error())
    }(gperrs)

    dialFn := func() (*gremtune.Client, error) {
        dialer := gremtune.NewDialer("ws://localhost:8182")
        c, err := gremtune.Dial(dialer, gperrs)
        if err != nil {
            log.Fatal(err)
        }
        return &c, err
    }
    pool := gremtune.Pool{
        Dial:        dialFn,
        MaxActive:   maxActiveConnection,
        IdleTimeout: time.Duration(10 * time.Second),
    }
    return &pool
}

func profilePoolconnection(pool *gremtune.Pool) {
    t1 := time.Now()
    getUsingPool(pool)
    t2 := time.Now()
    diff := t2.Sub(t1)
    fmt.Printf("Pool connection time %s \n", diff)
}

func getUsingPool(pool *gremtune.Pool) {
    count := 100
    chanWait := make(chan int, count)
    for i := 0; i < count; i++ {
        go func() {
            res, err := pool.Execute( // Sends a query to Gremlin Server
                "g.V('b1492039-eb11-517c-8d2a-a34d2059188e')",
            )
            if err != nil {
                fmt.Println(err)

            }

            _, err = json.Marshal(res[0].Result.Data) // res will return a list of resultsets,  where the data is a json.RawMessage
            if err != nil {
                fmt.Println(err)

            }
            chanWait <- i

        }()
    }
    for i := 0; i < count; i++ {
        <-chanWait
    }
}
kalpanathakur08 commented 4 years ago
100 Get, loop 10 times

----0-----
Single connection time :: 374.310403ms
Pool connection time 5.801515553s
----1-----
Single connection time :: 372.129675ms
Pool connection time 659.972796ms
----2-----
Single connection time :: 375.152791ms
Pool connection time 666.440753ms
----3-----
Single connection time :: 380.741529ms
Pool connection time 684.330146ms
----4-----
Single connection time :: 379.017799ms
Pool connection time 662.868172ms
----5-----
Single connection time :: 379.667604ms
Pool connection time 666.33727ms
----6-----
Single connection time :: 379.812183ms
Pool connection time 664.622033ms
----7-----
Single connection time :: 382.743076ms
Pool connection time 664.403443ms
----8-----
Single connection time :: 382.961919ms
Pool connection time 665.193827ms
----9-----
Single connection time :: 377.379946ms
Pool connection time 662.831724ms

1000 Get, loop 10 times

----0-----
Single connection time :: 1.34967213s
Pool connection time 18.247864785s
----1-----
Single connection time :: 1.292962257s
Pool connection time 13.080666451s
----2-----
Single connection time :: 1.291708217s
Pool connection time 13.080030813s
----3-----
Single connection time :: 1.287039897s
Pool connection time 13.099999333s
----4-----
Single connection time :: 1.254268393s
Pool connection time 13.092294845s
----5-----
Single connection time :: 1.287178614s
Pool connection time 13.103195055s
----6-----
Single connection time :: 1.300647412s
Pool connection time 13.07716571s
----7-----
Single connection time :: 1.26925581s
Pool connection time 13.071782297s
----8-----
Single connection time :: 1.319527638s
Pool connection time 13.072152108s
----9-----
Single connection time :: 1.311900871s
Pool connection time 13.058643805s