From d52ac8b1d159d382ea9a11824ceae0b29da70a95 Mon Sep 17 00:00:00 2001 From: Matt Devy Date: Mon, 24 Nov 2025 11:40:00 +0000 Subject: [PATCH 1/6] feat: adds Close method to BaseClient --- Makefile | 14 +- _benchmarks/benchmarks/go.mod | 2 +- _examples/bulk/benchmarks/go.mod | 5 +- _examples/bulk/benchmarks/go.sum | 10 +- _examples/bulk/default.go | 8 + _examples/bulk/go.mod | 4 +- _examples/bulk/go.sum | 8 +- _examples/bulk/kafka/go.mod | 2 +- _examples/bulk/kafka/go.sum | 4 +- _examples/cloudfunction/go.mod | 2 +- _examples/cloudfunction/go.sum | 4 +- _examples/encoding/easyjson.go | 8 + _examples/encoding/gjson.go | 9 + _examples/encoding/go.mod | 2 +- _examples/encoding/go.sum | 4 +- _examples/encoding/jsonreader.go | 10 ++ _examples/extension/go.mod | 2 +- _examples/extension/go.sum | 6 +- _examples/extension/main.go | 9 + _examples/fasthttp/cmd/main.go | 8 + _examples/fasthttp/go.mod | 2 +- _examples/fasthttp/go.sum | 6 +- _examples/go.mod | 2 +- _examples/go.sum | 12 +- _examples/instrumentation/go.mod | 2 +- _examples/instrumentation/go.sum | 6 +- _examples/instrumentation/opencensus.go | 7 + _examples/logging/custom.go | 8 + _examples/logging/default.go | 6 + _examples/logging/go.mod | 3 +- _examples/logging/go.sum | 22 +-- _examples/main.go | 9 +- _examples/security/go.mod | 3 +- _examples/security/go.sum | 24 +-- _examples/security/tls_configure_ca.go | 9 + _examples/security/tls_with_ca.go | 9 + .../xkcdsearch/cmd/xkcd/commands/index.go | 8 + .../xkcdsearch/cmd/xkcd/commands/search.go | 9 + .../xkcdsearch/cmd/xkcd/commands/server.go | 10 +- _examples/xkcdsearch/go.mod | 5 +- _examples/xkcdsearch/go.sum | 16 +- doc.go | 46 ++--- docs/reference/connecting.md | 21 +++ docs/reference/esql.md | 8 + docs/reference/index.md | 3 + docs/reference/installation.md | 2 + elasticsearch.go | 70 +++++++- elasticsearch_internal_test.go | 161 +++++++++++++++++- esapi/esapi.request.go | 2 - esapi/esapi.response.go | 6 - esutil/bulk_indexer.go | 1 + esutil/bulk_indexer_benchmark_test.go | 3 + esutil/bulk_indexer_example_test.go | 7 + esutil/doc.go | 1 - esutil/json_reader.go | 5 - go.mod | 2 +- go.sum | 4 +- internal/testing/go.mod | 2 +- internal/testing/go.sum | 4 +- 59 files changed, 513 insertions(+), 134 deletions(-) diff --git a/Makefile b/Makefile index 2b2b924f2a..39ddbd0b39 100644 --- a/Makefile +++ b/Makefile @@ -126,19 +126,7 @@ test-examples: ## Execute the _examples false; \ ); \ done; \ - );\ -# \ -# for f in _examples/*/; do \ -# printf "\033[2m────────────────────────────────────────────────────────────────────────────────\033[0m\n"; \ -# printf "\033[1m$$f\033[0m\n"; \ -# printf "\033[2m────────────────────────────────────────────────────────────────────────────────\033[0m\n"; \ -# (cd $$f && make test && true) || \ -# ( \ -# printf "\033[31m────────────────────────────────────────────────────────────────────────────────\033[0m\n"; \ -# printf "\033[31;1m⨯ ERROR\033[0m\n"; \ -# false; \ -# ); \ -# done; \ + ); \ printf "\033[32m────────────────────────────────────────────────────────────────────────────────\033[0m\n"; \ \ printf "\033[32;1mSUCCESS\033[0m\n"; \ diff --git a/_benchmarks/benchmarks/go.mod b/_benchmarks/benchmarks/go.mod index a80503c5a2..d99ccf45ca 100644 --- a/_benchmarks/benchmarks/go.mod +++ b/_benchmarks/benchmarks/go.mod @@ -7,7 +7,7 @@ toolchain go1.24.2 replace github.com/elastic/go-elasticsearch/v9 => ../../ require ( - github.com/elastic/elastic-transport-go/v8 v8.7.0 + github.com/elastic/elastic-transport-go/v8 v8.8.0 github.com/elastic/go-elasticsearch/v9 v9.0.0-00010101000000-000000000000 github.com/fatih/color v1.7.0 github.com/montanaflynn/stats v0.6.3 diff --git a/_examples/bulk/benchmarks/go.mod b/_examples/bulk/benchmarks/go.mod index 17c19591f5..915f61de30 100644 --- a/_examples/bulk/benchmarks/go.mod +++ b/_examples/bulk/benchmarks/go.mod @@ -9,14 +9,15 @@ replace github.com/elastic/go-elasticsearch/v9 => ../../.. require ( github.com/dustin/go-humanize v1.0.0 github.com/elastic/go-elasticsearch/v9 v9.0.0-20210817150010-57d659deaca7 - github.com/mailru/easyjson v0.7.1 github.com/montanaflynn/stats v0.6.3 ) require ( - github.com/elastic/elastic-transport-go/v8 v8.7.0 // indirect + github.com/elastic/elastic-transport-go/v8 v8.8.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/otel v1.35.0 // indirect go.opentelemetry.io/otel/metric v1.35.0 // indirect diff --git a/_examples/bulk/benchmarks/go.sum b/_examples/bulk/benchmarks/go.sum index 8be8efb00d..cddd81326f 100644 --- a/_examples/bulk/benchmarks/go.sum +++ b/_examples/bulk/benchmarks/go.sum @@ -2,8 +2,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/elastic/elastic-transport-go/v8 v8.7.0 h1:OgTneVuXP2uip4BA658Xi6Hfw+PeIOod2rY3GVMGoVE= -github.com/elastic/elastic-transport-go/v8 v8.7.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/elastic-transport-go/v8 v8.8.0 h1:7k1Ua+qluFr6p1jfJjGDl97ssJS/P7cHNInzfxgBQAo= +github.com/elastic/elastic-transport-go/v8 v8.8.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -11,8 +11,10 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/mailru/easyjson v0.7.1 h1:mdxE1MF9o53iCb2Ghj1VfWvh7ZOwHpnVG/xwXrV90U8= -github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/montanaflynn/stats v0.6.3 h1:F8446DrvIF5V5smZfZ8K9nrmmix0AFgevPdLruGOmzk= github.com/montanaflynn/stats v0.6.3/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/_examples/bulk/default.go b/_examples/bulk/default.go index 429a95336e..6e564ac528 100644 --- a/_examples/bulk/default.go +++ b/_examples/bulk/default.go @@ -33,6 +33,7 @@ package main import ( "bytes" + "context" "encoding/json" "flag" "fmt" @@ -125,6 +126,13 @@ func main() { if err != nil { log.Fatalf("Error creating the client: %s", err) } + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := es.Close(ctx); err != nil { + log.Fatalf("Error closing the client: %s", err) + } + }() // Generate the articles collection // diff --git a/_examples/bulk/go.mod b/_examples/bulk/go.mod index d7f0326b11..bce3f214aa 100644 --- a/_examples/bulk/go.mod +++ b/_examples/bulk/go.mod @@ -13,9 +13,11 @@ require ( ) require ( - github.com/elastic/elastic-transport-go/v8 v8.7.0 // indirect + github.com/elastic/elastic-transport-go/v8 v8.8.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/otel v1.35.0 // indirect go.opentelemetry.io/otel/metric v1.35.0 // indirect diff --git a/_examples/bulk/go.sum b/_examples/bulk/go.sum index d20ec81c50..02b263a6f8 100644 --- a/_examples/bulk/go.sum +++ b/_examples/bulk/go.sum @@ -4,8 +4,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/elastic/elastic-transport-go/v8 v8.7.0 h1:OgTneVuXP2uip4BA658Xi6Hfw+PeIOod2rY3GVMGoVE= -github.com/elastic/elastic-transport-go/v8 v8.7.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/elastic-transport-go/v8 v8.8.0 h1:7k1Ua+qluFr6p1jfJjGDl97ssJS/P7cHNInzfxgBQAo= +github.com/elastic/elastic-transport-go/v8 v8.8.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -13,10 +13,14 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= diff --git a/_examples/bulk/kafka/go.mod b/_examples/bulk/kafka/go.mod index cd444fd3ad..e3eb2636f4 100644 --- a/_examples/bulk/kafka/go.mod +++ b/_examples/bulk/kafka/go.mod @@ -14,7 +14,7 @@ require ( require ( github.com/armon/go-radix v1.0.0 // indirect - github.com/elastic/elastic-transport-go/v8 v8.7.0 // indirect + github.com/elastic/elastic-transport-go/v8 v8.8.0 // indirect github.com/elastic/go-licenser v0.3.1 // indirect github.com/elastic/go-sysinfo v1.1.1 // indirect github.com/elastic/go-windows v1.0.0 // indirect diff --git a/_examples/bulk/kafka/go.sum b/_examples/bulk/kafka/go.sum index 3ae05b0ae3..a26aa00af3 100644 --- a/_examples/bulk/kafka/go.sum +++ b/_examples/bulk/kafka/go.sum @@ -5,8 +5,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/elastic/elastic-transport-go/v8 v8.7.0 h1:OgTneVuXP2uip4BA658Xi6Hfw+PeIOod2rY3GVMGoVE= -github.com/elastic/elastic-transport-go/v8 v8.7.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/elastic-transport-go/v8 v8.8.0 h1:7k1Ua+qluFr6p1jfJjGDl97ssJS/P7cHNInzfxgBQAo= +github.com/elastic/elastic-transport-go/v8 v8.8.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= github.com/elastic/go-licenser v0.3.1 h1:RmRukU/JUmts+rpexAw0Fvt2ly7VVu6mw8z4HrEzObU= github.com/elastic/go-licenser v0.3.1/go.mod h1:D8eNQk70FOCVBl3smCGQt/lv7meBeQno2eI1S5apiHQ= github.com/elastic/go-sysinfo v1.1.1 h1:ZVlaLDyhVkDfjwPGU55CQRCRolNpc7P0BbyhhQZQmMI= diff --git a/_examples/cloudfunction/go.mod b/_examples/cloudfunction/go.mod index 3c58d9bff1..3402be903d 100644 --- a/_examples/cloudfunction/go.mod +++ b/_examples/cloudfunction/go.mod @@ -9,7 +9,7 @@ replace github.com/elastic/go-elasticsearch/v9 => ../.. require github.com/elastic/go-elasticsearch/v9 v9.0.0-00010101000000-000000000000 require ( - github.com/elastic/elastic-transport-go/v8 v8.7.0 // indirect + github.com/elastic/elastic-transport-go/v8 v8.8.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect diff --git a/_examples/cloudfunction/go.sum b/_examples/cloudfunction/go.sum index 765694010b..592b30bbe7 100644 --- a/_examples/cloudfunction/go.sum +++ b/_examples/cloudfunction/go.sum @@ -1,7 +1,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/elastic/elastic-transport-go/v8 v8.7.0 h1:OgTneVuXP2uip4BA658Xi6Hfw+PeIOod2rY3GVMGoVE= -github.com/elastic/elastic-transport-go/v8 v8.7.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/elastic-transport-go/v8 v8.8.0 h1:7k1Ua+qluFr6p1jfJjGDl97ssJS/P7cHNInzfxgBQAo= +github.com/elastic/elastic-transport-go/v8 v8.8.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= diff --git a/_examples/encoding/easyjson.go b/_examples/encoding/easyjson.go index fd7c3f966a..3859590535 100644 --- a/_examples/encoding/easyjson.go +++ b/_examples/encoding/easyjson.go @@ -19,6 +19,7 @@ package main import ( "bytes" + "context" "fmt" "math/rand" "os" @@ -56,6 +57,13 @@ func main() { fmt.Printf("Error creating the client: %s\n", err) os.Exit(2) } + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := es.Close(ctx); err != nil { + fmt.Printf("Error closing the client: %s\n", err) + } + }() fnames = []string{"Alice", "John", "Mary"} diff --git a/_examples/encoding/gjson.go b/_examples/encoding/gjson.go index 6aa9e66826..084e6350d2 100644 --- a/_examples/encoding/gjson.go +++ b/_examples/encoding/gjson.go @@ -19,10 +19,12 @@ package main import ( "bytes" + "context" "fmt" "io" "log" "strings" + "time" "github.com/elastic/go-elasticsearch/v9" "github.com/fatih/color" @@ -43,6 +45,13 @@ func main() { if err != nil { log.Fatalf("Error creating client: %s", err) } + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := es.Close(ctx); err != nil { + fmt.Printf("Error closing the client: %s\n", err) + } + }() res, err := es.Cluster.Stats(es.Cluster.Stats.WithHuman()) if err != nil { diff --git a/_examples/encoding/go.mod b/_examples/encoding/go.mod index 71c965e76d..d6a05f2ba9 100644 --- a/_examples/encoding/go.mod +++ b/_examples/encoding/go.mod @@ -14,7 +14,7 @@ require ( ) require ( - github.com/elastic/elastic-transport-go/v8 v8.7.0 // indirect + github.com/elastic/elastic-transport-go/v8 v8.8.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/josharian/intern v1.0.0 // indirect diff --git a/_examples/encoding/go.sum b/_examples/encoding/go.sum index b05baf5cbc..6510cc2fff 100644 --- a/_examples/encoding/go.sum +++ b/_examples/encoding/go.sum @@ -1,7 +1,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/elastic/elastic-transport-go/v8 v8.7.0 h1:OgTneVuXP2uip4BA658Xi6Hfw+PeIOod2rY3GVMGoVE= -github.com/elastic/elastic-transport-go/v8 v8.7.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/elastic-transport-go/v8 v8.8.0 h1:7k1Ua+qluFr6p1jfJjGDl97ssJS/P7cHNInzfxgBQAo= +github.com/elastic/elastic-transport-go/v8 v8.8.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= diff --git a/_examples/encoding/jsonreader.go b/_examples/encoding/jsonreader.go index 47b071d192..ba99b12e13 100644 --- a/_examples/encoding/jsonreader.go +++ b/_examples/encoding/jsonreader.go @@ -18,7 +18,10 @@ package main import ( + "context" + "fmt" "log" + "time" "github.com/elastic/go-elasticsearch/v9" "github.com/elastic/go-elasticsearch/v9/esapi" @@ -39,6 +42,13 @@ func main() { if err != nil { log.Fatalf("Error creating the client: %s", err) } + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := es.Close(ctx); err != nil { + fmt.Printf("Error closing the client: %s\n", err) + } + }() doc := struct { Title string `json:"title"` diff --git a/_examples/extension/go.mod b/_examples/extension/go.mod index 7fb459500f..dd64b1c4de 100644 --- a/_examples/extension/go.mod +++ b/_examples/extension/go.mod @@ -7,7 +7,7 @@ toolchain go1.24.2 replace github.com/elastic/go-elasticsearch/v9 => ../.. require ( - github.com/elastic/elastic-transport-go/v8 v8.7.0 + github.com/elastic/elastic-transport-go/v8 v8.8.0 github.com/elastic/go-elasticsearch/v9 v9.0.0-00010101000000-000000000000 ) diff --git a/_examples/extension/go.sum b/_examples/extension/go.sum index f0c09061bf..592b30bbe7 100644 --- a/_examples/extension/go.sum +++ b/_examples/extension/go.sum @@ -1,9 +1,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/elastic/elastic-transport-go/v8 v8.6.1 h1:h2jQRqH6eLGiBSN4eZbQnJLtL4bC5b4lfVFRjw2R4e4= -github.com/elastic/elastic-transport-go/v8 v8.6.1/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= -github.com/elastic/elastic-transport-go/v8 v8.7.0 h1:OgTneVuXP2uip4BA658Xi6Hfw+PeIOod2rY3GVMGoVE= -github.com/elastic/elastic-transport-go/v8 v8.7.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/elastic-transport-go/v8 v8.8.0 h1:7k1Ua+qluFr6p1jfJjGDl97ssJS/P7cHNInzfxgBQAo= +github.com/elastic/elastic-transport-go/v8 v8.8.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= diff --git a/_examples/extension/main.go b/_examples/extension/main.go index 80d00af8f4..ed129c6904 100644 --- a/_examples/extension/main.go +++ b/_examples/extension/main.go @@ -23,6 +23,7 @@ package main import ( + "context" "io" "log" "net" @@ -30,6 +31,7 @@ import ( "net/http/httputil" "net/url" "os" + "time" "github.com/elastic/elastic-transport-go/v8/elastictransport" "github.com/elastic/go-elasticsearch/v9" @@ -77,6 +79,13 @@ func main() { if err != nil { log.Fatalf("Error creating the client: %s", err) } + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := esclient.Close(ctx); err != nil { + log.Fatalf("Error closing the client: %s\n", err) + } + }() es := ExtendedClient{Client: esclient, Custom: &ExtendedAPI{esclient}} <-started diff --git a/_examples/fasthttp/cmd/main.go b/_examples/fasthttp/cmd/main.go index 3ed7ba1440..00f1f0daf2 100644 --- a/_examples/fasthttp/cmd/main.go +++ b/_examples/fasthttp/cmd/main.go @@ -19,6 +19,7 @@ package main import ( "context" + "fmt" "log" "os" "sort" @@ -56,6 +57,13 @@ func main() { if err != nil { log.Fatalf("Error creating the client: %s", err) } + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := es.Close(ctx); err != nil { + fmt.Printf("Error closing the client: %s\n", err) + } + }() // Test sending the body as POST // diff --git a/_examples/fasthttp/go.mod b/_examples/fasthttp/go.mod index f3303d1e15..c1f93efb7b 100644 --- a/_examples/fasthttp/go.mod +++ b/_examples/fasthttp/go.mod @@ -13,7 +13,7 @@ require ( require ( github.com/andybalholm/brotli v1.0.4 // indirect - github.com/elastic/elastic-transport-go/v8 v8.7.0 // indirect + github.com/elastic/elastic-transport-go/v8 v8.8.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/klauspost/compress v1.15.0 // indirect diff --git a/_examples/fasthttp/go.sum b/_examples/fasthttp/go.sum index 0608ed7430..74b84e8cfc 100644 --- a/_examples/fasthttp/go.sum +++ b/_examples/fasthttp/go.sum @@ -2,10 +2,8 @@ github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/elastic/elastic-transport-go/v8 v8.6.1 h1:h2jQRqH6eLGiBSN4eZbQnJLtL4bC5b4lfVFRjw2R4e4= -github.com/elastic/elastic-transport-go/v8 v8.6.1/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= -github.com/elastic/elastic-transport-go/v8 v8.7.0 h1:OgTneVuXP2uip4BA658Xi6Hfw+PeIOod2rY3GVMGoVE= -github.com/elastic/elastic-transport-go/v8 v8.7.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/elastic-transport-go/v8 v8.8.0 h1:7k1Ua+qluFr6p1jfJjGDl97ssJS/P7cHNInzfxgBQAo= +github.com/elastic/elastic-transport-go/v8 v8.8.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= diff --git a/_examples/go.mod b/_examples/go.mod index edcb25d344..c7fb7471f2 100644 --- a/_examples/go.mod +++ b/_examples/go.mod @@ -9,7 +9,7 @@ replace github.com/elastic/go-elasticsearch/v9 => ../ require github.com/elastic/go-elasticsearch/v9 v9.0.0-00010101000000-000000000000 require ( - github.com/elastic/elastic-transport-go/v8 v8.7.0 // indirect + github.com/elastic/elastic-transport-go/v8 v8.8.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect diff --git a/_examples/go.sum b/_examples/go.sum index 9bac8f415b..592b30bbe7 100644 --- a/_examples/go.sum +++ b/_examples/go.sum @@ -1,7 +1,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/elastic/elastic-transport-go/v8 v8.7.0 h1:OgTneVuXP2uip4BA658Xi6Hfw+PeIOod2rY3GVMGoVE= -github.com/elastic/elastic-transport-go/v8 v8.7.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/elastic-transport-go/v8 v8.8.0 h1:7k1Ua+qluFr6p1jfJjGDl97ssJS/P7cHNInzfxgBQAo= +github.com/elastic/elastic-transport-go/v8 v8.8.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -9,8 +9,14 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= @@ -25,5 +31,7 @@ go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/_examples/instrumentation/go.mod b/_examples/instrumentation/go.mod index 038828d4f0..05255cc909 100644 --- a/_examples/instrumentation/go.mod +++ b/_examples/instrumentation/go.mod @@ -7,7 +7,7 @@ toolchain go1.24.2 replace github.com/elastic/go-elasticsearch/v9 => ../.. require ( - github.com/elastic/elastic-transport-go/v8 v8.7.0 + github.com/elastic/elastic-transport-go/v8 v8.8.0 github.com/elastic/go-elasticsearch/v9 v9.0.0-00010101000000-000000000000 github.com/fatih/color v1.7.0 go.elastic.co/apm v1.11.0 diff --git a/_examples/instrumentation/go.sum b/_examples/instrumentation/go.sum index 1f3349cf19..69523e1176 100644 --- a/_examples/instrumentation/go.sum +++ b/_examples/instrumentation/go.sum @@ -14,10 +14,8 @@ github.com/cucumber/godog v0.8.1/go.mod h1:vSh3r/lM+psC1BPXvdkSEuNjmXfpVqrMGYAEl github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/elastic/elastic-transport-go/v8 v8.6.1 h1:h2jQRqH6eLGiBSN4eZbQnJLtL4bC5b4lfVFRjw2R4e4= -github.com/elastic/elastic-transport-go/v8 v8.6.1/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= -github.com/elastic/elastic-transport-go/v8 v8.7.0 h1:OgTneVuXP2uip4BA658Xi6Hfw+PeIOod2rY3GVMGoVE= -github.com/elastic/elastic-transport-go/v8 v8.7.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/elastic-transport-go/v8 v8.8.0 h1:7k1Ua+qluFr6p1jfJjGDl97ssJS/P7cHNInzfxgBQAo= +github.com/elastic/elastic-transport-go/v8 v8.8.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= github.com/elastic/go-sysinfo v1.0.1/go.mod h1:O/D5m1VpYLwGjCYzEt63g3Z1uO3jXfwyzzjiW90t8cY= github.com/elastic/go-sysinfo v1.1.1 h1:ZVlaLDyhVkDfjwPGU55CQRCRolNpc7P0BbyhhQZQmMI= github.com/elastic/go-sysinfo v1.1.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0= diff --git a/_examples/instrumentation/opencensus.go b/_examples/instrumentation/opencensus.go index 1f68e0142b..10987082eb 100644 --- a/_examples/instrumentation/opencensus.go +++ b/_examples/instrumentation/opencensus.go @@ -138,6 +138,13 @@ func main() { if err != nil { log.Fatalf("ERROR: %s", err) } + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := es.Close(ctx); err != nil { + fmt.Printf("Error closing the client: %s\n", err) + } + }() // Set up the "done" channel // diff --git a/_examples/logging/custom.go b/_examples/logging/custom.go index 6a047c2219..70f7f85030 100644 --- a/_examples/logging/custom.go +++ b/_examples/logging/custom.go @@ -24,6 +24,7 @@ package main import ( + "context" "io" "io/ioutil" "net/http" @@ -116,6 +117,13 @@ func main() { es, _ := elasticsearch.NewClient(elasticsearch.Config{ Logger: &CustomLogger{log}, }) + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := es.Close(ctx); err != nil { + log.Fatal().Err(err).Msg("Error closing the client") + } + }() // ---------------------------------------------------------------------------------------------- { diff --git a/_examples/logging/default.go b/_examples/logging/default.go index 7acca8762e..69248030eb 100644 --- a/_examples/logging/default.go +++ b/_examples/logging/default.go @@ -27,6 +27,7 @@ package main import ( + "context" "fmt" "log" "os" @@ -49,6 +50,7 @@ func main() { Logger: &elastictransport.TextLogger{Output: os.Stdout}, }) run(es, "Text") + _ = es.Close(context.Background()) // ============================================================================================== // @@ -58,6 +60,7 @@ func main() { Logger: &elastictransport.ColorLogger{Output: os.Stdout}, }) run(es, "Color") + _ = es.Close(context.Background()) // ============================================================================================== // @@ -71,6 +74,7 @@ func main() { }, }) run(es, "Request/Response Body") + _ = es.Close(context.Background()) // ============================================================================================== // @@ -81,6 +85,7 @@ func main() { Logger: &elastictransport.CurlLogger{Output: os.Stdout, EnableRequestBody: true, EnableResponseBody: true}, }) run(es, "Curl") + _ = es.Close(context.Background()) // ============================================================================================== // @@ -90,6 +95,7 @@ func main() { Logger: &elastictransport.JSONLogger{Output: os.Stdout}, }) run(es, "JSON") + _ = es.Close(context.Background()) } // ------------------------------------------------------------------------------------------------ diff --git a/_examples/logging/go.mod b/_examples/logging/go.mod index 5ee2bd2c05..c33a1a5fdc 100644 --- a/_examples/logging/go.mod +++ b/_examples/logging/go.mod @@ -7,7 +7,7 @@ toolchain go1.24.2 replace github.com/elastic/go-elasticsearch/v9 => ../.. require ( - github.com/elastic/elastic-transport-go/v8 v8.7.0 + github.com/elastic/elastic-transport-go/v8 v8.8.0 github.com/elastic/go-elasticsearch/v9 v9.0.0-00010101000000-000000000000 github.com/rs/zerolog v1.32.0 ) @@ -17,6 +17,7 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/otel v1.35.0 // indirect go.opentelemetry.io/otel/metric v1.35.0 // indirect go.opentelemetry.io/otel/trace v1.35.0 // indirect diff --git a/_examples/logging/go.sum b/_examples/logging/go.sum index 80be21d469..6e8753ed0f 100644 --- a/_examples/logging/go.sum +++ b/_examples/logging/go.sum @@ -2,10 +2,8 @@ github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8 github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/elastic/elastic-transport-go/v8 v8.6.1 h1:h2jQRqH6eLGiBSN4eZbQnJLtL4bC5b4lfVFRjw2R4e4= -github.com/elastic/elastic-transport-go/v8 v8.6.1/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= -github.com/elastic/elastic-transport-go/v8 v8.7.0 h1:OgTneVuXP2uip4BA658Xi6Hfw+PeIOod2rY3GVMGoVE= -github.com/elastic/elastic-transport-go/v8 v8.7.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/elastic-transport-go/v8 v8.8.0 h1:7k1Ua+qluFr6p1jfJjGDl97ssJS/P7cHNInzfxgBQAo= +github.com/elastic/elastic-transport-go/v8 v8.8.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -13,10 +11,10 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -28,28 +26,22 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= -go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= -go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= -go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -57,5 +49,7 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/_examples/main.go b/_examples/main.go index 6186d80779..c03617d8fd 100644 --- a/_examples/main.go +++ b/_examples/main.go @@ -30,6 +30,7 @@ import ( "strconv" "strings" "sync" + "time" "github.com/elastic/go-elasticsearch/v9" "github.com/elastic/go-elasticsearch/v9/esapi" @@ -51,7 +52,13 @@ func main() { if err != nil { log.Fatalf("Error creating the client: %s", err) } - + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := es.Close(ctx); err != nil { + log.Fatalf("Error closing the client: %s\n", err) + } + }() // 1. Get cluster info // res, err := es.Info() diff --git a/_examples/security/go.mod b/_examples/security/go.mod index afaafc0f40..09b5fe5275 100644 --- a/_examples/security/go.mod +++ b/_examples/security/go.mod @@ -9,9 +9,10 @@ replace github.com/elastic/go-elasticsearch/v9 => ../.. require github.com/elastic/go-elasticsearch/v9 v9.0.0-00010101000000-000000000000 require ( - github.com/elastic/elastic-transport-go/v8 v8.7.0 // indirect + github.com/elastic/elastic-transport-go/v8 v8.8.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/otel v1.35.0 // indirect go.opentelemetry.io/otel/metric v1.35.0 // indirect go.opentelemetry.io/otel/trace v1.35.0 // indirect diff --git a/_examples/security/go.sum b/_examples/security/go.sum index 0b3abedeab..592b30bbe7 100644 --- a/_examples/security/go.sum +++ b/_examples/security/go.sum @@ -1,45 +1,37 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/elastic/elastic-transport-go/v8 v8.6.1 h1:h2jQRqH6eLGiBSN4eZbQnJLtL4bC5b4lfVFRjw2R4e4= -github.com/elastic/elastic-transport-go/v8 v8.6.1/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= -github.com/elastic/elastic-transport-go/v8 v8.7.0 h1:OgTneVuXP2uip4BA658Xi6Hfw+PeIOod2rY3GVMGoVE= -github.com/elastic/elastic-transport-go/v8 v8.7.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/elastic-transport-go/v8 v8.8.0 h1:7k1Ua+qluFr6p1jfJjGDl97ssJS/P7cHNInzfxgBQAo= +github.com/elastic/elastic-transport-go/v8 v8.8.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= -go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= -go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= -go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/_examples/security/tls_configure_ca.go b/_examples/security/tls_configure_ca.go index c90cc91987..32c8b2444e 100644 --- a/_examples/security/tls_configure_ca.go +++ b/_examples/security/tls_configure_ca.go @@ -21,11 +21,13 @@ package main import ( + "context" "crypto/x509" "flag" "io/ioutil" "log" "net/http" + "time" "github.com/elastic/go-elasticsearch/v9" ) @@ -78,6 +80,13 @@ func main() { if err != nil { log.Fatalf("ERROR: Unable to create client: %s", err) } + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := es.Close(ctx); err != nil { + log.Fatalf("Error closing the client: %s\n", err) + } + }() res, err := es.Info() if err != nil { diff --git a/_examples/security/tls_with_ca.go b/_examples/security/tls_with_ca.go index 52f94afb71..1f7359b75b 100644 --- a/_examples/security/tls_with_ca.go +++ b/_examples/security/tls_with_ca.go @@ -21,9 +21,11 @@ package main import ( + "context" "flag" "io/ioutil" "log" + "time" "github.com/elastic/go-elasticsearch/v9" ) @@ -61,6 +63,13 @@ func main() { if err != nil { log.Fatalf("ERROR: Unable to create client: %s", err) } + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := es.Close(ctx); err != nil { + log.Fatalf("Error closing the client: %s\n", err) + } + }() res, err := es.Info() if err != nil { diff --git a/_examples/xkcdsearch/cmd/xkcd/commands/index.go b/_examples/xkcdsearch/cmd/xkcd/commands/index.go index 1406af5397..3cf680adc4 100644 --- a/_examples/xkcdsearch/cmd/xkcd/commands/index.go +++ b/_examples/xkcdsearch/cmd/xkcd/commands/index.go @@ -18,6 +18,7 @@ package commands import ( + "context" "encoding/json" "fmt" "math/rand" @@ -82,6 +83,13 @@ var indexCmd = &cobra.Command{ if err != nil { crawler.log.Fatal().Err(err).Msg("Error creating Elasticsearch client") } + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := es.Close(ctx); err != nil { + crawler.log.Fatal().Err(err).Msg("Error closing the client") + } + }() config := xkcdsearch.StoreConfig{Client: es, IndexName: IndexName} store, err := xkcdsearch.NewStore(config) diff --git a/_examples/xkcdsearch/cmd/xkcd/commands/search.go b/_examples/xkcdsearch/cmd/xkcd/commands/search.go index 9aeb067332..2f5aac5969 100644 --- a/_examples/xkcdsearch/cmd/xkcd/commands/search.go +++ b/_examples/xkcdsearch/cmd/xkcd/commands/search.go @@ -18,11 +18,13 @@ package commands import ( + "context" "fmt" "io" "os" "regexp" "strings" + "time" "github.com/spf13/cobra" @@ -48,6 +50,13 @@ var searchCmd = &cobra.Command{ if err != nil { fmt.Fprintf(os.Stderr, "\x1b[1;107;41mERROR: %s\x1b[0m\n", err) } + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := es.Close(ctx); err != nil { + fmt.Fprintf(os.Stderr, "Error closing the client: %s\n", err) + } + }() config := xkcdsearch.StoreConfig{Client: es, IndexName: IndexName} store, err := xkcdsearch.NewStore(config) diff --git a/_examples/xkcdsearch/cmd/xkcd/commands/server.go b/_examples/xkcdsearch/cmd/xkcd/commands/server.go index efd1359dc9..e665d5eeec 100644 --- a/_examples/xkcdsearch/cmd/xkcd/commands/server.go +++ b/_examples/xkcdsearch/cmd/xkcd/commands/server.go @@ -18,8 +18,10 @@ package commands import ( + "context" "net/http" "os" + "time" "github.com/rs/zerolog" "github.com/spf13/cobra" @@ -62,7 +64,13 @@ var serverCmd = &cobra.Command{ if err != nil { log.Fatal().Err(err).Msg("Error creating Elasticsearch client") } - + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := es.Close(ctx); err != nil { + log.Fatal().Err(err).Msg("Error closing the client") + } + }() config := xkcdsearch.StoreConfig{Client: es, IndexName: IndexName} store, err := xkcdsearch.NewStore(config) if err != nil { diff --git a/_examples/xkcdsearch/go.mod b/_examples/xkcdsearch/go.mod index 3d45606e14..1bf14fde53 100644 --- a/_examples/xkcdsearch/go.mod +++ b/_examples/xkcdsearch/go.mod @@ -1,6 +1,7 @@ module github.com/elastic/go-elasticsearch/v9/_examples/xkcdsearch -go 1.23 +go 1.23.0 + toolchain go1.24.2 replace github.com/elastic/go-elasticsearch/v9 => ../.. @@ -13,7 +14,7 @@ require ( ) require ( - github.com/elastic/elastic-transport-go/v8 v8.7.0 // indirect + github.com/elastic/elastic-transport-go/v8 v8.8.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect diff --git a/_examples/xkcdsearch/go.sum b/_examples/xkcdsearch/go.sum index c37d8af591..571a7105af 100644 --- a/_examples/xkcdsearch/go.sum +++ b/_examples/xkcdsearch/go.sum @@ -1,7 +1,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/elastic/elastic-transport-go/v8 v8.7.0 h1:OgTneVuXP2uip4BA658Xi6Hfw+PeIOod2rY3GVMGoVE= -github.com/elastic/elastic-transport-go/v8 v8.7.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/elastic-transport-go/v8 v8.8.0 h1:7k1Ua+qluFr6p1jfJjGDl97ssJS/P7cHNInzfxgBQAo= +github.com/elastic/elastic-transport-go/v8 v8.8.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -11,8 +11,14 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/rs/zerolog v1.11.0 h1:DRuq/S+4k52uJzBQciUcofXx45GrMC6yrEbb/CoK6+M= github.com/rs/zerolog v1.11.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= @@ -33,9 +39,15 @@ go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/doc.go b/doc.go index 59a77ba7e4..801becc759 100644 --- a/doc.go +++ b/doc.go @@ -20,31 +20,31 @@ Package elasticsearch provides a Go client for Elasticsearch. Create the client with the NewDefaultClient function: - elasticsearch.NewDefaultClient() + elasticsearch.NewDefaultClient() The ELASTICSEARCH_URL environment variable is used instead of the default URL, when set. Use a comma to separate multiple URLs. To configure the client, pass a Config object to the NewClient function: - cfg := elasticsearch.Config{ - Addresses: []string{ - "http://localhost:9200", - "http://localhost:9201", - }, - Username: "foo", - Password: "bar", - Transport: &http.Transport{ - MaxIdleConnsPerHost: 10, - ResponseHeaderTimeout: time.Second, - DialContext: (&net.Dialer{Timeout: time.Second}).DialContext, - TLSClientConfig: &tls.Config{ - MinVersion: tls.VersionTLS12, - }, - }, - } + cfg := elasticsearch.Config{ + Addresses: []string{ + "http://localhost:9200", + "http://localhost:9201", + }, + Username: "foo", + Password: "bar", + Transport: &http.Transport{ + MaxIdleConnsPerHost: 10, + ResponseHeaderTimeout: time.Second, + DialContext: (&net.Dialer{Timeout: time.Second}).DialContext, + TLSClientConfig: &tls.Config{ + MinVersion: tls.VersionTLS12, + }, + }, + } - elasticsearch.NewClient(cfg) + elasticsearch.NewClient(cfg) When using the Elastic Service (https://elastic.co/cloud), you can use CloudID instead of Addresses. When either Addresses or CloudID is set, the ELASTICSEARCH_URL environment variable is ignored. @@ -53,12 +53,12 @@ See the elasticsearch_integration_test.go file and the _examples folder for more Call the Elasticsearch APIs by invoking the corresponding methods on the client: - res, err := es.Info() - if err != nil { - log.Fatalf("Error getting response: %s", err) - } + res, err := es.Info() + if err != nil { + log.Fatalf("Error getting response: %s", err) + } - log.Println(res) + log.Println(res) See the github.com/elastic/go-elasticsearch/esapi package for more information about using the API. diff --git a/docs/reference/connecting.md b/docs/reference/connecting.md index aaf6a7df12..56f9e9b430 100644 --- a/docs/reference/connecting.md +++ b/docs/reference/connecting.md @@ -214,6 +214,13 @@ es, err := elasticsearch.NewDefaultClient() if err != nil { log.Fatalf("Error creating the client: %s", err) } +defer func() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := es.Close(ctx); err != nil { + log.Fatalf("Error closing the client: %s", err) + } +} () res, err := es.Info() if err != nil { @@ -236,6 +243,11 @@ This section illustrates the best practices for leveraging the {{es}} client in package httpexample import ( + "context" + "net/http" + "time" + "log" + "github.com/elastic/go-elasticsearch/v9" ) @@ -249,6 +261,13 @@ func init() { if err != nil { log.Fatalf("elasticsearch.NewClient: %v", err) } + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := client.Close(ctx); err != nil { + log.Fatalf("Error closing the client: %s", err) + } + } () } func HttpExample(w http.ResponseWriter, r *http.Request) { @@ -263,6 +282,8 @@ func HttpExample(w http.ResponseWriter, r *http.Request) { package httpexample import ( + "log" + "github.com/aws/aws-lambda-go/lambda" "github.com/elastic/go-elasticsearch/v9" ) diff --git a/docs/reference/esql.md b/docs/reference/esql.md index 20529d1efc..4bc0faebdf 100644 --- a/docs/reference/esql.md +++ b/docs/reference/esql.md @@ -58,6 +58,7 @@ import ( "context" "fmt" "log" + "time" "github.com/elastic/go-elasticsearch/v9" "github.com/elastic/go-elasticsearch/v9/typedapi/esql/query" @@ -75,6 +76,13 @@ func main() { if err != nil { log.Fatal(err) } + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + if err := client.Close(ctx); err != nil { + log.Fatal(err) + } + } () queryAuthor := `from library | where author == "Isaac Asimov" diff --git a/docs/reference/index.md b/docs/reference/index.md index 9ce6bd540e..241f58efca 100644 --- a/docs/reference/index.md +++ b/docs/reference/index.md @@ -29,6 +29,7 @@ Full documentation is hosted at [GitHub](https://github.com/elastic/go-elasticse package main import ( + "context" "log" "github.com/elastic/go-elasticsearch/v9" @@ -36,6 +37,7 @@ import ( func main() { es, _ := elasticsearch.NewDefaultClient() + defer es.Close(context.Background()) log.Println(es.Info()) } ``` @@ -57,6 +59,7 @@ func main() { es, _ := elasticsearch.NewTypedClient(elasticsearch.Config{ Addresses: []string{"http://localhost:9200"}, }) + defer es.Close(context.Background()) log.Println(es.Info().Do(context.Background())) } ``` diff --git a/docs/reference/installation.md b/docs/reference/installation.md index c1edc5799e..95584f78fd 100644 --- a/docs/reference/installation.md +++ b/docs/reference/installation.md @@ -34,6 +34,7 @@ cat > main.go <<-END package main import ( + "context" "log" "github.com/elastic/go-elasticsearch/v9" @@ -41,6 +42,7 @@ cat > main.go <<-END func main() { es, _ := elasticsearch.NewDefaultClient() + defer es.Close(context.Background()) log.Println(elasticsearch.Version) log.Println(es.Info()) } diff --git a/elasticsearch.go b/elasticsearch.go index 6eec2de9ca..ee5e03e58e 100644 --- a/elasticsearch.go +++ b/elasticsearch.go @@ -18,10 +18,10 @@ package elasticsearch import ( + "context" "encoding/base64" "errors" "fmt" - "go.opentelemetry.io/otel/trace" "net/http" "net/url" "os" @@ -30,8 +30,11 @@ import ( "strconv" "strings" "sync" + "sync/atomic" "time" + "go.opentelemetry.io/otel/trace" + "github.com/elastic/go-elasticsearch/v9/typedapi" "github.com/elastic/go-elasticsearch/v9/esapi" @@ -62,6 +65,14 @@ var ( reMetaVersion = regexp.MustCompile("([0-9.]+)(.*)") ) +var ( + // ErrClosed is returned when the client is closed. + ErrClosed = errors.New("client is closed") + + // ErrAlreadyClosed is returned by the Close method when the client is already closed. + ErrAlreadyClosed = errors.New("client is already closed") +) + func init() { userAgent = initUserAgent() } @@ -140,6 +151,9 @@ type BaseClient struct { disableMetaHeader bool productCheckMu sync.RWMutex productCheckSuccess bool + + closeC chan struct{} + closeDone uint32 } // Client represents the Functional Options API. @@ -169,6 +183,7 @@ func NewBaseClient(cfg Config) (*BaseClient, error) { disableMetaHeader: cfg.DisableMetaHeader, metaHeader: initMetaHeader(tp), compatibilityHeader: cfg.EnableCompatibilityMode || compatibilityHeader, + closeC: make(chan struct{}), } if cfg.DiscoverNodesOnStart { @@ -214,6 +229,7 @@ func NewClient(cfg Config) (*Client, error) { disableMetaHeader: cfg.DisableMetaHeader, metaHeader: initMetaHeader(tp), compatibilityHeader: cfg.EnableCompatibilityMode || compatibilityHeader, + closeC: make(chan struct{}), }, } client.API = esapi.New(client) @@ -247,6 +263,7 @@ func NewTypedClient(cfg Config) (*TypedClient, error) { disableMetaHeader: cfg.DisableMetaHeader, metaHeader: metaHeader, compatibilityHeader: cfg.EnableCompatibilityMode || compatibilityHeader, + closeC: make(chan struct{}), }, } client.MethodAPI = typedapi.NewMethodAPI(client) @@ -344,6 +361,10 @@ func newTransport(cfg Config) (*elastictransport.Client, error) { // Perform delegates to Transport to execute a request and return a response. func (c *BaseClient) Perform(req *http.Request) (*http.Response, error) { + if c.isClosed() { + return nil, ErrClosed + } + // Compatibility Header if c.compatibilityHeader { if req.Body != nil { @@ -434,12 +455,59 @@ func (c *BaseClient) Metrics() (elastictransport.Metrics, error) { // DiscoverNodes reloads the client connections by fetching information from the cluster. func (c *BaseClient) DiscoverNodes() error { + if c.isClosed() { + return ErrClosed + } if dt, ok := c.Transport.(elastictransport.Discoverable); ok { return dt.DiscoverNodes() } return errors.New("transport is missing method DiscoverNodes()") } +func (c *BaseClient) isClosed() bool { + select { + case <-c.closeC: + return true + default: + return false + } +} + +// Close closes the client. If the underlying Transport is elastictransport.Closeable, it is closed as well. +// Close should only be called once. Later calls to Close will return ErrAlreadyClosed. +// Once closed, future calls to the client will return ErrClosed. +// Existing requests may continue to run but may return: +// - elastictransport.ErrClosed +// - errors.New("connection pool is closed") +func (c *BaseClient) Close(ctx context.Context) error { + if ctx == nil { + ctx = context.Background() + } + + if atomic.CompareAndSwapUint32(&c.closeDone, 0, 1) { + close(c.closeC) + + closeable, ok := c.Transport.(elastictransport.Closeable) + if ok { + transportClosed := make(chan error, 1) + go func() { + transportClosed <- closeable.Close(context.Background()) + }() + + select { + case err := <-transportClosed: + return err + case <-ctx.Done(): + return ctx.Err() + } + } + + return nil + } else { + return ErrAlreadyClosed + } +} + // addrsFromEnvironment returns a list of addresses by splitting // the ELASTICSEARCH_URL environment variable with comma, or an empty list. func addrsFromEnvironment() []string { diff --git a/elasticsearch_internal_test.go b/elasticsearch_internal_test.go index 3b23b353d3..4651dd85f7 100644 --- a/elasticsearch_internal_test.go +++ b/elasticsearch_internal_test.go @@ -27,8 +27,6 @@ import ( "crypto/x509" "encoding/base64" "errors" - "github.com/elastic/go-elasticsearch/v9/esapi" - "github.com/elastic/go-elasticsearch/v9/typedapi/types" "io" "io/ioutil" "net/http" @@ -40,6 +38,10 @@ import ( "strconv" "strings" "testing" + "time" + + "github.com/elastic/go-elasticsearch/v9/esapi" + "github.com/elastic/go-elasticsearch/v9/typedapi/types" "github.com/elastic/elastic-transport-go/v8/elastictransport" ) @@ -1265,5 +1267,160 @@ func TestInstrumentation(t *testing.T) { }) }) } +} + +func TestClose(t *testing.T) { + type closeable interface { + esapi.Transport + elastictransport.Closeable + } + + tests := []struct { + name string + c func() closeable + }{ + {name: "BaseClient", c: func() closeable { + c, _ := NewBaseClient(Config{Transport: &mockTransp{}}) + return c + }}, + {name: "Client", c: func() closeable { + c, _ := NewClient(Config{Transport: &mockTransp{}}) + return c + }}, + {name: "TypedClient", c: func() closeable { + c, _ := NewTypedClient(Config{Transport: &mockTransp{}}) + return c + }}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Run("close", func(t *testing.T) { + c := tt.c() + err := c.Close(context.Background()) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + }) + + t.Run("closed twice", func(t *testing.T) { + c := tt.c() + _ = c.Close(context.Background()) + err := c.Close(context.Background()) + if err != nil { + if !errors.Is(err, ErrAlreadyClosed) { + t.Errorf("unexpected error: %v", err) + } + } + }) + + t.Run("performing a request after close", func(t *testing.T) { + c := tt.c() + if err := c.Close(context.Background()); err != nil { + t.Fatalf("unexpected error: %v", err) + } + req, err := http.NewRequest(http.MethodGet, "http://localhost:9200", nil) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if _, err := c.Perform(req); err != nil { + if !errors.Is(err, ErrClosed) { + t.Fatalf("unexpected error: %v", err) + } + } else { + t.Fatal("expected error") + } + }) + + t.Run("transport close called", func(t *testing.T) { + c := tt.c() + transportCloseCalled := false + mockTransport := &mockESTransport{CloseFunc: func(ctx context.Context) error { + transportCloseCalled = true + return nil + }} + switch c := c.(type) { + case *BaseClient: + c.Transport = mockTransport + case *Client: + c.Transport = mockTransport + case *TypedClient: + c.Transport = mockTransport + } + + err := c.Close(context.Background()) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if !transportCloseCalled { + t.Fatal("transport close not called") + } + }) + + t.Run("close timed out, transport close unresponsive", func(t *testing.T) { + done := make(chan struct{}) + t.Cleanup(func() { close(done) }) + mockTransport := &mockESTransport{CloseFunc: func(ctx context.Context) error { + <-done + return nil + }} + c := tt.c() + switch c := c.(type) { + case *BaseClient: + c.Transport = mockTransport + case *Client: + c.Transport = mockTransport + case *TypedClient: + c.Transport = mockTransport + } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) + defer cancel() + if err := c.Close(ctx); !errors.Is(err, context.DeadlineExceeded) { + t.Fatalf("unexpected error: %v", err) + } + }) + + t.Run("close timed out, transport close responsive", func(t *testing.T) { + mockTransport := &mockESTransport{CloseFunc: func(ctx context.Context) error { + <-ctx.Done() + return ctx.Err() + }} + c := tt.c() + switch c := c.(type) { + case *BaseClient: + c.Transport = mockTransport + case *Client: + c.Transport = mockTransport + case *TypedClient: + c.Transport = mockTransport + } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) + defer cancel() + if err := c.Close(ctx); !errors.Is(err, context.DeadlineExceeded) { + t.Fatalf("unexpected error: %v", err) + } + }) + + }) + } +} +type mockESTransport struct { + PerformFunc func(*http.Request) (*http.Response, error) + CloseFunc func(context.Context) error +} + +func (m mockESTransport) Perform(req *http.Request) (*http.Response, error) { + if m.PerformFunc != nil { + return m.PerformFunc(req) + } + t := &mockTransp{} + return t.RoundTrip(req) +} + +func (m mockESTransport) Close(ctx context.Context) error { + if m.CloseFunc != nil { + return m.CloseFunc(ctx) + } + return nil } diff --git a/esapi/esapi.request.go b/esapi/esapi.request.go index 234983615e..8b43d8eca9 100644 --- a/esapi/esapi.request.go +++ b/esapi/esapi.request.go @@ -32,13 +32,11 @@ var ( ) // Request defines the API request. -// type Request interface { Do(ctx context.Context, transport Transport) (*Response, error) } // newRequest creates an HTTP request. -// func newRequest(method, path string, body io.Reader) (*http.Request, error) { return http.NewRequest(method, path, body) } diff --git a/esapi/esapi.response.go b/esapi/esapi.response.go index a657b5ee9e..b6991f1029 100644 --- a/esapi/esapi.response.go +++ b/esapi/esapi.response.go @@ -28,7 +28,6 @@ import ( ) // Response represents the API response. -// type Response struct { StatusCode int Header http.Header @@ -38,7 +37,6 @@ type Response struct { // String returns the response as a string. // // The intended usage is for testing or debugging only. -// func (r *Response) String() string { var ( out = new(bytes.Buffer) @@ -75,7 +73,6 @@ func (r *Response) String() string { } // Status returns the response status as a string. -// func (r *Response) Status() string { var b strings.Builder if r != nil { @@ -87,19 +84,16 @@ func (r *Response) Status() string { } // IsError returns true when the response status indicates failure. -// func (r *Response) IsError() bool { return r.StatusCode > 299 } // Warnings returns the deprecation warnings from response headers. -// func (r *Response) Warnings() []string { return r.Header["Warning"] } // HasWarnings returns true when the response headers contain deprecation warnings. -// func (r *Response) HasWarnings() bool { return len(r.Warnings()) > 0 } diff --git a/esutil/bulk_indexer.go b/esutil/bulk_indexer.go index 95639f7a2b..7b1dd436fc 100644 --- a/esutil/bulk_indexer.go +++ b/esutil/bulk_indexer.go @@ -343,6 +343,7 @@ func (bi *bulkIndexer) Add(ctx context.Context, item BulkIndexerItem) error { // Close stops the periodic flush, closes the indexer queue channel, // which triggers the workers to flush and stop. +// Note: it is the user's responsibility to call Close on the elasticsearch Client passed in to the BulkIndexerConfig. func (bi *bulkIndexer) Close(ctx context.Context) error { close(bi.queue) diff --git a/esutil/bulk_indexer_benchmark_test.go b/esutil/bulk_indexer_benchmark_test.go index d020423cf6..e498f4e5fe 100644 --- a/esutil/bulk_indexer_benchmark_test.go +++ b/esutil/bulk_indexer_benchmark_test.go @@ -65,6 +65,9 @@ func BenchmarkBulkIndexer(b *testing.B) { b.ResetTimer() es, _ := elasticsearch.NewClient(elasticsearch.Config{Transport: &mockTransp{}}) + defer func() { + _ = es.Close(context.Background()) + }() bi, _ := esutil.NewBulkIndexer(esutil.BulkIndexerConfig{ Client: es, FlushBytes: 1024, diff --git a/esutil/bulk_indexer_example_test.go b/esutil/bulk_indexer_example_test.go index 5e11036488..52aa553c26 100644 --- a/esutil/bulk_indexer_example_test.go +++ b/esutil/bulk_indexer_example_test.go @@ -52,6 +52,13 @@ func ExampleNewBulkIndexer() { if err != nil { log.Fatalf("Error creating the client: %s", err) } + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := es.Close(ctx); err != nil { + log.Fatalf("Error closing the client: %s", err) + } + }() // Create the indexer // diff --git a/esutil/doc.go b/esutil/doc.go index 494a019e85..b00cb0440c 100644 --- a/esutil/doc.go +++ b/esutil/doc.go @@ -17,6 +17,5 @@ /* Package esutil provides helper utilities to the Go client for Elasticsearch. - */ package esutil diff --git a/esutil/json_reader.go b/esutil/json_reader.go index 36673a4ca4..049b828800 100644 --- a/esutil/json_reader.go +++ b/esutil/json_reader.go @@ -24,20 +24,17 @@ import ( ) // NewJSONReader encodes v into JSON and returns it as an io.Reader. -// func NewJSONReader(v interface{}) io.Reader { return &JSONReader{val: v, buf: nil} } // JSONEncoder defines the interface for custom JSON encoders. -// type JSONEncoder interface { EncodeJSON(io.Writer) error } // JSONReader represents a reader which takes an interface value, // encodes it into JSON, and wraps it in an io.Reader. -// type JSONReader struct { val interface{} buf interface { @@ -47,7 +44,6 @@ type JSONReader struct { } // Read implements the io.Reader interface. -// func (r *JSONReader) Read(p []byte) (int, error) { if r.buf == nil { r.buf = new(bytes.Buffer) @@ -60,7 +56,6 @@ func (r *JSONReader) Read(p []byte) (int, error) { } // WriteTo implements the io.WriterTo interface. -// func (r *JSONReader) WriteTo(w io.Writer) (int64, error) { cw := countingWriter{Writer: w} err := r.encode(&cw) diff --git a/go.mod b/go.mod index 4b5c3a0939..fae41cba69 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.23 toolchain go1.23.0 require ( - github.com/elastic/elastic-transport-go/v8 v8.7.0 + github.com/elastic/elastic-transport-go/v8 v8.8.0 go.opentelemetry.io/otel/trace v1.35.0 ) diff --git a/go.sum b/go.sum index 9bac8f415b..5ed442edff 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/elastic/elastic-transport-go/v8 v8.7.0 h1:OgTneVuXP2uip4BA658Xi6Hfw+PeIOod2rY3GVMGoVE= -github.com/elastic/elastic-transport-go/v8 v8.7.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/elastic-transport-go/v8 v8.8.0 h1:7k1Ua+qluFr6p1jfJjGDl97ssJS/P7cHNInzfxgBQAo= +github.com/elastic/elastic-transport-go/v8 v8.8.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= diff --git a/internal/testing/go.mod b/internal/testing/go.mod index dc3a8812a3..2af42b5d65 100644 --- a/internal/testing/go.mod +++ b/internal/testing/go.mod @@ -7,7 +7,7 @@ toolchain go1.24.2 replace github.com/elastic/go-elasticsearch/v9 => ./../.. require ( - github.com/elastic/elastic-transport-go/v8 v8.7.0 + github.com/elastic/elastic-transport-go/v8 v8.8.0 github.com/elastic/go-elasticsearch/v9 v9.0.0-20250401132409-0ffca4b1f163 github.com/testcontainers/testcontainers-go v0.34.0 github.com/testcontainers/testcontainers-go/modules/elasticsearch v0.34.0 diff --git a/internal/testing/go.sum b/internal/testing/go.sum index 5808a5dab8..7e084b4805 100644 --- a/internal/testing/go.sum +++ b/internal/testing/go.sum @@ -29,8 +29,8 @@ github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/elastic/elastic-transport-go/v8 v8.7.0 h1:OgTneVuXP2uip4BA658Xi6Hfw+PeIOod2rY3GVMGoVE= -github.com/elastic/elastic-transport-go/v8 v8.7.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/elastic-transport-go/v8 v8.8.0 h1:7k1Ua+qluFr6p1jfJjGDl97ssJS/P7cHNInzfxgBQAo= +github.com/elastic/elastic-transport-go/v8 v8.8.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= github.com/elastic/go-elasticsearch/v8 v8.12.1 h1:QcuFK5LaZS0pSIj/eAEsxmJWmMo7tUs1aVBbzdIgtnE= github.com/elastic/go-elasticsearch/v8 v8.12.1/go.mod h1:wSzJYrrKPZQ8qPuqAqc6KMR4HrBfHnZORvyL+FMFqq0= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= From 55a830938fce1421774c6e24511ff602388e50ce Mon Sep 17 00:00:00 2001 From: Matt Devy Date: Wed, 26 Nov 2025 10:55:56 +0000 Subject: [PATCH 2/6] test: update e2e tests with Close method --- .../e2e/bulk_indexer_integration_test.go | 4 ++ .../e2e/elasticsearch_integration_test.go | 53 ++++++++++++++++++- .../testing/e2e/esapi_integration_test.go | 15 ++++++ .../e2e/json_reader_integration_test.go | 12 +++-- 4 files changed, 80 insertions(+), 4 deletions(-) diff --git a/internal/testing/e2e/bulk_indexer_integration_test.go b/internal/testing/e2e/bulk_indexer_integration_test.go index 7e25c384f5..073ea96630 100644 --- a/internal/testing/e2e/bulk_indexer_integration_test.go +++ b/internal/testing/e2e/bulk_indexer_integration_test.go @@ -100,6 +100,7 @@ func TestBulkIndexerIntegration(t *testing.T) { PoolCompressor: tt.PoolCompressor, Logger: &elastictransport.ColorLogger{Output: os.Stdout}, }) + defer es.Close(context.Background()) es.Indices.Delete([]string{indexName}, es.Indices.Delete.WithIgnoreUnavailable(true)) es.Indices.Create( @@ -171,6 +172,7 @@ func TestBulkIndexerIntegration(t *testing.T) { PoolCompressor: tt.PoolCompressor, Logger: &elastictransport.ColorLogger{Output: os.Stdout}, }) + defer es.Close(context.Background()) bi, _ := esutil.NewBulkIndexer(esutil.BulkIndexerConfig{ Index: "test-index-a", @@ -245,6 +247,7 @@ func TestBulkIndexerIntegration(t *testing.T) { PoolCompressor: tt.PoolCompressor, Logger: &elastictransport.ColorLogger{Output: os.Stdout}, }) + defer es.Close(context.Background()) es.Indices.Delete([]string{index}, es.Indices.Delete.WithIgnoreUnavailable(true)) es.Indices.Create(index, es.Indices.Create.WithWaitForActiveShards("1")) @@ -312,6 +315,7 @@ func TestBulkIndexerIntegration(t *testing.T) { PoolCompressor: tt.PoolCompressor, Logger: &elastictransport.ColorLogger{Output: os.Stdout, EnableRequestBody: true, EnableResponseBody: true}, }) + defer es.Close(context.Background()) es.Indices.Delete([]string{index}, es.Indices.Delete.WithIgnoreUnavailable(true)) es.Indices.Create(index, es.Indices.Create.WithWaitForActiveShards("1")) diff --git a/internal/testing/e2e/elasticsearch_integration_test.go b/internal/testing/e2e/elasticsearch_integration_test.go index 90b84cb800..95770056d8 100644 --- a/internal/testing/e2e/elasticsearch_integration_test.go +++ b/internal/testing/e2e/elasticsearch_integration_test.go @@ -49,9 +49,10 @@ import ( "github.com/elastic/go-elasticsearch/v9/typedapi/types/enums/result" "github.com/elastic/go-elasticsearch/v9/typedapi/types/enums/sortorder" + "testing/containertest" + "github.com/testcontainers/testcontainers-go" tces "github.com/testcontainers/testcontainers-go/modules/elasticsearch" - "testing/containertest" ) func TestElasticsearchIntegration(t *testing.T) { @@ -78,6 +79,11 @@ func TestElasticsearchIntegration(t *testing.T) { if err != nil { t.Fatalf("Error creating the client: %s", err) } + defer func() { + if err := es.Close(context.Background()); err != nil { + t.Fatalf("Error closing the client: %s", err) + } + }() var total int @@ -130,6 +136,11 @@ func TestElasticsearchIntegration(t *testing.T) { if err != nil { t.Fatalf("Error creating the client: %s", err) } + defer func() { + if err := es.Close(context.Background()); err != nil { + t.Fatalf("Error closing the client: %s", err) + } + }() for i := 0; i < 101; i++ { wg.Add(1) @@ -153,6 +164,11 @@ func TestElasticsearchIntegration(t *testing.T) { if err != nil { t.Fatalf("Error creating the client: %s", err) } + defer func() { + if err := es.Close(context.Background()); err != nil { + t.Fatalf("Error closing the client: %s", err) + } + }() ctx, cancel := context.WithTimeout(context.Background(), time.Nanosecond) defer cancel() @@ -189,6 +205,11 @@ func TestElasticsearchIntegration(t *testing.T) { if err != nil { t.Fatalf("Error creating the client: %s", err) } + defer func() { + if err := es.Close(context.Background()); err != nil { + t.Fatalf("Error closing the client: %s", err) + } + }() res, err := es.Info() if err == nil { @@ -210,6 +231,11 @@ func TestElasticsearchIntegration(t *testing.T) { if err != nil { t.Fatalf("error creating the client: %s", err) } + defer func() { + if err := es.Close(context.Background()); err != nil { + t.Fatalf("Error closing the client: %s", err) + } + }() res, err := es.Info().Do(context.Background()) if err != nil { @@ -232,6 +258,11 @@ func TestElasticsearchIntegration(t *testing.T) { if err != nil { t.Fatalf("error creating the client: %s", err) } + defer func() { + if err := es.Close(context.Background()); err != nil { + t.Fatalf("Error closing the client: %s", err) + } + }() // If the index doesn't exist we create it with a mapping. indexName := "test-index" @@ -559,6 +590,11 @@ func TestElasticsearchInsecureIntegration(t *testing.T) { if err != nil { t.Fatalf("Error creating the client: %s", err) } + defer func() { + if err := es.Close(context.Background()); err != nil { + t.Fatalf("Error closing the client: %s", err) + } + }() for i := 0; i < 10; i++ { res, err := es.Info() @@ -585,6 +621,11 @@ func TestElasticsearchInsecureIntegration(t *testing.T) { }, API: esapi.New(tp), } + defer func() { + if err := es.Close(context.Background()); err != nil { + t.Fatalf("Error closing the client: %s", err) + } + }() for i := 0; i < 10; i++ { res, err := es.Info() @@ -610,6 +651,11 @@ func TestElasticsearchInsecureIntegration(t *testing.T) { }, API: esapi.New(tr), } + defer func() { + if err := es.Close(context.Background()); err != nil { + t.Fatalf("Error closing the client: %s", err) + } + }() for i := 0; i < 10; i++ { res, err := es.Info() @@ -631,6 +677,11 @@ func TestElasticsearchInsecureIntegration(t *testing.T) { if err != nil { t.Fatalf("Error creating the client: %s\n", err) } + defer func() { + if err := es.Close(context.Background()); err != nil { + t.Fatalf("Error closing the client: %s", err) + } + }() res, err := es.Info() if err != nil { diff --git a/internal/testing/e2e/esapi_integration_test.go b/internal/testing/e2e/esapi_integration_test.go index 94de92bb93..a0c623bb3b 100644 --- a/internal/testing/e2e/esapi_integration_test.go +++ b/internal/testing/e2e/esapi_integration_test.go @@ -58,6 +58,11 @@ func TestAPI(t *testing.T) { if err != nil { t.Fatalf("Error creating the client: %s\n", err) } + defer func() { + if err := es.Close(context.Background()); err != nil { + t.Fatalf("Error closing the client: %s", err) + } + }() es.Cluster.Health(es.Cluster.Health.WithWaitForStatus("yellow")) res, err := es.Search(es.Search.WithTimeout(500 * time.Millisecond)) @@ -83,6 +88,11 @@ func TestAPI(t *testing.T) { if err != nil { t.Fatalf("Error creating the client: %s\n", err) } + defer func() { + if err := es.Close(context.Background()); err != nil { + t.Fatalf("Error closing the client: %s", err) + } + }() res, err := es.Info(es.Info.WithHeader(map[string]string{"Accept": "application/yaml"})) if err != nil { @@ -113,6 +123,11 @@ func TestAPI(t *testing.T) { if err != nil { t.Fatalf("Error creating the client: %s\n", err) } + defer func() { + if err := es.Close(context.Background()); err != nil { + t.Fatalf("Error closing the client: %s", err) + } + }() // Prepare indices // diff --git a/internal/testing/e2e/json_reader_integration_test.go b/internal/testing/e2e/json_reader_integration_test.go index 4aba79a648..d295550a98 100644 --- a/internal/testing/e2e/json_reader_integration_test.go +++ b/internal/testing/e2e/json_reader_integration_test.go @@ -22,13 +22,14 @@ package e2e_test import ( "context" - "github.com/elastic/go-elasticsearch/v9" - "github.com/elastic/go-elasticsearch/v9/esapi" - "github.com/elastic/go-elasticsearch/v9/esutil" "os" "strings" "testing" + "github.com/elastic/go-elasticsearch/v9" + "github.com/elastic/go-elasticsearch/v9/esapi" + "github.com/elastic/go-elasticsearch/v9/esutil" + "testing/containertest" ) @@ -60,6 +61,11 @@ func TestJSONReaderIntegration(t *testing.T) { if err != nil { t.Fatalf("Error creating the client: %s\n", err) } + defer func() { + if err := es.Close(context.Background()); err != nil { + t.Fatalf("Error closing the client: %s", err) + } + }() es.Indices.Delete([]string{"test"}, es.Indices.Delete.WithIgnoreUnavailable(true)) From 74fd65d2dd8a7d653c441b5c35d2fd56fbdb82d7 Mon Sep 17 00:00:00 2001 From: Matt Devy Date: Wed, 26 Nov 2025 11:00:18 +0000 Subject: [PATCH 3/6] docs: correct GCP function usage doc --- docs/reference/connecting.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/docs/reference/connecting.md b/docs/reference/connecting.md index 56f9e9b430..1bb33a887c 100644 --- a/docs/reference/connecting.md +++ b/docs/reference/connecting.md @@ -261,13 +261,6 @@ func init() { if err != nil { log.Fatalf("elasticsearch.NewClient: %v", err) } - defer func() { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - if err := client.Close(ctx); err != nil { - log.Fatalf("Error closing the client: %s", err) - } - } () } func HttpExample(w http.ResponseWriter, r *http.Request) { From 8d8bb4ba80a5157cabf3c49684909998e72e2def Mon Sep 17 00:00:00 2001 From: Matt Devy Date: Wed, 26 Nov 2025 11:11:37 +0000 Subject: [PATCH 4/6] fix: fall back to closeDone atomic when closeC is nil --- elasticsearch.go | 7 ++++++- elasticsearch_internal_test.go | 5 +++++ internal/testing/e2e/elasticsearch_integration_test.go | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/elasticsearch.go b/elasticsearch.go index ee5e03e58e..9027a33d3e 100644 --- a/elasticsearch.go +++ b/elasticsearch.go @@ -465,6 +465,9 @@ func (c *BaseClient) DiscoverNodes() error { } func (c *BaseClient) isClosed() bool { + if c.closeC == nil { + return atomic.LoadUint32(&c.closeDone) != 0 + } select { case <-c.closeC: return true @@ -485,7 +488,9 @@ func (c *BaseClient) Close(ctx context.Context) error { } if atomic.CompareAndSwapUint32(&c.closeDone, 0, 1) { - close(c.closeC) + if c.closeC != nil { + close(c.closeC) + } closeable, ok := c.Transport.(elastictransport.Closeable) if ok { diff --git a/elasticsearch_internal_test.go b/elasticsearch_internal_test.go index 4651dd85f7..4935cda52e 100644 --- a/elasticsearch_internal_test.go +++ b/elasticsearch_internal_test.go @@ -1291,6 +1291,11 @@ func TestClose(t *testing.T) { c, _ := NewTypedClient(Config{Transport: &mockTransp{}}) return c }}, + {name: "BaseClient nil closeC", c: func() closeable { + c, _ := NewBaseClient(Config{Transport: &mockTransp{}}) + c.closeC = nil + return c + }}, } for _, tt := range tests { diff --git a/internal/testing/e2e/elasticsearch_integration_test.go b/internal/testing/e2e/elasticsearch_integration_test.go index 95770056d8..88d38e5f9d 100644 --- a/internal/testing/e2e/elasticsearch_integration_test.go +++ b/internal/testing/e2e/elasticsearch_integration_test.go @@ -648,6 +648,7 @@ func TestElasticsearchInsecureIntegration(t *testing.T) { es := elasticsearch.Client{ BaseClient: elasticsearch.BaseClient{ Transport: tr, + closeC: make(chan struct{}), }, API: esapi.New(tr), } From 0418579e47ae9029d23a952e32d9ee29ac9ce140 Mon Sep 17 00:00:00 2001 From: Matt Devy Date: Wed, 26 Nov 2025 11:18:08 +0000 Subject: [PATCH 5/6] test: remove setting closeC from integration test --- internal/testing/e2e/elasticsearch_integration_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/testing/e2e/elasticsearch_integration_test.go b/internal/testing/e2e/elasticsearch_integration_test.go index 88d38e5f9d..95770056d8 100644 --- a/internal/testing/e2e/elasticsearch_integration_test.go +++ b/internal/testing/e2e/elasticsearch_integration_test.go @@ -648,7 +648,6 @@ func TestElasticsearchInsecureIntegration(t *testing.T) { es := elasticsearch.Client{ BaseClient: elasticsearch.BaseClient{ Transport: tr, - closeC: make(chan struct{}), }, API: esapi.New(tr), } From 70871319bb2e91ef5b3eb59642fce6ee29d58113 Mon Sep 17 00:00:00 2001 From: Matt Devy Date: Wed, 26 Nov 2025 11:29:55 +0000 Subject: [PATCH 6/6] refactor: remove closeC in favour of atomic --- elasticsearch.go | 18 +----------------- elasticsearch_internal_test.go | 5 ----- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/elasticsearch.go b/elasticsearch.go index 9027a33d3e..7a6cf456e7 100644 --- a/elasticsearch.go +++ b/elasticsearch.go @@ -152,7 +152,6 @@ type BaseClient struct { productCheckMu sync.RWMutex productCheckSuccess bool - closeC chan struct{} closeDone uint32 } @@ -183,7 +182,6 @@ func NewBaseClient(cfg Config) (*BaseClient, error) { disableMetaHeader: cfg.DisableMetaHeader, metaHeader: initMetaHeader(tp), compatibilityHeader: cfg.EnableCompatibilityMode || compatibilityHeader, - closeC: make(chan struct{}), } if cfg.DiscoverNodesOnStart { @@ -229,7 +227,6 @@ func NewClient(cfg Config) (*Client, error) { disableMetaHeader: cfg.DisableMetaHeader, metaHeader: initMetaHeader(tp), compatibilityHeader: cfg.EnableCompatibilityMode || compatibilityHeader, - closeC: make(chan struct{}), }, } client.API = esapi.New(client) @@ -263,7 +260,6 @@ func NewTypedClient(cfg Config) (*TypedClient, error) { disableMetaHeader: cfg.DisableMetaHeader, metaHeader: metaHeader, compatibilityHeader: cfg.EnableCompatibilityMode || compatibilityHeader, - closeC: make(chan struct{}), }, } client.MethodAPI = typedapi.NewMethodAPI(client) @@ -465,15 +461,7 @@ func (c *BaseClient) DiscoverNodes() error { } func (c *BaseClient) isClosed() bool { - if c.closeC == nil { - return atomic.LoadUint32(&c.closeDone) != 0 - } - select { - case <-c.closeC: - return true - default: - return false - } + return atomic.LoadUint32(&c.closeDone) != 0 } // Close closes the client. If the underlying Transport is elastictransport.Closeable, it is closed as well. @@ -488,10 +476,6 @@ func (c *BaseClient) Close(ctx context.Context) error { } if atomic.CompareAndSwapUint32(&c.closeDone, 0, 1) { - if c.closeC != nil { - close(c.closeC) - } - closeable, ok := c.Transport.(elastictransport.Closeable) if ok { transportClosed := make(chan error, 1) diff --git a/elasticsearch_internal_test.go b/elasticsearch_internal_test.go index 4935cda52e..4651dd85f7 100644 --- a/elasticsearch_internal_test.go +++ b/elasticsearch_internal_test.go @@ -1291,11 +1291,6 @@ func TestClose(t *testing.T) { c, _ := NewTypedClient(Config{Transport: &mockTransp{}}) return c }}, - {name: "BaseClient nil closeC", c: func() closeable { - c, _ := NewBaseClient(Config{Transport: &mockTransp{}}) - c.closeC = nil - return c - }}, } for _, tt := range tests {