forked from elastic/kibana
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ML] File upload adding deployment initialization step (elastic#198446)
Fixes elastic#196696 When adding a semantic text field, we now have an additional step in the file uploading process which calls inference for the selected inference endpoint. The response of the inference call is ignored and a poll is started to check to see of the model has been deployed by check to see if `num_allocations > 0` Any errors returned from the inference call will stop the upload, unless they are timeout errors which are ignored. https://github.com/user-attachments/assets/382ce565-3b4b-47a3-a081-d79c15aa462f
- Loading branch information
1 parent
254397c
commit babee9a
Showing
7 changed files
with
291 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
76 changes: 76 additions & 0 deletions
76
..._visualizer/public/application/file_data_visualizer/components/import_view/auto_deploy.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import type { InferenceInferenceEndpointInfo } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; | ||
import type { HttpSetup } from '@kbn/core/public'; | ||
|
||
const POLL_INTERVAL = 5; // seconds | ||
|
||
export class AutoDeploy { | ||
private inferError: Error | null = null; | ||
constructor(private readonly http: HttpSetup, private readonly inferenceId: string) {} | ||
|
||
public async deploy() { | ||
this.inferError = null; | ||
if (await this.isDeployed()) { | ||
return; | ||
} | ||
|
||
this.infer().catch((e) => { | ||
// ignore timeout errors | ||
// The deployment may take a long time | ||
// we'll know when it's ready from polling the inference endpoints | ||
// looking for num_allocations | ||
const status = e.response?.status; | ||
if (status === 408 || status === 504 || status === 502) { | ||
return; | ||
} | ||
this.inferError = e; | ||
}); | ||
await this.pollIsDeployed(); | ||
} | ||
|
||
private async infer() { | ||
return this.http.fetch<InferenceInferenceEndpointInfo[]>( | ||
`/internal/data_visualizer/inference/${this.inferenceId}`, | ||
{ | ||
method: 'POST', | ||
version: '1', | ||
body: JSON.stringify({ input: '' }), | ||
} | ||
); | ||
} | ||
|
||
private async isDeployed() { | ||
const inferenceEndpoints = await this.http.fetch<InferenceInferenceEndpointInfo[]>( | ||
'/internal/data_visualizer/inference_endpoints', | ||
{ | ||
method: 'GET', | ||
version: '1', | ||
} | ||
); | ||
return inferenceEndpoints.some((endpoint) => { | ||
return ( | ||
endpoint.inference_id === this.inferenceId && endpoint.service_settings.num_allocations > 0 | ||
); | ||
}); | ||
} | ||
|
||
private async pollIsDeployed() { | ||
while (true) { | ||
if (this.inferError !== null) { | ||
throw this.inferError; | ||
} | ||
const isDeployed = await this.isDeployed(); | ||
if (isDeployed) { | ||
// break out of the loop once we have a successful deployment | ||
return; | ||
} | ||
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL * 1000)); | ||
} | ||
} | ||
} |
Oops, something went wrong.