Skip to content

Commit a162cc9

Browse files
jonathan-buttneromricohenn
authored andcommitted
[ML] Return empty usage statistics in the event of an failure (elastic#124799)
* Returning empty usage on failure * Adding logging
1 parent 20cc52d commit a162cc9

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/inference/InferenceFeatureSetUsage.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import java.io.IOException;
2222
import java.util.Collection;
23+
import java.util.List;
2324
import java.util.Objects;
2425

2526
public class InferenceFeatureSetUsage extends XPackFeatureUsage {
@@ -101,6 +102,8 @@ public int hashCode() {
101102
}
102103
}
103104

105+
public static final InferenceFeatureSetUsage EMPTY = new InferenceFeatureSetUsage(List.of());
106+
104107
private final Collection<ModelStats> modelStats;
105108

106109
public InferenceFeatureSetUsage(Collection<ModelStats> modelStats) {
@@ -129,4 +132,16 @@ public void writeTo(StreamOutput out) throws IOException {
129132
public TransportVersion getMinimalSupportedVersion() {
130133
return TransportVersions.V_8_12_0;
131134
}
135+
136+
@Override
137+
public boolean equals(Object o) {
138+
if (o == null || getClass() != o.getClass()) return false;
139+
InferenceFeatureSetUsage that = (InferenceFeatureSetUsage) o;
140+
return Objects.equals(modelStats, that.modelStats);
141+
}
142+
143+
@Override
144+
public int hashCode() {
145+
return Objects.hashCode(modelStats);
146+
}
132147
}

x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/action/TransportInferenceUsageAction.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@
77

88
package org.elasticsearch.xpack.inference.action;
99

10+
import org.apache.logging.log4j.LogManager;
11+
import org.apache.logging.log4j.Logger;
1012
import org.elasticsearch.action.ActionListener;
1113
import org.elasticsearch.action.support.ActionFilters;
1214
import org.elasticsearch.client.internal.Client;
1315
import org.elasticsearch.client.internal.OriginSettingClient;
1416
import org.elasticsearch.cluster.ClusterState;
1517
import org.elasticsearch.cluster.service.ClusterService;
18+
import org.elasticsearch.common.Strings;
1619
import org.elasticsearch.inference.ModelConfigurations;
1720
import org.elasticsearch.inference.TaskType;
1821
import org.elasticsearch.injection.guice.Inject;
@@ -33,6 +36,8 @@
3336

3437
public class TransportInferenceUsageAction extends XPackUsageFeatureTransportAction {
3538

39+
private final Logger logger = LogManager.getLogger(TransportInferenceUsageAction.class);
40+
3641
private final Client client;
3742

3843
@Inject
@@ -55,7 +60,7 @@ protected void localClusterStateOperation(
5560
ActionListener<XPackUsageFeatureResponse> listener
5661
) {
5762
GetInferenceModelAction.Request getInferenceModelAction = new GetInferenceModelAction.Request("_all", TaskType.ANY, false);
58-
client.execute(GetInferenceModelAction.INSTANCE, getInferenceModelAction, listener.delegateFailureAndWrap((delegate, response) -> {
63+
client.execute(GetInferenceModelAction.INSTANCE, getInferenceModelAction, ActionListener.wrap(response -> {
5964
Map<String, InferenceFeatureSetUsage.ModelStats> stats = new TreeMap<>();
6065
for (ModelConfigurations model : response.getEndpoints()) {
6166
String statKey = model.getService() + ":" + model.getTaskType().name();
@@ -66,7 +71,10 @@ protected void localClusterStateOperation(
6671
stat.add();
6772
}
6873
InferenceFeatureSetUsage usage = new InferenceFeatureSetUsage(stats.values());
69-
delegate.onResponse(new XPackUsageFeatureResponse(usage));
74+
listener.onResponse(new XPackUsageFeatureResponse(usage));
75+
}, e -> {
76+
logger.warn(Strings.format("Retrieving inference usage failed with error: %s", e.getMessage()), e);
77+
listener.onResponse(new XPackUsageFeatureResponse(InferenceFeatureSetUsage.EMPTY));
7078
}));
7179
}
7280
}

x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/action/TransportInferenceUsageActionTests.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
import java.util.List;
4040

41+
import static org.elasticsearch.xpack.inference.Utils.TIMEOUT;
4142
import static org.hamcrest.Matchers.hasSize;
4243
import static org.hamcrest.core.Is.is;
4344
import static org.mockito.ArgumentMatchers.any;
@@ -116,4 +117,19 @@ public void test() throws Exception {
116117
assertThat(source.getValue("models.2.task_type"), is("TEXT_EMBEDDING"));
117118
assertThat(source.getValue("models.2.count"), is(3));
118119
}
120+
121+
public void testFailureReturnsEmptyUsage() {
122+
doAnswer(invocation -> {
123+
ActionListener<GetInferenceModelAction.Response> listener = invocation.getArgument(2);
124+
listener.onFailure(new IllegalArgumentException("invalid field"));
125+
return Void.TYPE;
126+
}).when(client).execute(any(GetInferenceModelAction.class), any(), any());
127+
128+
var future = new PlainActionFuture<XPackUsageFeatureResponse>();
129+
action.localClusterStateOperation(mock(Task.class), mock(XPackUsageRequest.class), mock(ClusterState.class), future);
130+
131+
var usage = future.actionGet(TIMEOUT);
132+
var inferenceUsage = (InferenceFeatureSetUsage) usage.getUsage();
133+
assertThat(inferenceUsage, is(InferenceFeatureSetUsage.EMPTY));
134+
}
119135
}

0 commit comments

Comments
 (0)