feat[opensearchutil]: route subsequent bulk requests on the same documentID to the same worker. - #950
feat[opensearchutil]: route subsequent bulk requests on the same documentID to the same worker.#950yanaix10 wants to merge 7 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #950 +/- ##
==========================================
- Coverage 55.47% 55.46% -0.02%
==========================================
Files 660 660
Lines 64338 64378 +40
==========================================
+ Hits 35694 35705 +11
- Misses 26804 26828 +24
- Partials 1840 1845 +5
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
hey @sean- I am not very sure about the test case I wrote. I hardcorded the documentID. |
5155e4f to
e7d9f58
Compare
sean-
left a comment
There was a problem hiding this comment.
Admittedly, I haven't looked into the opensearchutil/BulkIndexer much, but I'm not a fan of it in its current incarnation because it's interface is not particularly rigid. That said, I think its internals should be adapted to use the opensearchtransport/DocRouter until a v2 of this package can be put together to tighten up its interface.
| // | ||
| // Adding an item after a call to Close() will panic. | ||
| func (bi *bulkIndexer) Add(ctx context.Context, item BulkIndexerItem) error { | ||
| var targetQueue chan BulkIndexerItem |
There was a problem hiding this comment.
Here, we'd take a BulkIndexerItem, encapsulate it as an http.Request, then pass it along to DocRouter.Eval(). In fact, there may be a chance that the new routing code in v5 (and if opted-in, v4) may just "do this" out of the box on a best-effort basis, but to force this, we should have opensearchtuil/ construct a DocRouter and firehose things into the DocRouter.
| - Default the benchmark pprof server to an ephemeral loopback port so back-to-back `go test -bench` runs no longer collide on a `TIME_WAIT` socket held by the prior run. The startup logic moves into an `internal/pprofutil` package that registers the pprof handlers on a private mux (off `http.DefaultServeMux`); `PPROF_ADDR` pins an explicit `host:port` when needed. ([#864](https://github.com/opensearch-project/opensearch-go/issues/864)) | ||
|
|
||
| - Consistently route bulk requests for the same DocumentID to the same worker to prevent race conditions ([#950](https://github.com/opensearch-project/opensearch-go/pull/950)). | ||
|
|
|
hey @sean- I have made required changes based on the feedback. Please review. |
| idx = bi.config.Index | ||
| } | ||
|
|
||
| u := url.URL{Path: path.Join("/", idx, "_doc", item.DocumentID)} |
There was a problem hiding this comment.
There's nothing here that escapes idx: we're just trusting the user input blindly. Can you look into url.PathUnescape() and look at the ./internal/build/ package and how it is used.
There was a problem hiding this comment.
I have used url.PathEscape() on idx and documentID to handle user input. manually constructing the http.Request and explicitly setting Path (via url.PathUnescape()) and RawPath. Due to manual construction I could drop http.NewRequest entirely - bypassing url.Parse allocation overhead.
There was a problem hiding this comment.
Because this is in the bulk-path, I'm not too worried about the performance, but it's up to you.
sean-
left a comment
There was a problem hiding this comment.
Thank you for adapting to using the router!
Signed-off-by: Naitik Yadav <naitik.yadav641@gmail.com>
Signed-off-by: Naitik Yadav <naitik.yadav641@gmail.com>
Signed-off-by: Naitik Yadav <naitik.yadav641@gmail.com>
Signed-off-by: Naitik Yadav <naitik.yadav641@gmail.com>
Signed-off-by: Naitik Yadav <naitik.yadav641@gmail.com>
…retain Eval Signed-off-by: Naitik Yadav <naitik.yadav641@gmail.com>
|
|
||
| encodedPath := "/" + url.PathEscape(idx) + "/_doc/" + url.PathEscape(item.DocumentID) | ||
|
|
||
| if p, err := url.PathUnescape(encodedPath); err == nil { |
There was a problem hiding this comment.
Question about the escape/unescape pair here: does the escaping survive to Eval?
Would putting the escaped form straight into Path work for what you were after, dropping PathUnescape and RawPath?
| }, | ||
| }).WithContext(ctx) | ||
|
|
||
| if hop, evalErr := bi.docRouter.Eval(ctx, req); evalErr == nil && hop.Conn != nil { |
There was a problem hiding this comment.
Does this Eval ever return a connection? I think NewDocRouter() gets its connections through DiscoveryUpdate(), which only the owning transport calls, so activeConns looks like it stays empty and Eval returns early at policy_doc_router.go:144-150.
Changes made :