From 1329aa51b605cb54ba9aae3a82a0a87b881fb7b3 Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Mon, 13 Nov 2017 09:09:58 -0800 Subject: Updating server dependancies. (#7816) --- vendor/gopkg.in/olivere/elastic.v5/.travis.yml | 2 +- vendor/gopkg.in/olivere/elastic.v5/CONTRIBUTORS | 6 ++ vendor/gopkg.in/olivere/elastic.v5/bulk.go | 2 +- vendor/gopkg.in/olivere/elastic.v5/bulk_test.go | 27 +++++ vendor/gopkg.in/olivere/elastic.v5/client.go | 13 ++- .../gopkg.in/olivere/elastic.v5/docker-compose.yml | 2 +- .../gopkg.in/olivere/elastic.v5/indices_refresh.go | 12 +-- vendor/gopkg.in/olivere/elastic.v5/msearch.go | 2 +- vendor/gopkg.in/olivere/elastic.v5/request_test.go | 14 +++ vendor/gopkg.in/olivere/elastic.v5/response.go | 4 +- .../gopkg.in/olivere/elastic.v5/response_test.go | 48 +++++++++ vendor/gopkg.in/olivere/elastic.v5/run-es-5.6.3.sh | 2 + vendor/gopkg.in/olivere/elastic.v5/search.go | 31 +++--- .../gopkg.in/olivere/elastic.v5/search_request.go | 9 +- .../olivere/elastic.v5/search_suggester_test.go | 106 +++++++++++++++++++ vendor/gopkg.in/olivere/elastic.v5/setup_test.go | 8 +- .../olivere/elastic.v5/suggester_context.go | 113 +++++++++++++++++++++ .../olivere/elastic.v5/suggester_context_test.go | 55 ++++++++++ vendor/gopkg.in/throttled/throttled.v2/.travis.yml | 18 ++-- vendor/gopkg.in/throttled/throttled.v2/Makefile | 2 - vendor/gopkg.in/throttled/throttled.v2/README.md | 83 ++++++--------- .../throttled/throttled.v2/deprecated_test.go | 4 +- vendor/gopkg.in/throttled/throttled.v2/doc.go | 2 +- .../throttled/throttled.v2/example_test.go | 4 +- .../gopkg.in/throttled/throttled.v2/http_test.go | 2 +- vendor/gopkg.in/throttled/throttled.v2/rate.go | 17 ++-- .../gopkg.in/throttled/throttled.v2/rate_test.go | 4 +- .../throttled/throttled.v2/store/deprecated.go | 6 +- .../throttled.v2/store/memstore/memstore.go | 2 +- .../throttled.v2/store/memstore/memstore_test.go | 4 +- .../throttled.v2/store/redigostore/redigostore.go | 34 +++++-- .../store/redigostore/redigostore_test.go | 85 ++++++++++++++++ .../store/redigostore/redisstore_test.go | 85 ---------------- .../throttled/throttled.v2/store/storetest/doc.go | 2 +- .../throttled.v2/store/storetest/storetest.go | 4 +- .../gopkg.in/throttled/throttled.v2/varyby_test.go | 2 +- 36 files changed, 591 insertions(+), 225 deletions(-) create mode 100644 vendor/gopkg.in/olivere/elastic.v5/response_test.go create mode 100755 vendor/gopkg.in/olivere/elastic.v5/run-es-5.6.3.sh create mode 100644 vendor/gopkg.in/olivere/elastic.v5/suggester_context_test.go create mode 100644 vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redigostore_test.go delete mode 100644 vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redisstore_test.go (limited to 'vendor/gopkg.in') diff --git a/vendor/gopkg.in/olivere/elastic.v5/.travis.yml b/vendor/gopkg.in/olivere/elastic.v5/.travis.yml index 703fa01be..6f718f66a 100644 --- a/vendor/gopkg.in/olivere/elastic.v5/.travis.yml +++ b/vendor/gopkg.in/olivere/elastic.v5/.travis.yml @@ -12,5 +12,5 @@ services: - docker before_install: - sudo sysctl -w vm.max_map_count=262144 - - docker run --rm --privileged=true -p 9200:9200 -p 9300:9300 -e "bootstrap.memory_lock=true" -e "ES_JAVA_OPTS=-Xms1g -Xmx1g" docker.elastic.co/elasticsearch/elasticsearch:5.6.1 elasticsearch -Expack.security.enabled=false -Escript.inline=true -Escript.stored=true -Escript.file=true -Enetwork.host=_local_,_site_ -Enetwork.publish_host=_local_ >& /dev/null & + - docker run --rm --privileged=true -p 9200:9200 -p 9300:9300 -e "bootstrap.memory_lock=true" -e "ES_JAVA_OPTS=-Xms1g -Xmx1g" docker.elastic.co/elasticsearch/elasticsearch:5.6.3 elasticsearch -Expack.security.enabled=false -Escript.inline=true -Escript.stored=true -Escript.file=true -Enetwork.host=_local_,_site_ -Enetwork.publish_host=_local_ >& /dev/null & - sleep 30 diff --git a/vendor/gopkg.in/olivere/elastic.v5/CONTRIBUTORS b/vendor/gopkg.in/olivere/elastic.v5/CONTRIBUTORS index 572caf62d..e3ded87cd 100644 --- a/vendor/gopkg.in/olivere/elastic.v5/CONTRIBUTORS +++ b/vendor/gopkg.in/olivere/elastic.v5/CONTRIBUTORS @@ -20,6 +20,7 @@ Andrew Dunham [@andrew-d](https://github.com/andrew-d) Andrew Gaul [@andrewgaul](https://github.com/andrewgaul) Andy Walker [@alaska](https://github.com/alaska) Arquivei [@arquivei](https://github.com/arquivei) +arthurgustin [@arthurgustin](https://github.com/arthurgustin) Benjamin Fernandes [@LotharSee](https://github.com/LotharSee) Benjamin Zarzycki [@kf6nux](https://github.com/kf6nux) Braden Bassingthwaite [@bbassingthwaite-va](https://github.com/bbassingthwaite-va) @@ -65,13 +66,16 @@ Joe Buck [@four2five](https://github.com/four2five) John Barker [@j16r](https://github.com/j16r) John Goodall [@jgoodall](https://github.com/jgoodall) John Stanford [@jxstanford](https://github.com/jxstanford) +Josh Chorlton [@jchorl](https://github.com/jchorl) jun [@coseyo](https://github.com/coseyo) Junpei Tsuji [@jun06t](https://github.com/jun06t) Keith Hatton [@khatton-ft](https://github.com/khatton-ft) +kel [@liketic](https://github.com/liketic) Kenta SUZUKI [@suzuken](https://github.com/suzuken) Kevin Mulvey [@kmulvey](https://github.com/kmulvey) Kyle Brandt [@kylebrandt](https://github.com/kylebrandt) Leandro Piccilli [@lpic10](https://github.com/lpic10) +M. Zulfa Achsani [@misterciput](https://github.com/misterciput) Maciej Lisiewski [@c2h5oh](https://github.com/c2h5oh) Mara Kim [@autochthe](https://github.com/autochthe) Marcy Buccellato [@marcybuccellato](https://github.com/marcybuccellato) @@ -88,6 +92,7 @@ Nick K [@utrack](https://github.com/utrack) Nick Whyte [@nickw444](https://github.com/nickw444) Nicolae Vartolomei [@nvartolomei](https://github.com/nvartolomei) Orne Brocaar [@brocaar](https://github.com/brocaar) +Paul [@eyeamera](https://github.com/eyeamera) Pete C [@peteclark-ft](https://github.com/peteclark-ft) Radoslaw Wesolowski [r--w](https://github.com/r--w) Ryan Schmukler [@rschmukler](https://github.com/rschmukler) @@ -110,4 +115,5 @@ Wyndham Blanton [@wyndhblb](https://github.com/wyndhblb) Yarden Bar [@ayashjorden](https://github.com/ayashjorden) zakthomas [@zakthomas](https://github.com/zakthomas) singham [@zhaochenxiao90](https://github.com/zhaochenxiao90) +@林 [@zplzpl](https://github.com/zplzpl) Roman Colohanin [@zuzmic](https://github.com/zuzmic) diff --git a/vendor/gopkg.in/olivere/elastic.v5/bulk.go b/vendor/gopkg.in/olivere/elastic.v5/bulk.go index eac240ddb..f2fa0ea73 100644 --- a/vendor/gopkg.in/olivere/elastic.v5/bulk.go +++ b/vendor/gopkg.in/olivere/elastic.v5/bulk.go @@ -234,7 +234,7 @@ func (s *BulkService) Do(ctx context.Context) (*BulkResponse, error) { } // Get response - res, err := s.client.PerformRequest(ctx, "POST", path, params, body) + res, err := s.client.PerformRequestWithContentType(ctx, "POST", path, params, body, "application/x-ndjson") if err != nil { return nil, err } diff --git a/vendor/gopkg.in/olivere/elastic.v5/bulk_test.go b/vendor/gopkg.in/olivere/elastic.v5/bulk_test.go index fba52be73..394439630 100644 --- a/vendor/gopkg.in/olivere/elastic.v5/bulk_test.go +++ b/vendor/gopkg.in/olivere/elastic.v5/bulk_test.go @@ -7,6 +7,9 @@ package elastic import ( "context" "encoding/json" + "fmt" + "net/http" + "net/http/httptest" "testing" ) @@ -505,3 +508,27 @@ func BenchmarkBulkEstimatedSizeInBytesWith100Requests(b *testing.B) { b.ReportAllocs() benchmarkBulkEstimatedSizeInBytes = result // ensure the compiler doesn't optimize } + +func TestBulkContentType(t *testing.T) { + var header http.Header + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + header = r.Header + fmt.Fprintln(w, `{}`) + })) + defer ts.Close() + + client, err := NewSimpleClient(SetURL(ts.URL)) + if err != nil { + t.Fatal(err) + } + indexReq := NewBulkIndexRequest().Index(testIndexName).Type("tweet").Id("1").Doc(tweet{User: "olivere", Message: "Welcome to Golang and Elasticsearch."}) + if _, err := client.Bulk().Add(indexReq).Do(context.Background()); err != nil { + t.Fatal(err) + } + if header == nil { + t.Fatalf("expected header, got %v", header) + } + if want, have := "application/x-ndjson", header.Get("Content-Type"); want != have { + t.Fatalf("Content-Type: want %q, have %q", want, have) + } +} diff --git a/vendor/gopkg.in/olivere/elastic.v5/client.go b/vendor/gopkg.in/olivere/elastic.v5/client.go index 13b45d831..9a48d9ac7 100644 --- a/vendor/gopkg.in/olivere/elastic.v5/client.go +++ b/vendor/gopkg.in/olivere/elastic.v5/client.go @@ -26,7 +26,7 @@ import ( const ( // Version is the current version of Elastic. - Version = "5.0.48" + Version = "5.0.53" // DefaultURL is the default endpoint of Elasticsearch on the local machine. // It is used e.g. when initializing a new Client without a specific URL. @@ -1168,12 +1168,18 @@ func (c *Client) mustActiveConn() error { } // PerformRequest does a HTTP request to Elasticsearch. +// See PerformRequestWithContentType for details. +func (c *Client) PerformRequest(ctx context.Context, method, path string, params url.Values, body interface{}, ignoreErrors ...int) (*Response, error) { + return c.PerformRequestWithContentType(ctx, method, path, params, body, "application/json", ignoreErrors...) +} + +// PerformRequestWithContentType executes a HTTP request with a specific content type. // It returns a response (which might be nil) and an error on failure. // // Optionally, a list of HTTP error codes to ignore can be passed. // This is necessary for services that expect e.g. HTTP status 404 as a // valid outcome (Exists, IndicesExists, IndicesTypeExists). -func (c *Client) PerformRequest(ctx context.Context, method, path string, params url.Values, body interface{}, ignoreErrors ...int) (*Response, error) { +func (c *Client) PerformRequestWithContentType(ctx context.Context, method, path string, params url.Values, body interface{}, contentType string, ignoreErrors ...int) (*Response, error) { start := time.Now().UTC() c.mu.RLock() @@ -1236,6 +1242,9 @@ func (c *Client) PerformRequest(ctx context.Context, method, path string, params if basicAuth { req.SetBasicAuth(basicAuthUsername, basicAuthPassword) } + if contentType != "" { + req.Header.Set("Content-Type", contentType) + } // Set body if body != nil { diff --git a/vendor/gopkg.in/olivere/elastic.v5/docker-compose.yml b/vendor/gopkg.in/olivere/elastic.v5/docker-compose.yml index 046096db2..002eac7fa 100644 --- a/vendor/gopkg.in/olivere/elastic.v5/docker-compose.yml +++ b/vendor/gopkg.in/olivere/elastic.v5/docker-compose.yml @@ -2,7 +2,7 @@ version: '3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:5.6.0 + image: docker.elastic.co/elasticsearch/elasticsearch:5.6.3 # container_name: elasticsearch hostname: elasticsearch environment: diff --git a/vendor/gopkg.in/olivere/elastic.v5/indices_refresh.go b/vendor/gopkg.in/olivere/elastic.v5/indices_refresh.go index 79324d75f..dbc83ac2c 100644 --- a/vendor/gopkg.in/olivere/elastic.v5/indices_refresh.go +++ b/vendor/gopkg.in/olivere/elastic.v5/indices_refresh.go @@ -14,11 +14,10 @@ import ( ) // RefreshService explicitly refreshes one or more indices. -// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/indices-refresh.html. +// See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/indices-refresh.html. type RefreshService struct { client *Client index []string - force *bool pretty bool } @@ -36,12 +35,6 @@ func (s *RefreshService) Index(index ...string) *RefreshService { return s } -// Force forces a refresh. -func (s *RefreshService) Force(force bool) *RefreshService { - s.force = &force - return s -} - // Pretty asks Elasticsearch to return indented JSON. func (s *RefreshService) Pretty(pretty bool) *RefreshService { s.pretty = pretty @@ -66,9 +59,6 @@ func (s *RefreshService) buildURL() (string, url.Values, error) { // Add query string parameters params := url.Values{} - if s.force != nil { - params.Set("force", fmt.Sprintf("%v", *s.force)) - } if s.pretty { params.Set("pretty", fmt.Sprintf("%v", s.pretty)) } diff --git a/vendor/gopkg.in/olivere/elastic.v5/msearch.go b/vendor/gopkg.in/olivere/elastic.v5/msearch.go index 52ca9ee74..5d0949d9c 100644 --- a/vendor/gopkg.in/olivere/elastic.v5/msearch.go +++ b/vendor/gopkg.in/olivere/elastic.v5/msearch.go @@ -68,7 +68,7 @@ func (s *MultiSearchService) Do(ctx context.Context) (*MultiSearchResult, error) if err != nil { return nil, err } - body, err := json.Marshal(sr.body()) + body, err := json.Marshal(sr.Body()) if err != nil { return nil, err } diff --git a/vendor/gopkg.in/olivere/elastic.v5/request_test.go b/vendor/gopkg.in/olivere/elastic.v5/request_test.go index 2a2d229df..d5ae4f800 100644 --- a/vendor/gopkg.in/olivere/elastic.v5/request_test.go +++ b/vendor/gopkg.in/olivere/elastic.v5/request_test.go @@ -8,6 +8,20 @@ import "testing" var testReq *Request // used as a temporary variable to avoid compiler optimizations in tests/benchmarks +func TestRequestSetContentType(t *testing.T) { + req, err := NewRequest("GET", "/") + if err != nil { + t.Fatal(err) + } + if want, have := "application/json", req.Header.Get("Content-Type"); want != have { + t.Fatalf("want %q, have %q", want, have) + } + req.Header.Set("Content-Type", "application/x-ndjson") + if want, have := "application/x-ndjson", req.Header.Get("Content-Type"); want != have { + t.Fatalf("want %q, have %q", want, have) + } +} + func BenchmarkRequestSetBodyString(b *testing.B) { req, err := NewRequest("GET", "/") if err != nil { diff --git a/vendor/gopkg.in/olivere/elastic.v5/response.go b/vendor/gopkg.in/olivere/elastic.v5/response.go index e7380d98a..4fcdc32d6 100644 --- a/vendor/gopkg.in/olivere/elastic.v5/response.go +++ b/vendor/gopkg.in/olivere/elastic.v5/response.go @@ -34,9 +34,7 @@ func (c *Client) newResponse(res *http.Response) (*Response, error) { } // HEAD requests return a body but no content if len(slurp) > 0 { - if err := c.decoder.Decode(slurp, &r.Body); err != nil { - return nil, err - } + r.Body = json.RawMessage(slurp) } } return r, nil diff --git a/vendor/gopkg.in/olivere/elastic.v5/response_test.go b/vendor/gopkg.in/olivere/elastic.v5/response_test.go new file mode 100644 index 000000000..e62773403 --- /dev/null +++ b/vendor/gopkg.in/olivere/elastic.v5/response_test.go @@ -0,0 +1,48 @@ +// Copyright 2012-present Oliver Eilhard. All rights reserved. +// Use of this source code is governed by a MIT-license. +// See http://olivere.mit-license.org/license.txt for details. + +package elastic + +import ( + "bytes" + "fmt" + "io/ioutil" + "net/http" + "testing" +) + +func BenchmarkResponse(b *testing.B) { + c := &Client{ + decoder: &DefaultDecoder{}, + } + + var resp *Response + for n := 0; n < b.N; n++ { + iteration := fmt.Sprint(n) + body := fmt.Sprintf(`{"n":%d}`, n) + res := &http.Response{ + Header: http.Header{ + "X-Iteration": []string{iteration}, + }, + Body: ioutil.NopCloser(bytes.NewBufferString(body)), + StatusCode: http.StatusOK, + } + var err error + resp, err = c.newResponse(res) + if err != nil { + b.Fatal(err) + } + /* + if want, have := body, string(resp.Body); want != have { + b.Fatalf("want %q, have %q", want, have) + } + //*/ + /* + if want, have := iteration, resp.Header.Get("X-Iteration"); want != have { + b.Fatalf("want %q, have %q", want, have) + } + //*/ + } + _ = resp +} diff --git a/vendor/gopkg.in/olivere/elastic.v5/run-es-5.6.3.sh b/vendor/gopkg.in/olivere/elastic.v5/run-es-5.6.3.sh new file mode 100755 index 000000000..6a9864668 --- /dev/null +++ b/vendor/gopkg.in/olivere/elastic.v5/run-es-5.6.3.sh @@ -0,0 +1,2 @@ +VERSION=5.6.3 +docker run --rm --privileged=true -p 9200:9200 -p 9300:9300 -v "$PWD/etc:/usr/share/elasticsearch/config" -e "bootstrap.memory_lock=true" -e "ES_JAVA_OPTS=-Xms1g -Xmx1g" docker.elastic.co/elasticsearch/elasticsearch:$VERSION elasticsearch -Expack.security.enabled=false -Escript.inline=true -Escript.stored=true -Escript.file=true diff --git a/vendor/gopkg.in/olivere/elastic.v5/search.go b/vendor/gopkg.in/olivere/elastic.v5/search.go index 301550815..7121d5545 100644 --- a/vendor/gopkg.in/olivere/elastic.v5/search.go +++ b/vendor/gopkg.in/olivere/elastic.v5/search.go @@ -60,7 +60,7 @@ func (s *SearchService) Source(source interface{}) *SearchService { // FilterPath allows reducing the response, a mechanism known as // response filtering and described here: -// https://www.elastic.co/guide/en/elasticsearch/reference/5.2/common-options.html#common-options-response-filtering. +// https://www.elastic.co/guide/en/elasticsearch/reference/5.6/common-options.html#common-options-response-filtering. func (s *SearchService) FilterPath(filterPath ...string) *SearchService { s.filterPath = append(s.filterPath, filterPath...) return s @@ -113,7 +113,7 @@ func (s *SearchService) TimeoutInMillis(timeoutInMillis int) *SearchService { // SearchType sets the search operation type. Valid values are: // "query_then_fetch", "query_and_fetch", "dfs_query_then_fetch", // "dfs_query_and_fetch", "count", "scan". -// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-request-search-type.html +// See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-request-search-type.html // for details. func (s *SearchService) SearchType(searchType string) *SearchService { s.searchType = searchType @@ -271,7 +271,7 @@ func (s *SearchService) StoredFields(fields ...string) *SearchService { // SearchAfter allows a different form of pagination by using a live cursor, // using the results of the previous page to help the retrieval of the next. // -// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-request-search-after.html +// See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-request-search-after.html func (s *SearchService) SearchAfter(sortValues ...interface{}) *SearchService { s.searchSource = s.searchSource.SearchAfter(sortValues...) return s @@ -473,7 +473,7 @@ type SearchHitInnerHits struct { } // SearchExplanation explains how the score for a hit was computed. -// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-request-explain.html. +// See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-request-explain.html. type SearchExplanation struct { Value float64 `json:"value"` // e.g. 1.0 Description string `json:"description"` // e.g. "boost" or "ConstantScore(*:*), product of:" @@ -483,11 +483,11 @@ type SearchExplanation struct { // Suggest // SearchSuggest is a map of suggestions. -// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-suggesters.html. +// See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-suggesters.html. type SearchSuggest map[string][]SearchSuggestion // SearchSuggestion is a single search suggestion. -// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-suggesters.html. +// See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-suggesters.html. type SearchSuggestion struct { Text string `json:"text"` Offset int `json:"offset"` @@ -496,14 +496,17 @@ type SearchSuggestion struct { } // SearchSuggestionOption is an option of a SearchSuggestion. -// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-suggesters.html. +// See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-suggesters.html. type SearchSuggestionOption struct { - Text string `json:"text"` - Index string `json:"_index"` - Type string `json:"_type"` - Id string `json:"_id"` - Score float64 `json:"_score"` - Source *json.RawMessage `json:"_source"` + Text string `json:"text"` + Index string `json:"_index"` + Type string `json:"_type"` + Id string `json:"_id"` + Score float64 `json:"score"` + Highlighted string `json:"highlighted"` + CollateMatch bool `json:"collate_match"` + Freq int `json:"freq"` // from TermSuggestion.Option in Java API + Source *json.RawMessage `json:"_source"` } // SearchProfile is a list of shard profiling data collected during @@ -556,6 +559,6 @@ type ProfileResult struct { // Highlighting // SearchHitHighlight is the highlight information of a search hit. -// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-request-highlighting.html +// See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-request-highlighting.html // for a general discussion of highlighting. type SearchHitHighlight map[string][]string diff --git a/vendor/gopkg.in/olivere/elastic.v5/search_request.go b/vendor/gopkg.in/olivere/elastic.v5/search_request.go index ad22a5a3f..03513085f 100644 --- a/vendor/gopkg.in/olivere/elastic.v5/search_request.go +++ b/vendor/gopkg.in/olivere/elastic.v5/search_request.go @@ -194,9 +194,12 @@ func (r *SearchRequest) header() interface{} { return h } -// body is used by MultiSearch to get information about the search body +// Body allows to access the search body of the request, as generated by the DSL. +// Notice that Body is read-only. You must not change the request body. +// +// Body is used e.g. by MultiSearch to get information about the search body // of one SearchRequest. -// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/search-multi-search.html -func (r *SearchRequest) body() interface{} { +// See https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-multi-search.html +func (r *SearchRequest) Body() interface{} { return r.source } diff --git a/vendor/gopkg.in/olivere/elastic.v5/search_suggester_test.go b/vendor/gopkg.in/olivere/elastic.v5/search_suggester_test.go index 78232e9d6..a555e3462 100644 --- a/vendor/gopkg.in/olivere/elastic.v5/search_suggester_test.go +++ b/vendor/gopkg.in/olivere/elastic.v5/search_suggester_test.go @@ -238,3 +238,109 @@ func TestCompletionSuggester(t *testing.T) { t.Errorf("expected Text = 'Golang'; got %s", myOption.Text) } } + +func TestContextSuggester(t *testing.T) { + client := setupTestClientAndCreateIndex(t) // , SetTraceLog(log.New(os.Stdout, "", 0))) + + // TODO make a nice way of creating tweets, as currently the context fields are unsupported as part of the suggestion fields + tweet1 := ` + { + "user":"olivere", + "message":"Welcome to Golang and Elasticsearch.", + "retweets":0, + "created":"0001-01-01T00:00:00Z", + "suggest_field":{ + "input":[ + "Golang", + "Elasticsearch" + ], + "contexts":{ + "user_name": ["olivere"] + } + } + } + ` + tweet2 := ` + { + "user":"sandrae", + "message":"I like golfing", + "retweets":0, + "created":"0001-01-01T00:00:00Z", + "suggest_field":{ + "input":[ + "Golfing" + ], + "contexts":{ + "user_name": ["sandrae"] + } + } + } + ` + + // Add all documents + _, err := client.Index().Index(testIndexName).Type("tweet").Id("1").BodyString(tweet1).Do(context.TODO()) + if err != nil { + t.Fatal(err) + } + + _, err = client.Index().Index(testIndexName).Type("tweet").Id("2").BodyString(tweet2).Do(context.TODO()) + if err != nil { + t.Fatal(err) + } + + _, err = client.Flush().Index(testIndexName).Do(context.TODO()) + if err != nil { + t.Fatal(err) + } + + suggesterName := "my-suggestions" + cs := NewContextSuggester(suggesterName) + cs = cs.Prefix("Gol") + cs = cs.Field("suggest_field") + cs = cs.ContextQueries( + NewSuggesterCategoryQuery("user_name", "olivere"), + ) + + searchResult, err := client.Search(). + Index(testIndexName). + Suggester(cs). + Do(context.TODO()) + if err != nil { + t.Fatal(err) + } + if searchResult.Suggest == nil { + t.Errorf("expected SearchResult.Suggest != nil; got nil") + } + mySuggestions, found := searchResult.Suggest[suggesterName] + if !found { + t.Errorf("expected to find SearchResult.Suggest[%s]; got false", suggesterName) + } + if mySuggestions == nil { + t.Errorf("expected SearchResult.Suggest[%s] != nil; got nil", suggesterName) + } + + // sandra's tweet is not returned because of the user_name context + if len(mySuggestions) != 1 { + t.Errorf("expected 1 suggestion; got %d", len(mySuggestions)) + } + mySuggestion := mySuggestions[0] + if mySuggestion.Text != "Gol" { + t.Errorf("expected Text = 'Gol'; got %s", mySuggestion.Text) + } + if mySuggestion.Offset != 0 { + t.Errorf("expected Offset = %d; got %d", 0, mySuggestion.Offset) + } + if mySuggestion.Length != 3 { + t.Errorf("expected Length = %d; got %d", 3, mySuggestion.Length) + } + if len(mySuggestion.Options) != 1 { + t.Errorf("expected 1 option; got %d", len(mySuggestion.Options)) + } + myOption := mySuggestion.Options[0] + if myOption.Text != "Golang" { + t.Errorf("expected Text = 'Golang'; got %s", myOption.Text) + } + if myOption.Id != "1" { + t.Errorf("expected Id = '1'; got %s", myOption.Id) + } +} diff --git a/vendor/gopkg.in/olivere/elastic.v5/setup_test.go b/vendor/gopkg.in/olivere/elastic.v5/setup_test.go index 7e449c821..df2206a14 100644 --- a/vendor/gopkg.in/olivere/elastic.v5/setup_test.go +++ b/vendor/gopkg.in/olivere/elastic.v5/setup_test.go @@ -45,7 +45,13 @@ const ( "type":"geo_point" }, "suggest_field":{ - "type":"completion" + "type":"completion", + "contexts":[ + { + "name": "user_name", + "type": "category" + } + ] } } }, diff --git a/vendor/gopkg.in/olivere/elastic.v5/suggester_context.go b/vendor/gopkg.in/olivere/elastic.v5/suggester_context.go index caf477669..ade099151 100644 --- a/vendor/gopkg.in/olivere/elastic.v5/suggester_context.go +++ b/vendor/gopkg.in/olivere/elastic.v5/suggester_context.go @@ -4,8 +4,121 @@ package elastic +import "errors" + // SuggesterContextQuery is used to define context information within // a suggestion request. type SuggesterContextQuery interface { Source() (interface{}, error) } + +// ContextSuggester is a fast suggester for e.g. type-ahead completion that supports filtering and boosting based on contexts. +// See https://www.elastic.co/guide/en/elasticsearch/reference/current/suggester-context.html +// for more details. +type ContextSuggester struct { + Suggester + name string + prefix string + field string + size *int + contextQueries []SuggesterContextQuery +} + +// Creates a new context suggester. +func NewContextSuggester(name string) *ContextSuggester { + return &ContextSuggester{ + name: name, + contextQueries: make([]SuggesterContextQuery, 0), + } +} + +func (q *ContextSuggester) Name() string { + return q.name +} + +func (q *ContextSuggester) Prefix(prefix string) *ContextSuggester { + q.prefix = prefix + return q +} + +func (q *ContextSuggester) Field(field string) *ContextSuggester { + q.field = field + return q +} + +func (q *ContextSuggester) Size(size int) *ContextSuggester { + q.size = &size + return q +} + +func (q *ContextSuggester) ContextQuery(query SuggesterContextQuery) *ContextSuggester { + q.contextQueries = append(q.contextQueries, query) + return q +} + +func (q *ContextSuggester) ContextQueries(queries ...SuggesterContextQuery) *ContextSuggester { + q.contextQueries = append(q.contextQueries, queries...) + return q +} + +// contextSuggesterRequest is necessary because the order in which +// the JSON elements are routed to Elasticsearch is relevant. +// We got into trouble when using plain maps because the text element +// needs to go before the completion element. +type contextSuggesterRequest struct { + Prefix string `json:"prefix"` + Completion interface{} `json:"completion"` +} + +// Creates the source for the context suggester. +func (q *ContextSuggester) Source(includeName bool) (interface{}, error) { + cs := &contextSuggesterRequest{} + + if q.prefix != "" { + cs.Prefix = q.prefix + } + + suggester := make(map[string]interface{}) + cs.Completion = suggester + + if q.field != "" { + suggester["field"] = q.field + } + if q.size != nil { + suggester["size"] = *q.size + } + switch len(q.contextQueries) { + case 0: + case 1: + src, err := q.contextQueries[0].Source() + if err != nil { + return nil, err + } + suggester["context"] = src + default: + ctxq := make(map[string]interface{}) + for _, query := range q.contextQueries { + src, err := query.Source() + if err != nil { + return nil, err + } + // Merge the dictionary into ctxq + m, ok := src.(map[string]interface{}) + if !ok { + return nil, errors.New("elastic: context query is not a map") + } + for k, v := range m { + ctxq[k] = v + } + } + suggester["contexts"] = ctxq + } + + if !includeName { + return cs, nil + } + + source := make(map[string]interface{}) + source[q.name] = cs + return source, nil +} diff --git a/vendor/gopkg.in/olivere/elastic.v5/suggester_context_test.go b/vendor/gopkg.in/olivere/elastic.v5/suggester_context_test.go new file mode 100644 index 000000000..cd3c5586c --- /dev/null +++ b/vendor/gopkg.in/olivere/elastic.v5/suggester_context_test.go @@ -0,0 +1,55 @@ +// Copyright 2012-present Oliver Eilhard. All rights reserved. +// Use of this source code is governed by a MIT-license. +// See http://olivere.mit-license.org/license.txt for details. + +package elastic + +import ( + "encoding/json" + "testing" +) + +func TestContextSuggesterSource(t *testing.T) { + s := NewContextSuggester("place_suggestion"). + Prefix("tim"). + Field("suggest") + src, err := s.Source(true) + if err != nil { + t.Fatal(err) + } + data, err := json.Marshal(src) + if err != nil { + t.Fatalf("marshaling to JSON failed: %v", err) + } + got := string(data) + expected := `{"place_suggestion":{"prefix":"tim","completion":{"field":"suggest"}}}` + if got != expected { + t.Errorf("expected\n%s\n,got:\n%s", expected, got) + } +} + +func TestContextSuggesterSourceWithMultipleContexts(t *testing.T) { + s := NewContextSuggester("place_suggestion"). + Prefix("tim"). + Field("suggest"). + ContextQueries( + NewSuggesterCategoryQuery("place_type", "cafe", "restaurants"), + ) + src, err := s.Source(true) + if err != nil { + t.Fatal(err) + } + data, err := json.Marshal(src) + if err != nil { + t.Fatalf("marshaling to JSON failed: %v", err) + } + got := string(data) + // Due to the randomization of dictionary key, we could actually have two different valid expected outcomes + expected := `{"place_suggestion":{"prefix":"tim","completion":{"context":{"place_type":[{"context":"cafe"},{"context":"restaurants"}]},"field":"suggest"}}}` + if got != expected { + expected := `{"place_suggestion":{"prefix":"tim","completion":{"context":{"place_type":[{"context":"restaurants"},{"context":"cafe"}]},"field":"suggest"}}}` + if got != expected { + t.Errorf("expected %s\n,got:\n%s", expected, got) + } + } +} diff --git a/vendor/gopkg.in/throttled/throttled.v2/.travis.yml b/vendor/gopkg.in/throttled/throttled.v2/.travis.yml index 29225d7af..0c19e2cd5 100644 --- a/vendor/gopkg.in/throttled/throttled.v2/.travis.yml +++ b/vendor/gopkg.in/throttled/throttled.v2/.travis.yml @@ -3,8 +3,13 @@ sudo: false language: go go: - - 1.3 - - tip + - 1.7 + - 1.8 + - 1.9 + # 1.x builds the latest in that series. Also try to add other versions here + # as they come up so that we're pretty sure that we're maintaining + # backwards compatibility. + - 1.x notifications: email: false @@ -12,13 +17,6 @@ notifications: services: - redis-server -install: - - make get-deps - # Move to the gopkg location that rather than the default clone location - # otherwise Go 1.4+ complains about incorrect import paths. - - export GOPKG_DIR=$GOPATH/src/gopkg.in/throttled - - mkdir -p $GOPKG_DIR - - mv $TRAVIS_BUILD_DIR $GOPKG_DIR/throttled.v2 - - cd $GOPKG_DIR/throttled.v2 +install: make get-deps script: make diff --git a/vendor/gopkg.in/throttled/throttled.v2/Makefile b/vendor/gopkg.in/throttled/throttled.v2/Makefile index cfc235c31..d6e33c516 100644 --- a/vendor/gopkg.in/throttled/throttled.v2/Makefile +++ b/vendor/gopkg.in/throttled/throttled.v2/Makefile @@ -11,9 +11,7 @@ bench: lint: gofmt -l . -ifneq ($(TRAVIS_GO_VERSION),1.3) # go vet doesn't play nicely on 1.3 go vet ./... -endif which golint # Fail if golint doesn't exist -golint . # Don't fail on golint warnings themselves -golint store # Don't fail on golint warnings themselves diff --git a/vendor/gopkg.in/throttled/throttled.v2/README.md b/vendor/gopkg.in/throttled/throttled.v2/README.md index b18dcbcc6..d0e0609a5 100644 --- a/vendor/gopkg.in/throttled/throttled.v2/README.md +++ b/vendor/gopkg.in/throttled/throttled.v2/README.md @@ -1,7 +1,7 @@ -# Throttled [![build status](https://secure.travis-ci.org/throttled/throttled.png)](https://travis-ci.org/throttled/throttled) [![GoDoc](https://godoc.org/gopkg.in/throttled/throttled.v2?status.png)](https://godoc.org/gopkg.in/throttled/throttled.v2) +# Throttled [![build status](https://secure.travis-ci.org/throttled/throttled.svg)](https://travis-ci.org/throttled/throttled) [![GoDoc](https://godoc.org/github.com/throttled/throttled?status.svg)](https://godoc.org/github.com/throttled/throttled) -Package throttled implements rate limiting access to resources such as -HTTP endpoints. +Package throttled implements rate limiting using the [generic cell rate +algorithm][gcra] to limit access to resources such as HTTP endpoints. The 2.0.0 release made some major changes to the throttled API. If this change broke your code in problematic ways or you wish a feature @@ -11,16 +11,9 @@ what our users need. Thanks! ## Installation -throttled uses gopkg.in for semantic versioning: -`go get gopkg.in/throttled/throttled.v2` - -As of July 27, 2015, the package is located under its own Github -organization. Please adjust your imports to -`gopkg.in/throttled/throttled.v2`. - -The 1.x release series is compatible with the original, unversioned -library written by [Martin Angers][puerkitobio]. There is a -[blog post explaining that version's usage on 0value.com][blog]. +```sh +go get -u github.com/throttled/throttled` +``` ## Documentation @@ -29,57 +22,39 @@ example demonstrates the usage of HTTPLimiter for rate-limiting access to an http.Handler to 20 requests per path per minute with bursts of up to 5 additional requests: - store, err := memstore.New(65536) - if err != nil { - log.Fatal(err) - } - - quota := throttled.RateQuota{throttled.PerMin(20), 5} - rateLimiter, err := throttled.NewGCRARateLimiter(store, quota) - if err != nil { - log.Fatal(err) - } - - httpRateLimiter := throttled.HTTPRateLimiter{ - RateLimiter: rateLimiter, - VaryBy: &throttled.VaryBy{Path: true}, - } +```go +store, err := memstore.New(65536) +if err != nil { + log.Fatal(err) +} - http.ListenAndServe(":8080", httpRateLimiter.RateLimit(myHandler)) +quota := throttled.RateQuota{throttled.PerMin(20), 5} +rateLimiter, err := throttled.NewGCRARateLimiter(store, quota) +if err != nil { + log.Fatal(err) +} -## Contributing +httpRateLimiter := throttled.HTTPRateLimiter{ + RateLimiter: rateLimiter, + VaryBy: &throttled.VaryBy{Path: true}, +} -Since throttled uses gopkg.in for versioning, running `go get` against -a fork or cloning from Github to the default path will break -imports. Instead, use the following process for setting up your -environment and contributing: - -```sh -# Retrieve the source and dependencies. -go get gopkg.in/throttled/throttled.v2/... - -# Fork the project on Github. For all following directions replace -# with your Github username. Add your fork as a remote. -cd $GOPATH/src/gopkg.in/throttled/throttled.v2 -git remote add fork git@github.com:/throttled.git - -# Create a branch, make your changes, test them and commit. -git checkout -b my-new-feature -# -make test -git commit -a -git push -u fork my-new-feature +http.ListenAndServe(":8080", httpRateLimiter.RateLimit(myHandler)) ``` -When your changes are ready, [open a pull request][pr] using "compare -across forks". +## Related Projects + +See [throttled/gcra][throttled-gcra] for a list of other projects related to +rate limiting and GCRA. ## License -The [BSD 3-clause license][bsd]. Copyright (c) 2014 Martin Angers and Contributors. +The [BSD 3-clause license][bsd]. Copyright (c) 2014 Martin Angers and contributors. [blog]: http://0value.com/throttled--guardian-of-the-web-server [bsd]: https://opensource.org/licenses/BSD-3-Clause -[doc]: https://godoc.org/gopkg.in/throttled/throttled.v2 +[doc]: https://godoc.org/github.com/throttled/throttled +[gcra]: https://en.wikipedia.org/wiki/Generic_cell_rate_algorithm [puerkitobio]: https://github.com/puerkitobio/ [pr]: https://github.com/throttled/throttled/compare +[throttled-gcra]: https://github.com/throttled/gcra diff --git a/vendor/gopkg.in/throttled/throttled.v2/deprecated_test.go b/vendor/gopkg.in/throttled/throttled.v2/deprecated_test.go index 93406648f..e0453d78f 100644 --- a/vendor/gopkg.in/throttled/throttled.v2/deprecated_test.go +++ b/vendor/gopkg.in/throttled/throttled.v2/deprecated_test.go @@ -5,8 +5,8 @@ import ( "net/http/httptest" "testing" - "gopkg.in/throttled/throttled.v2" - "gopkg.in/throttled/throttled.v2/store" + "github.com/throttled/throttled" + "github.com/throttled/throttled/store" ) // Ensure that the current implementation remains compatible with the diff --git a/vendor/gopkg.in/throttled/throttled.v2/doc.go b/vendor/gopkg.in/throttled/throttled.v2/doc.go index 302c2bed7..cb14a65a6 100644 --- a/vendor/gopkg.in/throttled/throttled.v2/doc.go +++ b/vendor/gopkg.in/throttled/throttled.v2/doc.go @@ -1,3 +1,3 @@ // Package throttled implements rate limiting access to resources such // as HTTP endpoints. -package throttled // import "gopkg.in/throttled/throttled.v2" +package throttled // import "github.com/throttled/throttled" diff --git a/vendor/gopkg.in/throttled/throttled.v2/example_test.go b/vendor/gopkg.in/throttled/throttled.v2/example_test.go index 66e6374be..7c4c5df14 100644 --- a/vendor/gopkg.in/throttled/throttled.v2/example_test.go +++ b/vendor/gopkg.in/throttled/throttled.v2/example_test.go @@ -5,8 +5,8 @@ import ( "log" "net/http" - "gopkg.in/throttled/throttled.v2" - "gopkg.in/throttled/throttled.v2/store/memstore" + "github.com/throttled/throttled" + "github.com/throttled/throttled/store/memstore" ) var myHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/vendor/gopkg.in/throttled/throttled.v2/http_test.go b/vendor/gopkg.in/throttled/throttled.v2/http_test.go index 42761da09..52a706e2d 100644 --- a/vendor/gopkg.in/throttled/throttled.v2/http_test.go +++ b/vendor/gopkg.in/throttled/throttled.v2/http_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "gopkg.in/throttled/throttled.v2" + "github.com/throttled/throttled" ) type stubLimiter struct { diff --git a/vendor/gopkg.in/throttled/throttled.v2/rate.go b/vendor/gopkg.in/throttled/throttled.v2/rate.go index 8c11cdb47..649287beb 100644 --- a/vendor/gopkg.in/throttled/throttled.v2/rate.go +++ b/vendor/gopkg.in/throttled/throttled.v2/rate.go @@ -84,17 +84,18 @@ type Rate struct { // RateQuota describes the number of requests allowed per time period. // MaxRate specified the maximum sustained rate of requests and must -// be greater than zero. MaxBurst defines the number of requests that +// be greater than zero. MaxBurst defines the number of requests that // will be allowed to exceed the rate in a single burst and must be // greater than or equal to zero. // // Rate{PerSec(1), 0} would mean that after each request, no more -// requests will be permitted for that client for one second. In -// practice, you probably want to set MaxBurst >0 to provide some -// flexibility to clients that only need to make a handful of -// requests. In fact a MaxBurst of zero will *never* permit a request -// with a quantity greater than one because it will immediately exceed -// the limit. +// requests will be permitted for that client for one second. +// Rate{PerSec(2), 0} permits one request per 0.5 seconds rather than +// two requests in one second. In practice, you probably want to set +// MaxBurst >0 to provide some flexibility to clients that only need +// to make a handful of requests. In fact a MaxBurst of zero will +// *never* permit a request with a quantity greater than one because +// it will immediately exceed the limit. type RateQuota struct { MaxRate Rate MaxBurst int @@ -118,10 +119,12 @@ func PerDay(n int) Rate { return Rate{24 * time.Hour / time.Duration(n), n} } // as for limiting the number of bytes uploaded. type GCRARateLimiter struct { limit int + // Think of the DVT as our flexibility: // How far can you deviate from the nominal equally spaced schedule? // If you like leaky buckets, think about it as the size of your bucket. delayVariationTolerance time.Duration + // Think of the emission interval as the time between events // in the nominal equally spaced schedule. If you like leaky buckets, // think of it as how frequently the bucket leaks one unit. diff --git a/vendor/gopkg.in/throttled/throttled.v2/rate_test.go b/vendor/gopkg.in/throttled/throttled.v2/rate_test.go index 292a050bc..a1a5f621e 100644 --- a/vendor/gopkg.in/throttled/throttled.v2/rate_test.go +++ b/vendor/gopkg.in/throttled/throttled.v2/rate_test.go @@ -4,8 +4,8 @@ import ( "testing" "time" - "gopkg.in/throttled/throttled.v2" - "gopkg.in/throttled/throttled.v2/store/memstore" + "github.com/throttled/throttled" + "github.com/throttled/throttled/store/memstore" ) const deniedStatus = 429 diff --git a/vendor/gopkg.in/throttled/throttled.v2/store/deprecated.go b/vendor/gopkg.in/throttled/throttled.v2/store/deprecated.go index 5476e87ac..0492ba89e 100644 --- a/vendor/gopkg.in/throttled/throttled.v2/store/deprecated.go +++ b/vendor/gopkg.in/throttled/throttled.v2/store/deprecated.go @@ -1,11 +1,11 @@ // Package store contains deprecated aliases for subpackages -package store // import "gopkg.in/throttled/throttled.v2/store" +package store // import "github.com/throttled/throttled/store" import ( "github.com/garyburd/redigo/redis" - "gopkg.in/throttled/throttled.v2/store/memstore" - "gopkg.in/throttled/throttled.v2/store/redigostore" + "github.com/throttled/throttled/store/memstore" + "github.com/throttled/throttled/store/redigostore" ) // DEPRECATED. NewMemStore is a compatible alias for mem.New diff --git a/vendor/gopkg.in/throttled/throttled.v2/store/memstore/memstore.go b/vendor/gopkg.in/throttled/throttled.v2/store/memstore/memstore.go index 5d8fee8b5..352232958 100644 --- a/vendor/gopkg.in/throttled/throttled.v2/store/memstore/memstore.go +++ b/vendor/gopkg.in/throttled/throttled.v2/store/memstore/memstore.go @@ -1,5 +1,5 @@ // Package memstore offers an in-memory store implementation for throttled. -package memstore // import "gopkg.in/throttled/throttled.v2/store/memstore" +package memstore // import "github.com/throttled/throttled/store/memstore" import ( "sync" diff --git a/vendor/gopkg.in/throttled/throttled.v2/store/memstore/memstore_test.go b/vendor/gopkg.in/throttled/throttled.v2/store/memstore/memstore_test.go index ef003d3de..27b1c9b95 100644 --- a/vendor/gopkg.in/throttled/throttled.v2/store/memstore/memstore_test.go +++ b/vendor/gopkg.in/throttled/throttled.v2/store/memstore/memstore_test.go @@ -3,8 +3,8 @@ package memstore_test import ( "testing" - "gopkg.in/throttled/throttled.v2/store/memstore" - "gopkg.in/throttled/throttled.v2/store/storetest" + "github.com/throttled/throttled/store/memstore" + "github.com/throttled/throttled/store/storetest" ) func TestMemStoreLRU(t *testing.T) { diff --git a/vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redigostore.go b/vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redigostore.go index 54208fa6d..03acbcab0 100644 --- a/vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redigostore.go +++ b/vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redigostore.go @@ -1,5 +1,5 @@ // Package redigostore offers Redis-based store implementation for throttled using redigo. -package redigostore // import "gopkg.in/throttled/throttled.v2/store/redigostore" +package redigostore // import "github.com/throttled/throttled/store/redigostore" import ( "strings" @@ -18,11 +18,7 @@ end if v ~= ARGV[1] then return 0 end -if ARGV[3] ~= "0" then - redis.call('setex', KEYS[1], ARGV[3], ARGV[2]) -else - redis.call('set', KEYS[1], ARGV[2]) -end +redis.call('setex', KEYS[1], ARGV[3], ARGV[2]) return 1 ` ) @@ -106,10 +102,17 @@ func (r *RedigoStore) SetIfNotExistsWithTTL(key string, value int64, ttl time.Du updated := v == 1 - if ttl >= time.Second { - if _, err := conn.Do("EXPIRE", key, int(ttl.Seconds())); err != nil { - return updated, err - } + ttlSeconds := int(ttl.Seconds()) + + // An `EXPIRE 0` will delete the key immediately, so make sure that we set + // expiry for a minimum of one second out so that our results stay in the + // store. + if ttlSeconds < 1 { + ttlSeconds = 1 + } + + if _, err := conn.Do("EXPIRE", key, ttlSeconds); err != nil { + return updated, err } return updated, nil @@ -128,7 +131,16 @@ func (r *RedigoStore) CompareAndSwapWithTTL(key string, old, new int64, ttl time } defer conn.Close() - swapped, err := redis.Bool(conn.Do("EVAL", redisCASScript, 1, key, old, new, int(ttl.Seconds()))) + ttlSeconds := int(ttl.Seconds()) + + // An `EXPIRE 0` will delete the key immediately, so make sure that we set + // expiry for a minimum of one second out so that our results stay in the + // store. + if ttlSeconds < 1 { + ttlSeconds = 1 + } + + swapped, err := redis.Bool(conn.Do("EVAL", redisCASScript, 1, key, old, new, ttlSeconds)) if err != nil { if strings.Contains(err.Error(), redisCASMissingKey) { return false, nil diff --git a/vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redigostore_test.go b/vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redigostore_test.go new file mode 100644 index 000000000..ee9e2904d --- /dev/null +++ b/vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redigostore_test.go @@ -0,0 +1,85 @@ +package redigostore_test + +import ( + "testing" + "time" + + "github.com/garyburd/redigo/redis" + + "github.com/throttled/throttled/store/redigostore" + "github.com/throttled/throttled/store/storetest" +) + +const ( + redisTestDB = 1 + redisTestPrefix = "throttled:" +) + +func getPool() *redis.Pool { + pool := &redis.Pool{ + MaxIdle: 3, + IdleTimeout: 30 * time.Second, + Dial: func() (redis.Conn, error) { + return redis.Dial("tcp", ":6379") + }, + TestOnBorrow: func(c redis.Conn, t time.Time) error { + _, err := c.Do("PING") + return err + }, + } + return pool +} + +func TestRedisStore(t *testing.T) { + c, st := setupRedis(t, 0) + defer c.Close() + defer clearRedis(c) + + clearRedis(c) + storetest.TestGCRAStore(t, st) + storetest.TestGCRAStoreTTL(t, st) +} + +func BenchmarkRedisStore(b *testing.B) { + c, st := setupRedis(b, 0) + defer c.Close() + defer clearRedis(c) + + storetest.BenchmarkGCRAStore(b, st) +} + +func clearRedis(c redis.Conn) error { + keys, err := redis.Values(c.Do("KEYS", redisTestPrefix+"*")) + if err != nil { + return err + } + + if _, err := redis.Int(c.Do("DEL", keys...)); err != nil { + return err + } + + return nil +} + +func setupRedis(tb testing.TB, ttl time.Duration) (redis.Conn, *redigostore.RedigoStore) { + pool := getPool() + c := pool.Get() + + if _, err := redis.String(c.Do("PING")); err != nil { + c.Close() + tb.Skip("redis server not available on localhost port 6379") + } + + if _, err := redis.String(c.Do("SELECT", redisTestDB)); err != nil { + c.Close() + tb.Fatal(err) + } + + st, err := redigostore.New(pool, redisTestPrefix, redisTestDB) + if err != nil { + c.Close() + tb.Fatal(err) + } + + return c, st +} diff --git a/vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redisstore_test.go b/vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redisstore_test.go deleted file mode 100644 index d47b635d2..000000000 --- a/vendor/gopkg.in/throttled/throttled.v2/store/redigostore/redisstore_test.go +++ /dev/null @@ -1,85 +0,0 @@ -package redigostore_test - -import ( - "testing" - "time" - - "github.com/garyburd/redigo/redis" - - "gopkg.in/throttled/throttled.v2/store/redigostore" - "gopkg.in/throttled/throttled.v2/store/storetest" -) - -const ( - redisTestDB = 1 - redisTestPrefix = "throttled:" -) - -func getPool() *redis.Pool { - pool := &redis.Pool{ - MaxIdle: 3, - IdleTimeout: 30 * time.Second, - Dial: func() (redis.Conn, error) { - return redis.Dial("tcp", ":6379") - }, - TestOnBorrow: func(c redis.Conn, t time.Time) error { - _, err := c.Do("PING") - return err - }, - } - return pool -} - -func TestRedisStore(t *testing.T) { - c, st := setupRedis(t, 0) - defer c.Close() - defer clearRedis(c) - - clearRedis(c) - storetest.TestGCRAStore(t, st) - storetest.TestGCRAStoreTTL(t, st) -} - -func BenchmarkRedisStore(b *testing.B) { - c, st := setupRedis(b, 0) - defer c.Close() - defer clearRedis(c) - - storetest.BenchmarkGCRAStore(b, st) -} - -func clearRedis(c redis.Conn) error { - keys, err := redis.Values(c.Do("KEYS", redisTestPrefix+"*")) - if err != nil { - return err - } - - if _, err := redis.Int(c.Do("DEL", keys...)); err != nil { - return err - } - - return nil -} - -func setupRedis(tb testing.TB, ttl time.Duration) (redis.Conn, *redigostore.RedigoStore) { - pool := getPool() - c := pool.Get() - - if _, err := redis.String(c.Do("PING")); err != nil { - c.Close() - tb.Skip("redis server not available on localhost port 6379") - } - - if _, err := redis.String(c.Do("SELECT", redisTestDB)); err != nil { - c.Close() - tb.Fatal(err) - } - - st, err := redigostore.New(pool, redisTestPrefix, redisTestDB) - if err != nil { - c.Close() - tb.Fatal(err) - } - - return c, st -} diff --git a/vendor/gopkg.in/throttled/throttled.v2/store/storetest/doc.go b/vendor/gopkg.in/throttled/throttled.v2/store/storetest/doc.go index ecfee2638..405c59a12 100644 --- a/vendor/gopkg.in/throttled/throttled.v2/store/storetest/doc.go +++ b/vendor/gopkg.in/throttled/throttled.v2/store/storetest/doc.go @@ -1,2 +1,2 @@ // Package storetest provides a helper for testing throttled stores. -package storetest // import "gopkg.in/throttled/throttled.v2/store/storetest" +package storetest // import "github.com/throttled/throttled/store/storetest" diff --git a/vendor/gopkg.in/throttled/throttled.v2/store/storetest/storetest.go b/vendor/gopkg.in/throttled/throttled.v2/store/storetest/storetest.go index 191b40a4f..2233ebdfb 100644 --- a/vendor/gopkg.in/throttled/throttled.v2/store/storetest/storetest.go +++ b/vendor/gopkg.in/throttled/throttled.v2/store/storetest/storetest.go @@ -1,5 +1,5 @@ // Package storetest provides a helper for testing throttled stores. -package storetest // import "gopkg.in/throttled/throttled.v2/store/storetest" +package storetest // import "github.com/throttled/throttled/store/storetest" import ( "math/rand" @@ -8,7 +8,7 @@ import ( "testing" "time" - "gopkg.in/throttled/throttled.v2" + "github.com/throttled/throttled" ) // TestGCRAStore tests the behavior of a GCRAStore implementation for diff --git a/vendor/gopkg.in/throttled/throttled.v2/varyby_test.go b/vendor/gopkg.in/throttled/throttled.v2/varyby_test.go index 66a5f4e98..6ad48ea19 100644 --- a/vendor/gopkg.in/throttled/throttled.v2/varyby_test.go +++ b/vendor/gopkg.in/throttled/throttled.v2/varyby_test.go @@ -5,7 +5,7 @@ import ( "net/url" "testing" - "gopkg.in/throttled/throttled.v2" + "github.com/throttled/throttled" ) func TestVaryBy(t *testing.T) { -- cgit v1.2.3-1-g7c22