-
Notifications
You must be signed in to change notification settings - Fork 181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prefill URI connections and fix prefill deploy model form from version #3590
base: main
Are you sure you want to change the base?
Prefill URI connections and fix prefill deploy model form from version #3590
Conversation
9015414
to
2516700
Compare
6e27303
to
754e35f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple things I noted from our meeting @manaswinidas @alexcreasy and some resulting thoughts.
if (uri.startsWith('https:')) { | ||
return { s3Fields: null, uri }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
URI should be the catch-all case since it could use any protocol (such as the upcoming oci://
). We should flip this logic and have all the S3-specific logic here only happen if the URI starts with s3:
, else return this URI version.
Initially I was going to say we should try to keep this function entirely only related to S3 and only call it in the S3 case (so as not to propagate this "URI-split-to-separate-fields" logic that @andrewballantyne has stated we should avoid propagating), but that would lead to needing a isS3URI()
check that we call pretty much everywhere we use a URI in order to determine if we need this function. I think it maybe makes sense to keep this pattern where we pass around this object of "URI and anything we need to know from parsing it", even if in the future we're only adding isOCI
to that or something.
I do think however that we should factor out the { s3Fields: ObjectStorageFields | null; uri: string | null }
into a separate type since we repeat it. Is there ever a place anymore where we use ObjectStorageFields
separate from this whole object? Maybe instead we can have a StorageFields
type and the s3Fields
can be nested in it. In fact, instead of StorageFields
can we maybe call it RegisteredModelLocation
? It's essentially an object representation of the location of a registered model (well, the location of an artifact of one of its versions, but RegisteredModelVersionLocation
is getting long - and I do think we should maybe have "Registered" in the name if we're going to pass it around in model serving code, to distinguish it from how model locations are stored in connections there).
Please feel free to ignore everything here except the first paragraph if it becomes too much trouble for this PR.
@@ -91,6 +93,7 @@ export type InferenceServiceStorage = { | |||
type: InferenceServiceStorageType; | |||
path: string; | |||
dataConnection: string; | |||
connectionType?: ModelLocationType | string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed on the call with @alexcreasy - If possible, we probably want to avoid adding model-registry-specific properties to these model serving types. isRecommended
/ LabeledConnection
is sort of an exception because it's a generic feature we added to model serving - anything can make a connection recommended.
I know this complicates things though - I want to think through it a little but we could decide to just address it outside this PR. If we do, let's put a comment here and anywhere this is used saying it's temporary.
frontend/src/pages/modelServing/screens/projects/kServeModal/ManageKServeModal.tsx
Outdated
Show resolved
Hide resolved
React.useEffect(() => { | ||
const locationType = data.storage.connectionType; | ||
if (locationType) { | ||
if (locationType === 's3') { | ||
setSelectedConnectionType( | ||
withRequiredFields( | ||
connectionTypes.find((t) => getResourceNameFromK8sResource(t) === locationType), | ||
S3ConnectionTypeKeys, | ||
), | ||
); | ||
setConnectionValues(getMRConnectionValues(data.storage.awsData)); | ||
} | ||
if (data.storage.uri) { | ||
setSelectedConnectionType( | ||
withRequiredFields( | ||
connectionTypes.find( | ||
(t) => getResourceNameFromK8sResource(t) === data.storage.connectionType, | ||
), | ||
['URI'], | ||
), | ||
); | ||
setConnectionValues(getMRConnectionValues(data.storage.uri)); | ||
} | ||
} | ||
}, [data.storage.connectionType, connectionTypes, data.storage.uri, data.storage.awsData]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, so recapping part of our discussion with @alexcreasy - this useEffect exists to update state in response to a user action, which should ideally not be done in a useEffect (it should be part of whatever callback was triggered by the user action) to avoid unintended state updates. Let me try to think out loud about what we could maybe do:
In our case, we.... already broke that rule with usePrefillDeployModalFromModelRegistry
.... for.... reasons. (short version: we'd otherwise have to lift all the form state out of the whole ManageInferenceServiceModal so we could change its defaults for our MR-specific rendering of it... which was untenable due to the already-existing mess of useEffects we didn't want to touch). But if possible we should keep our useEffect crimes encapsulated in that one existing hook.
So, what's stopping us from doing that? There's no way to call setSelectedConnectionType
and setConnectionValues
from outside this ConnectionSection
. The traditional way to address that would be to "lift the state up" - take the useState
s for these and bring them up into ManageInferenceServiceModal
. That's.... not really practical here because we'd also have to lift all the other enabledConnectionTypes
logic from NewConnectionField, etc.
So what's another way we could address this? Well, we could introduce props/logic that is not specific to model registry that allow any consumer to optionally pre-fill default values for selectedConnectionType
and connectionValues
. If NewConnectionField
had props initialConnectionTypeName
and initialConnectionValues
, those could be conditionally used within the React.useState()
call for setting the initial state values there (using the connection type name as the prop because this is where connection types are fetched and we can look up the matching object here). Then we could drill those new props down: ConnectionSection
could have props like initialNewConnectionTypeName
and initialNewConnectionValues
(naming gets weird here maybe), and then those could be passed in where we render ConnectionSection
in ManageInferenceServiceModal
. Now we're back to where we have centralized MR-specific logic - we could have usePrefillDeployModalFromModelRegistry
conditionally return these initialNewConnectionType
and initialNewConnectionValues
if you are prefilling from MR.
That's just one idea -- and if that causes too much trouble to resolve in this PR we can come back to it. But I do think we should make sure to not leave this tech debt for long.
@yih-wang Can you check the above screenshots/screen recordings? My doubts:
![]() |
frontend/src/pages/modelRegistry/screens/RegisterModel/utils.ts
Outdated
Show resolved
Hide resolved
frontend/src/pages/modelRegistry/screens/RegisterModel/utils.ts
Outdated
Show resolved
Hide resolved
@manaswinidas So regarding the URI case, I don't think we should add the IMO it should behave exactly the same way with S3 connection, i.e.
The alert position looks good to me. |
Overall the videos look really good, thank you @manaswinidas! Got a few nitpicks on some minor details:
|
const [connections, connectionsLoaded, connectionsLoadError] = | ||
usePrefillDeployModalFromModelRegistry( | ||
projectContext, | ||
createDataInferenceService, | ||
setCreateDataInferenceService, | ||
registeredModelDeployInfo, | ||
); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just an observation, but this seems confusing because traditionally connections
would be of type Connection
or an array of it. But having it a LabeledConnection
seems confusing.
I don't know if there is a better solution though to add extra properties like this though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I followed what was done in #3074
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be worth opening a tech debt issue to see if we want to refactor to a different approach, but yeah the LabeledConnection
was the existing approach that was lost when connection types were introduced. An alternative could be to maybe return a separate list of recommendedConnections
, and when we render the connections dropdown check each to see if it's present in there to mark it recommended. But I'm not sure that's much better.
@yih-wang Changed the ![]() ![]() |
I'll defer to @kaedward 's opinion, but omitting that Incidentally though, I think we may want to correct the grammar there - |
@manaswinidas thank you for outlining the test cases and including the videos. That helps a lot to understand the complex changes. |
@mturley hmmm, so... I checked the content handoff doc and found there're several microcopies (in colorful rows) we forgot to refresh (possibly because the deployment pages are not available yet when the content is refreshing). I'm fine with not updating any content before summit and opening a separate ticket for tracking these changes. I'll defer to you... |
@yih-wang I've updated the screen recording for point 3 and added a few other UX fixes to ensure uniformity. ![]() |
Co-authored by: ppadti <[email protected]>
c2ad16f
to
6c6a22d
Compare
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
oh no! agh, I wonder if this was me dropping the ball... we should probably open a ticket and not block summit, but it might be nice to try to get some of it done if we have time. I should have made sure these were covered in our "Post-MVP usability improvements" strat. |
Closes: RHOAIENG-16146
Closes: RHOAIENG-14136
Description
Prefilling URI connections from
Register model
page(the dropdown should only contain connections filtered according to type):Screen.Recording.2025-02-11.at.9.51.21.PM.mov
A few scenarios for prefilling connections:
Existing Connection
will be selected and prefilled with the matching connection and path. The connection selection field will only populate with the connection when there is only 1 recommended connection.(You can test this by deploying the version insidemd-test-s3
model on themdas
project - it has one matching connection and that should be pre-selected and you should seeRecommended
label beside it when you click on the dropdown to see more connections on the psi-08 cluster)Screen.Recording.2025-02-11.at.9.52.56.PM.mov
Existing Connection
will be selected, but not be pre-filled - you can click on the dropdown and see two connections withRecommended
labels.Existing connection
will be selected and prefilled with connection name. You should have only 1 matching URI connection to see this(You can test this by deploying the version insidetest-mr-md
model on themdas
project - it has one matching URI connection on the psi-08 cluster). If you have multiple matching(Recommended
) connections,Existing Connection
is selected with no prefilled connections(Refer to point 2 screenshot)Screen.Recording.2025-02-14.at.12.15.44.PM.mov
New Connection
pre-selected and prefilled with a few fields including bucket, region, endpoint and path.(Video 1)(You can test this by deploying the version insidemd-test-s3
model on themdas-new
project - it has no matching connections - you should see the prefilled connection type and s3/object storage fields with alert on the psi-08 cluster). Same goes for URI field. (Video 2)(You can test this by deploying the version insidetest-mr-md
model on themdas-new
project - it has no matching connections - you should see the prefilled connection type and URI field with alert on the psi-08 cluster)Video 1:
Screen.Recording.2025-02-12.at.12.33.29.AM.mov
Video 2:
Screen.Recording.2025-02-12.at.12.36.54.AM.mov
Unit tests and prefilling logic co-written with @ppadti
How Has This Been Tested?
Instructions added along with screen recordings in description.
Test Impact
Added unit tests and fixing existing and adding new Cypress tests
Request review criteria:
Self checklist (all need to be checked):
If you have UI changes:
After the PR is posted & before it merges:
main