4545
4646import java .util .Arrays ;
4747
48- import static org .opensearch .action .bulk .BulkShardResponse .DEFAULT_QUEUE_SIZE ;
49- import static org .opensearch .action .bulk .BulkShardResponse .DEFAULT_SERVICE_TIME_IN_NANOS ;
50-
5148/**
5249 * This is a utility class that holds the per request state needed to perform bulk operations on the primary.
5350 * More specifically, it maintains an index to the current executing bulk item, which allows execution
@@ -91,13 +88,15 @@ enum ItemProcessingState {
9188 private int currentIndex = -1 ;
9289
9390 private ItemProcessingState currentItemState ;
94- private DocWriteRequest requestToExecute ;
91+ private DocWriteRequest <?> requestToExecute ;
9592 private BulkItemResponse executionResult ;
9693 private int retryCounter ;
94+ private final BulkItemResponse [] primaryResponses ;
9795
9896 BulkPrimaryExecutionContext (BulkShardRequest request , IndexShard primary ) {
9997 this .request = request ;
10098 this .primary = primary ;
99+ this .primaryResponses = new BulkItemResponse [request .items ().length ];
101100 advance ();
102101 }
103102
@@ -131,7 +130,12 @@ public DocWriteRequest<?> getCurrent() {
131130 }
132131
133132 public BulkShardRequest getBulkShardRequest () {
134- return request ;
133+ BulkItemRequest [] newRequests = new BulkItemRequest [request .items ().length ];
134+ for (int i = 0 ; i < newRequests .length ; i ++) {
135+ BulkItemRequest oldRequest = request .items ()[i ];
136+ newRequests [i ] = new BulkItemRequest (oldRequest .id (), oldRequest .request (), primaryResponses [i ]);
137+ }
138+ return new BulkShardRequest (request .shardId (), request .getRefreshPolicy (), newRequests );
135139 }
136140
137141 /** returns the result of the request that has been executed on the shard */
@@ -145,21 +149,11 @@ public int getRetryCounter() {
145149 return retryCounter ;
146150 }
147151
148- /** returns true if the current request has been executed on the primary */
149- public boolean isOperationExecuted () {
150- return currentItemState == ItemProcessingState .EXECUTED ;
151- }
152-
153152 /** returns true if the request needs to wait for a mapping update to arrive from the cluster-manager */
154153 public boolean requiresWaitingForMappingUpdate () {
155154 return currentItemState == ItemProcessingState .WAIT_FOR_MAPPING_UPDATE ;
156155 }
157156
158- /** returns true if the current request should be retried without waiting for an external event */
159- public boolean requiresImmediateRetry () {
160- return currentItemState == ItemProcessingState .IMMEDIATE_RETRY ;
161- }
162-
163157 /**
164158 * returns true if the current request has been completed and it's result translated to a user
165159 * facing response
@@ -206,17 +200,18 @@ public IndexShard getPrimary() {
206200 }
207201
208202 /**
209- * sets the request that should actually be executed on the primary. This can be different then the request
203+ * sets the request that should actually be executed on the primary. This can be different from the request
210204 * received from the user (specifically, an update request is translated to an indexing or delete request).
211205 */
212- public void setRequestToExecute (DocWriteRequest writeRequest ) {
206+ public void setRequestToExecute (DocWriteRequest <?> writeRequest ) {
213207 assert assertInvariants (ItemProcessingState .INITIAL );
214208 requestToExecute = writeRequest ;
215209 currentItemState = ItemProcessingState .TRANSLATED ;
216210 assert assertInvariants (ItemProcessingState .TRANSLATED );
217211 }
218212
219213 /** returns the request that should be executed on the shard. */
214+ @ SuppressWarnings ("unchecked" )
220215 public <T extends DocWriteRequest <T >> T getRequestToExecute () {
221216 assert assertInvariants (ItemProcessingState .TRANSLATED );
222217 return (T ) requestToExecute ;
@@ -252,7 +247,7 @@ public void markOperationAsNoOp(DocWriteResponse response) {
252247 public void failOnMappingUpdate (Exception cause ) {
253248 assert assertInvariants (ItemProcessingState .WAIT_FOR_MAPPING_UPDATE );
254249 currentItemState = ItemProcessingState .EXECUTED ;
255- final DocWriteRequest docWriteRequest = getCurrentItem ().request ();
250+ final DocWriteRequest <?> docWriteRequest = getCurrentItem ().request ();
256251 executionResult = new BulkItemResponse (
257252 getCurrentItem ().id (),
258253 docWriteRequest .opType (),
@@ -267,7 +262,7 @@ public void failOnMappingUpdate(Exception cause) {
267262 public void markOperationAsExecuted (Engine .Result result ) {
268263 assertInvariants (ItemProcessingState .TRANSLATED );
269264 final BulkItemRequest current = getCurrentItem ();
270- DocWriteRequest docWriteRequest = getRequestToExecute ();
265+ DocWriteRequest <?> docWriteRequest = getRequestToExecute ();
271266 switch (result .getResultType ()) {
272267 case SUCCESS :
273268 final DocWriteResponse response ;
@@ -347,24 +342,15 @@ public void markAsCompleted(BulkItemResponse translatedResponse) {
347342 if (translatedResponse .isFailed () == false && requestToExecute != null && requestToExecute != getCurrent ()) {
348343 request .items ()[currentIndex ] = new BulkItemRequest (request .items ()[currentIndex ].id (), requestToExecute );
349344 }
350- getCurrentItem (). setPrimaryResponse ( translatedResponse ) ;
345+ primaryResponses [ currentIndex ] = translatedResponse ;
351346 currentItemState = ItemProcessingState .COMPLETED ;
352347 advance ();
353348 }
354349
355350 /** builds the bulk shard response to return to the user */
356351 public BulkShardResponse buildShardResponse (long serviceTimeEWMAInNanos , int nodeQueueSize ) {
357352 assert hasMoreOperationsToExecute () == false ;
358- return new BulkShardResponse (
359- request .shardId (),
360- Arrays .stream (request .items ()).map (BulkItemRequest ::getPrimaryResponse ).toArray (BulkItemResponse []::new ),
361- serviceTimeEWMAInNanos ,
362- nodeQueueSize
363- );
364- }
365-
366- public BulkShardResponse buildShardResponse () {
367- return buildShardResponse (DEFAULT_SERVICE_TIME_IN_NANOS , DEFAULT_QUEUE_SIZE );
353+ return new BulkShardResponse (request .shardId (), primaryResponses , serviceTimeEWMAInNanos , nodeQueueSize );
368354 }
369355
370356 private boolean assertInvariants (ItemProcessingState ... expectedCurrentState ) {
@@ -379,18 +365,14 @@ private boolean assertInvariants(ItemProcessingState... expectedCurrentState) {
379365 assert requestToExecute == null : requestToExecute ;
380366 assert executionResult == null : executionResult ;
381367 break ;
382- case TRANSLATED :
368+ case TRANSLATED , IMMEDIATE_RETRY :
383369 assert requestToExecute != null ;
384370 assert executionResult == null : executionResult ;
385371 break ;
386372 case WAIT_FOR_MAPPING_UPDATE :
387373 assert requestToExecute == null ;
388374 assert executionResult == null : executionResult ;
389375 break ;
390- case IMMEDIATE_RETRY :
391- assert requestToExecute != null ;
392- assert executionResult == null : executionResult ;
393- break ;
394376 case EXECUTED :
395377 // requestToExecute can be null if the update ended up as NOOP
396378 assert executionResult != null ;
0 commit comments