Skip to content
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

fix(recordings): Fix active recordings table refresh behavior for replace:"ALWAYS" #1535

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

Josh-Matsuoka
Copy link
Contributor

Fixes: #1286

This changes the activeRecordingsTable notification handling logic to call refreshRecordingsList when receiving creation/deletion notifications rather than updating with only the fields in the notification. This ensures that the state of the table remains accurate.

When the query in the linked issue is run a second time it results in the notifications being fired in the following order:

Recording Created
Recording Deleted

Pre-patch the table would see the recording deleted notification last and remove it from the table despite the recording still being present in the target. Calling refreshRecordingsList and getting the state of the target's recordings from the API shows the same.

How to manually test:

  1. Run Cryostat via smoketest or ./mvnw quarkus:dev
  2. Run the following query twice: (Replace 8080 with 8181 if in quarkus:dev mode)

http --follow -v --auth='user:pass' POST :8080/api/v4/graphql
Content-Type:application/json
query='
query {
targetNodes(filter: { annotations: ["PORT = 9091"] }) {
name
target {
doStartRecording(recording: {
name: "test9",
template: "Profiling",
templateType: "TARGET",
replace: "ALWAYS"
}) {
name
state
}
}
}
}'

@andrewazores
Copy link
Member

andrewazores commented Jan 17, 2025 via email

@Josh-Matsuoka
Copy link
Contributor Author

Looking at the server side we wait for deleteRecording to finish already before continuing to recreating the new one:

getActiveRecording(target, r -> r.name.equals(recordingName))
.ifPresent(r -> this.deleteRecording(r).await().atMost(connectionFailedTimeout));

but it looks like this hooks into the existing transaction via QuarkusTransaction.joiningExisting() so the PostRemove hook will be called after PostPersist if I'm understanding correctly? I'm not entirely clear on how Jakarta and quarkus are interacting here.

@andrewazores
Copy link
Member

andrewazores commented Jan 17, 2025 via email

@andrewazores
Copy link
Member

I think there is also another potential avenue for a fix that doesn't involve reordering transactions, so it should be simpler and less invasive to implement. Since 3.0, recordings have not only a name but also a unique database id field, as well as a remoteId field which mirrors the recording ID assigned by the target JVM instance. I think the WebSocket notifications already include the id field, but the web client handling for the notifications was all written long before that when recordings had no IDs and names were used as unique keys instead. I think updating the client's internal modelling of recordings to include the id, and then listening for and processing the notifications by using the ID to perform state updates instead of the name, should also fix the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug] Active Recordings table fails to update when restarting a recording with replace: ALWAYS
2 participants