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(targets): hold targets state in new service #247

Merged
merged 3 commits into from
Aug 26, 2021

Conversation

andrewazores
Copy link
Member

Fixes #246

Query /api/v1/targets at web-client startup to find initial list of known
targets state. This list is updated incrementally via notification channel
updates asynchronously, which the TargetSelect component receives via RxJS
Observable emissions to update the graphical state accordingly.

This removes the need for a GET /api/v1/targets on each in-app navigation
(when the TargetSelect component is re-rendered), increasing page
responsiveness and fluidity. Update handling and state logic is also decoupled
from presentational React component and moved into the TargetsService, making
the component smaller and easier to understand/more maintainable.

To test, open your browser's dev tools panel and go to the Network tab (or
simply watch Cryostat backend logs). Click between Recordings and Events or
any other in-app navigation between pages that contain the TargetSelect
component at the top. On the current upstream main branch, observe that the
browser/logs record a GET /api/v1/targets (or even two, actually) on each
in-app navigation. On this PR branch, perform the same test and observe that
only one GET is performed at the application startup. The + and trashcan
icons can be used to test the custom target creation/deletion, which should
now update the UI without performing any GET. podman kill/podman run
(if running the backend using smoketest.sh) can be used to trigger async
discovery FOUND/LOST events as well, which should also cause the UI to
update without a GET query. Clicking the refresh circular-arrow icon on
the TargetSelect should prompt a single GET /api/v1/targets query. Enabling
view auto-refresh (gear icon on top nav bar) should cause singular GETs to
occur at the specified refresh interval.

Query /api/v1/targets at web-client startup to find initial list of
known targets state. This list is updated incrementally via notification
channel updates asynchronously, which the TargetSelect component
receives via RxJS Observable emissions to update the graphical state
accordingly.

This removes the need for a GET /api/v1/targets on each in-app
navigation (when the TargetSelect component is re-rendered), increasing
page responsiveness and fluidity.
@jan-law
Copy link
Contributor

jan-law commented Aug 25, 2021

How do I start the web client on your branch?

The web client's API requests fail, eg http://localhost:8181/health returns 'failed to load response data`. I tried the following in this order:

~/cryostat (main)> git pull upstream main
~/cryostat (main)> mvn clean package && CRYOSTAT_CORS_ORIGIN=http://localhost:9000 sh run.sh

(new terminal tab)
~/cryostat-web (api-query-service) [1]> npm run start:dev

@andrewazores
Copy link
Member Author

You'll need to disable SSL as well.
I do:

CRYOSTAT_CORS_ORIGIN=http://localhost:9000 CRYOSTAT_DISABLE_SSL=true CRYOSTAT_DISABLE_JMX_AUTH=true sh smoketest.sh

to start the backend, and

yarn yarn:frzinstall && yarn start:dev

to start the web-client frontend.

@jan-law
Copy link
Contributor

jan-law commented Aug 25, 2021

Checking my understanding here - TargetsService subscribes to all "target found" and "target lost" web socket notifications and updates the list _targets$ whenever it receives a new notification. Then TargetSelect reads the list of targets from TargetsService and updates the graphics when it notices a change?

@andrewazores
Copy link
Member Author

Checking my understanding here - TargetsService subscribes to all "target found" and "target lost" web socket notifications and updates the list _targets$ whenever it receives a new notification. Then TargetSelect reads the list of targets from TargetsService and updates the graphics when it notices a change?

Pretty much.

TargetsService does a GET to get the initial /api/v1/targets list state and then uses WebSocket notifications from then on to update that state.

Meanwhile, the TargetSelect component is subscribed to the TargetsService.targets() Observable. Observables are conceptually similar to streams, and in this case it's an asynchronous and unbounded stream. So, the TargetSelect component receives an update from the Observable whenever the state changes, receiving the whole list of targets (not just the added/removed element). At any given time, it renders the TargetSelect component, which is that white card with the dropdown for selection targets, using that data provided to it by the service.

Copy link
Member

@ebaron ebaron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works as described. Very nice!

Copy link
Contributor

@jan-law jan-law left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@andrewazores andrewazores merged commit 99e7bf3 into cryostatio:main Aug 26, 2021
@andrewazores andrewazores deleted the api-query-service branch August 26, 2021 21:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

In-app navigation causes repeated GET /api/v1/targets queries
3 participants