From 6721df934df7bf7f1d210977beb728ec0d8b5630 Mon Sep 17 00:00:00 2001 From: Hamish Macpherson Date: Thu, 19 Mar 2026 14:55:22 -0700 Subject: [PATCH 1/3] fix(sqs): make visibility timeout and batch size configurable The SQS client had a hardcoded VisibilityTimeout of 36000 seconds (10 hours), which caused the ApproximateAgeOfOldestMessage metric to climb to ~10h before messages expired from in-flight status. This directly triggered recurring PagerDuty alerts on the elasticsearch_indexer_k8s queue. Changes: - Add functional options pattern (WithVisibilityTimeout, WithMaxMessages, WithWaitTimeSeconds) so callers can configure per-queue settings - Change defaults to sensible values: 120s visibility, 10 max messages, 20s wait time - Add ReceiveBatch() method that returns all messages (up to max) - Keep Receive() backwards-compatible (returns first message only) - Existing callers that pass no options get the new defaults automatically Co-Authored-By: Claude Opus 4.6 (1M context) --- sqs/sqs.go | 95 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 21 deletions(-) diff --git a/sqs/sqs.go b/sqs/sqs.go index 210a141..eb4af37 100644 --- a/sqs/sqs.go +++ b/sqs/sqs.go @@ -10,12 +10,48 @@ import ( // Client all things SQS type Client struct { - queueURL string - client *sqs.SQS + queueURL string + client *sqs.SQS + visibilityTimeout int64 + maxMessages int64 + waitTimeSeconds int64 } -// NewClient creates a SQS client. -func NewClient(awsAccessKeyID string, awsSecretAccessKey string, queueURL string) (*Client, error) { +// Option configures the SQS client. +type Option func(*Client) + +// WithVisibilityTimeout sets the visibility timeout in seconds for received messages. +// Default is 120 seconds. +func WithVisibilityTimeout(seconds int64) Option { + return func(c *Client) { + c.visibilityTimeout = seconds + } +} + +// WithMaxMessages sets the maximum number of messages to receive per poll. +// Valid range is 1-10. Default is 10. +func WithMaxMessages(n int64) Option { + return func(c *Client) { + if n < 1 { + n = 1 + } + if n > 10 { + n = 10 + } + c.maxMessages = n + } +} + +// WithWaitTimeSeconds sets the long-poll wait time in seconds. +// Default is 20 seconds. +func WithWaitTimeSeconds(seconds int64) Option { + return func(c *Client) { + c.waitTimeSeconds = seconds + } +} + +// NewClient creates a SQS client. Options can override defaults. +func NewClient(awsAccessKeyID string, awsSecretAccessKey string, queueURL string, opts ...Option) (*Client, error) { sess, err := session.NewSession() if err != nil { @@ -27,31 +63,48 @@ func NewClient(awsAccessKeyID string, awsSecretAccessKey string, queueURL string Region: aws.String("us-east-1"), } - return &Client{ - queueURL: queueURL, - client: sqs.New(sess, awsConfig), - }, nil + c := &Client{ + queueURL: queueURL, + client: sqs.New(sess, awsConfig), + visibilityTimeout: 120, + maxMessages: 10, + waitTimeSeconds: 20, + } + + for _, opt := range opts { + opt(c) + } + + return c, nil } -// Receive receive a message from the queue. +// Receive receives a single message from the queue. +// For backwards compatibility, returns only the first message even if +// multiple are fetched. Use ReceiveBatch to get all messages. func (c *Client) Receive() (msg *sqs.Message, err error) { - var out *sqs.ReceiveMessageOutput - out, err = c.client.ReceiveMessage(&sqs.ReceiveMessageInput{ + msgs, err := c.ReceiveBatch() + if err != nil { + return nil, err + } + if len(msgs) == 0 { + return nil, nil + } + return msgs[0], nil +} + +// ReceiveBatch receives up to MaxMessages messages from the queue. +func (c *Client) ReceiveBatch() ([]*sqs.Message, error) { + out, err := c.client.ReceiveMessage(&sqs.ReceiveMessageInput{ QueueUrl: aws.String(c.queueURL), - MaxNumberOfMessages: aws.Int64(1), - VisibilityTimeout: aws.Int64(36000), - WaitTimeSeconds: aws.Int64(20), + MaxNumberOfMessages: aws.Int64(c.maxMessages), + VisibilityTimeout: aws.Int64(c.visibilityTimeout), + WaitTimeSeconds: aws.Int64(c.waitTimeSeconds), }) if err != nil { - err = errors.Wrap(err, "receiving sqs message failed") - return + return nil, errors.Wrap(err, "receiving sqs message failed") } - if len(out.Messages) <= 0 { - return nil, nil - } - msg = out.Messages[0] - return + return out.Messages, nil } // Delete deletes a message from the queue. From 3fae9887af208fd0d85dd5f1e2625165024ad7e3 Mon Sep 17 00:00:00 2001 From: Hamish Macpherson Date: Thu, 19 Mar 2026 15:05:30 -0700 Subject: [PATCH 2/3] =?UTF-8?q?fix(sqs):=20address=20review=20=E2=80=94=20?= =?UTF-8?q?Receive=20loses=20messages,=20add=20option=20validation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Receive() was delegating to ReceiveBatch() which fetches up to maxMessages, then returning only the first. The remaining messages became invisible for the visibility timeout but were never deleted. Now uses a private receiveMessages(1) helper so only 1 message is fetched from SQS. - WithVisibilityTimeout now clamps to 0–43200 (AWS SQS limit). - WithWaitTimeSeconds now clamps to 0–20 (AWS SQS limit). - Follows the same validation pattern already used in WithMaxMessages. Co-Authored-By: Claude Opus 4.6 (1M context) --- sqs/sqs.go | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/sqs/sqs.go b/sqs/sqs.go index eb4af37..8bc1af9 100644 --- a/sqs/sqs.go +++ b/sqs/sqs.go @@ -21,9 +21,15 @@ type Client struct { type Option func(*Client) // WithVisibilityTimeout sets the visibility timeout in seconds for received messages. -// Default is 120 seconds. +// Valid range is 0–43200 (12 hours). Default is 120 seconds. func WithVisibilityTimeout(seconds int64) Option { return func(c *Client) { + if seconds < 0 { + seconds = 0 + } + if seconds > 43200 { + seconds = 43200 + } c.visibilityTimeout = seconds } } @@ -43,9 +49,15 @@ func WithMaxMessages(n int64) Option { } // WithWaitTimeSeconds sets the long-poll wait time in seconds. -// Default is 20 seconds. +// Valid range is 0–20. Default is 20 seconds. func WithWaitTimeSeconds(seconds int64) Option { return func(c *Client) { + if seconds < 0 { + seconds = 0 + } + if seconds > 20 { + seconds = 20 + } c.waitTimeSeconds = seconds } } @@ -79,10 +91,9 @@ func NewClient(awsAccessKeyID string, awsSecretAccessKey string, queueURL string } // Receive receives a single message from the queue. -// For backwards compatibility, returns only the first message even if -// multiple are fetched. Use ReceiveBatch to get all messages. +// It polls SQS with MaxNumberOfMessages=1 so no other messages are hidden. func (c *Client) Receive() (msg *sqs.Message, err error) { - msgs, err := c.ReceiveBatch() + msgs, err := c.receiveMessages(1) if err != nil { return nil, err } @@ -94,9 +105,13 @@ func (c *Client) Receive() (msg *sqs.Message, err error) { // ReceiveBatch receives up to MaxMessages messages from the queue. func (c *Client) ReceiveBatch() ([]*sqs.Message, error) { + return c.receiveMessages(c.maxMessages) +} + +func (c *Client) receiveMessages(maxMessages int64) ([]*sqs.Message, error) { out, err := c.client.ReceiveMessage(&sqs.ReceiveMessageInput{ QueueUrl: aws.String(c.queueURL), - MaxNumberOfMessages: aws.Int64(c.maxMessages), + MaxNumberOfMessages: aws.Int64(maxMessages), VisibilityTimeout: aws.Int64(c.visibilityTimeout), WaitTimeSeconds: aws.Int64(c.waitTimeSeconds), }) From a7f6d7d9c518808abcef1e2ff21be77c30e31a60 Mon Sep 17 00:00:00 2001 From: Eric Khun Date: Mon, 23 Mar 2026 12:24:43 +0800 Subject: [PATCH 3/3] build: add Go modules (go.mod/go.sum) Switch from GOPATH mode to Go modules so dependencies are pinned and the project builds reliably with modern Go toolchains. Required because transitive dependencies (mongo-driver, klauspost/compress) now use Go 1.21+ stdlib packages that break GOPATH-mode builds. --- go.mod | 17 +++++++++++ go.sum | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 go.mod create mode 100644 go.sum diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..b9a837a --- /dev/null +++ b/go.mod @@ -0,0 +1,17 @@ +module github.com/bufferapp/go-base-worker + +go 1.23 + +require ( + github.com/aws/aws-sdk-go v1.55.8 + github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8 + github.com/pkg/errors v0.9.1 + github.com/sha1sum/aws_signing_client v0.0.0-20200229211254-f7815c59d5c1 + gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 + gopkg.in/olivere/elastic.v5 v5.0.86 +) + +require ( + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/mailru/easyjson v0.7.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..37ca2d1 --- /dev/null +++ b/go.sum @@ -0,0 +1,89 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/aws/aws-sdk-go v1.29.11/go.mod h1:1KvfttTE3SPKMpo8g2c6jL3ZKfXtFvKscTgahTma5Xg= +github.com/aws/aws-sdk-go v1.55.8 h1:JRmEUbU52aJQZ2AjX4q4Wu7t4uZjOu71uyNmaWlUkJQ= +github.com/aws/aws-sdk-go v1.55.8/go.mod h1:ZkViS9AqA6otK+JBBNH2++sx1sgxrPKcSzPPvQkUtXk= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +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/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8 h1:DujepqpGd1hyOd7aW59XpK7Qymp8iy83xq74fLr21is= +github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/mailru/easyjson v0.7.1 h1:mdxE1MF9o53iCb2Ghj1VfWvh7ZOwHpnVG/xwXrV90U8= +github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/olivere/elastic/v7 v7.0.12/go.mod h1:14rWX28Pnh3qCKYRVnSGXWLf9MbLonYS/4FDCY3LAPo= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +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/sha1sum/aws_signing_client v0.0.0-20200229211254-f7815c59d5c1 h1:k3oIn0gu6A3olJwowlMKxFwiqTi2wm5UbzBVEomlJEY= +github.com/sha1sum/aws_signing_client v0.0.0-20200229211254-f7815c59d5c1/go.mod h1:hPj3jKAamv0ryZvssbqkCeOWYFmy9itWMSOD7tDsE3E= +github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= +github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= +github.com/smartystreets/gunit v1.1.3/go.mod h1:EH5qMBab2UclzXUcpR8b93eHsIlp9u+pDQIRp5DZNzQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw= +gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/olivere/elastic.v5 v5.0.86 h1:xFy6qRCGAmo5Wjx96srho9BitLhZl2fcnpuidPwduXM= +gopkg.in/olivere/elastic.v5 v5.0.86/go.mod h1:M3WNlsF+WhYn7api4D87NIflwTV/c0iVs8cqfWhK+68= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=