-
Notifications
You must be signed in to change notification settings - Fork 20
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
feat(archives): Redesign "All Archives" view #431
feat(archives): Redesign "All Archives" view #431
Conversation
Adding a query for all archived recordings as you suggested and using it to populate both the uploaded and target-specific archived recordings tables solves the issue of authentication-related I'm also thinking of adding new notifications for when targets are added/deleted in order to keep the targets list up-to-date. |
Nice, that makes sense. I wonder if there is some better way to structure the implementation of that query so that it only opens the target connection when actually needed, ie querying active recordings.
Is this something different than https://github.com/cryostatio/cryostat/blob/ed9ff7e2d13da4d6c1d51a3325098e4169845295/src/main/java/io/cryostat/platform/internal/MergingPlatformClient.java#L70 ? |
I can look into this in a separate PR, for now the All Archives view can use the new query.
Ah, just a notification for target deletion then? |
Never mind, took a look at the frontend handling for |
TODO once I'm back from PTO:
|
The new Archives page: Thoughts? I only have tests left to write. Let me know what you think about my design approach with the implementation itself. |
Looks and feels good to use. I noticed a bug when I went to "Archives > Uploads". I uploaded an existing recording, but I also had an automated rule running in the background. My uploaded recording appears in the table, but so do newly archived recordings when notifications come in. Switching tabs to All Archives and back to Uploads does a full re-query and repopulation of the table, so the content goes back to being as expected - until the next archived recording notification comes in. I think you mentioned something about finding this bug already, but I took a quick look around and didn't see if it's already filed somewhere. The root cause seems to be that the notifications emitted when archives are created/deleted doesn't include information about which archive subdirectory the file was in (which target it originated from). If there is no issue for this bug already then please file one and it can be fixed separately. Also as an idea for a separate enhancement, it might be nice to give some indication to the user how many archives belong to each target in the Archives > All Targets table. For example adding some graphical element containing a count of recordings for that target. And perhaps if that count is 0 then the table row for that target is not expandable? |
Selecting each recording file and trying to individually delete it also doesn't result in the table updating. I get the success notification but the archived recording entry is still in the table and selected. |
I think the issue I filed should cover this case as well, even though the original bug I encountered had to do with
Good idea, I'll take a look into that.
This is another case of the issue I mentioned above. I had originally left this since you marked it as a "good first issue" for Max and Thuan, but if you like I could iron out all the issues we're having with archived recordings (both on the backend and frontend, as we discussed on IRC last week), after this PR. |
Makes sense. I'll leave it up to the three of you to decide - @maxcao13 @tthvo any interest in working with Hareet on this bug? |
Sure, I will take a look at it. |
@maxcao13 Sounds good, let me know if you have any questions. |
I'm a bit stumped on how best to approach keeping a count of the archived recordings per target in the Another way would be to add a new GraphQL query that returns a |
There are lots of good ideas in here, and I think I agree with the general high-level points overall. But, I think that for the purposes of this feature, the "least evil" is for each sub-table to perform its own query and update only when it's expanded, but also for the overall table to know how to perform essentially the same query but only use the aggregate data (counts). I think this is probably the ideal because it means that on first visit to the view, the main table only ever has to perform one query to populate all N of its rows. If the main table has to rely on the child tables to perform a query, compute the count, and send that data back to the parent, then we need to make N GraphQL queries when visiting this view just for the main table to fully populate. $ http :8181/api/v2.2/graphql?query="query { targetNodes { name recordings { archived { name } } } }"
HTTP/1.1 200 OK
content-encoding: gzip
content-length: 239
content-type: application/json
vary: origin
{
"data": {
"targetNodes": [
{
"name": "service:jmx:rmi:///jndi/rmi://cryostat:10000/jmxrmi",
"recordings": {
"archived": []
}
},
{
"name": "service:jmx:rmi:///jndi/rmi://cryostat:9091/jmxrmi",
"recordings": {
"archived": [
{
"name": "io-cryostat-Cryostat_self_20220610T200712Z.jfr"
}
]
}
},
{
"name": "service:jmx:rmi:///jndi/rmi://cryostat:9093/jmxrmi",
"recordings": {
"archived": [
{
"name": "es-andrewazor-demo-Main_auto_myrule_20220610T200817Z.jfr"
},
{
"name": "es-andrewazor-demo-Main_auto_myrule_20220610T200834Z.jfr"
}
]
}
},
{
"name": "service:jmx:rmi:///jndi/rmi://cryostat:9094/jmxrmi",
"recordings": {
"archived": [
{
"name": "es-andrewazor-demo-Main_auto_myrule_20220610T200817Z.jfr"
},
{
"name": "es-andrewazor-demo-Main_auto_myrule_20220610T200834Z.jfr"
}
]
}
},
{
"name": "service:jmx:rmi:///jndi/rmi://cryostat:9095/jmxrmi",
"recordings": {
"archived": [
{
"name": "es-andrewazor-demo-Main_auto_myrule_20220610T200817Z.jfr"
},
{
"name": "es-andrewazor-demo-Main_auto_myrule_20220610T200833Z.jfr"
}
]
}
},
{
"name": "service:jmx:rmi:///jndi/rmi://cryostat:9096/jmxrmi",
"recordings": {
"archived": []
}
}
]
}
} There's still plenty of room to improve this by using a filter on the My problem with this solution I'm presenting is that it means the client will be receiving a lot of data about archived recordings that it's just going to end up discarding - all we want is the number of recordings in each target archive, but we're getting a whole JSON object with at least the recording's name string in it. This could add up to a lot of wasted bandwidth if each target has a lot of archived recordings. To solve that, here's some reading with ideas: https://stackoverflow.com/questions/55940123/possible-to-count-result-list-elements-in-type-graphql This would suggest that, for example, we could modify our GraphQL Schema for the response type of that The query above could then hypothetically look like this instead: $ http :8181/api/v2.2/graphql?query="query { targetNodes { name recordings { archived { aggregate { count } } } } }"
HTTP/1.1 200 OK
content-encoding: gzip
content-length: 239
content-type: application/json
vary: origin
{
"data": {
"targetNodes": [
{
"name": "service:jmx:rmi:///jndi/rmi://cryostat:10000/jmxrmi",
"recordings": {
"archived": {
"aggregate": {
count: 0
}
}
}
},
{
"name": "service:jmx:rmi:///jndi/rmi://cryostat:9091/jmxrmi",
"recordings": {
"archived": {
"aggregate": {
count: 1
}
}
}
},
{
"name": "service:jmx:rmi:///jndi/rmi://cryostat:9093/jmxrmi",
"recordings": {
"archived": {
"aggregate": {
count: 2
}
}
}
},
{
"name": "service:jmx:rmi:///jndi/rmi://cryostat:9094/jmxrmi",
"recordings": {
"archived": {
"aggregate": {
count: 2
}
}
}
},
{
"name": "service:jmx:rmi:///jndi/rmi://cryostat:9095/jmxrmi",
"recordings": {
"archived": {
"aggregate": {
count: 2
}
}
}
},
{
"name": "service:jmx:rmi:///jndi/rmi://cryostat:9096/jmxrmi",
"recordings": {
"archived": {
"aggregate": {
count: 0
}
}
}
}
]
}
} I think updating the parent table in this way is fairly close to an ideal solution. This also means the child tables can continue using the same query and backend implementation as the parent table really - they just use a |
Awesome, appreciate the links/info. That aggregate count approach should work perfectly. Thanks! |
The counts are working now. I orginally tracked the list of targets and their corresponding recordings counts in a However, when I started adding unit tests I realized that when the count in the parent table is updated using a |
From a quick reading, I think this behaviour is coming from: This effect has a dependency on So when the notification comes in, the There might be a way around this by re-ordering your effects carefully, but it seems like that would end up fragile regardless. A little less performant but more robust would be to perform a deep comparison on the https://stackoverflow.com/questions/54095994/react-useeffect-comparing-objects This looks like an interesting route to explore. |
…nge to hide target rows that are excluded from the search using the isHidden flag.
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.
Wonderful work, thanks.
Fixes #400
Fixes #398