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

feat(ui): Add drawer with more details for each workflow in Workflow List #3151

Merged
merged 35 commits into from Jun 4, 2020

Conversation

rbreeze
Copy link
Member

@rbreeze rbreeze commented Jun 3, 2020

Checklist:

  • Either (a) I've created an enhancement proposal and discussed it with the community, (b) this is a bug fix, or (c) this is a chore.
  • The title of the PR is (a) conventional, (b) states what changed, and (c) suffixes the related issues number. E.g. "fix(controller): Updates such and such. Fixes #1234".
  • I've signed the CLA.
  • I have written unit and/or e2e tests for my change. PRs without these are unlikely to be merged.
  • My builds are green. Try syncing with master if they are not.
  • My organization is added to USERS.md.

Screen Shot 2020-06-02 at 5 10 16 PM

@alexec
Copy link
Contributor

alexec commented Jun 3, 2020

be very selective in the amount of data you query yes? there maybe >2k workflow listed

@rbreeze
Copy link
Member Author

rbreeze commented Jun 3, 2020

@alexec Is the data I've added so far too much? I discussed this a bit with @simster7 and those were the fields he suggested but I can remove some if needed. I also believe the drawer doesn't get rendered until a user clicks the SHOW button

@simster7
Copy link
Member

simster7 commented Jun 3, 2020

be very selective in the amount of data you query yes? there maybe >2k workflow listed

I believe the data has already been transmitted to the UI at this point, it's simply being surfaced now. Also, it might be a bit hard to see but the drawer is only shown – and therefore only rendered by React – if a user decides to display it.

@simster7 simster7 self-assigned this Jun 3, 2020
@rbreeze
Copy link
Member Author

rbreeze commented Jun 3, 2020

I believe the data has already been transmitted to the UI at this point, it's simply being surfaced now.

Yeah, each workflow object is already there in its entirety, I'm just displaying more of its properties in the drawer.

alexec
alexec previously requested changes Jun 3, 2020
Copy link
Contributor

@alexec alexec left a comment

Choose a reason for hiding this comment

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

believe the data has already been transmitted to the UI at this point,

We should not be transmitting the data of EVERY workflow that is loaded into this page. Only top line items. Can I confirm that if you open the drawer, then you are only loading the workflow at that point?

@simster7
Copy link
Member

simster7 commented Jun 3, 2020

We should not be transmitting the data of EVERY workflow that is loaded into this page. Only top line items. Can I confirm that if you open the drawer, then you are only loading the workflow at that point?

Sorry, not sure I understand what your concern is here. Could you help clarify?

If you're concerned about sending more information over-the-wire, then this PR does not send any new information that was not previously sent before. As of right now, we send Workflow objects in their entirety to the endpoint used by the timeline page. This PR simply exposes more of the information that is already being sent. If you're proposing we strip Workflow objects sent through this endpoint down to only the necessary fields to display them, then that would be out of scope of this PR.

If you're concerned about the UI having performance issues when loading or displaying the information that it has received, then React renders the information intelligently and will only do so if the user clicks the "Show" button.

@alexec
Copy link
Contributor

alexec commented Jun 3, 2020

@simster7 I'm confused - the screen shot in the description is of the workflow list page - but you're talking about the timeline page - I don't know what page that is - the only thing it might be is the timeline tab fo the workflow page?

Can you confirm which page makes these changes?

@alexec
Copy link
Contributor

alexec commented Jun 3, 2020

Looking at the changes, this is the workflow list page. This page should not be listing all workflow details - only those relevant to the list. This is to reduce network I/O for long lists (1000+ workflows).

This should be achieved by line 26 in workflow-service.ts:

fields=metadata,items.metadata.name,items.metadata.namespace,items.status.phase,items.status.finishedAt,items.status.startedAt

If that is actually returning more information, then we have a bug that this PR has revealed. However, what I expect is happening is that events that come from /workflow-events contain complete workflows. If that is the case, this solution will probably not work for large numbers of workflows - as you won't get that data and so they'll - missing the data you're rendering - I don't know how the changes handle that - but it could crash the UI.

If I'm correct, then can you make sure you're only getting the specific minimal data you need for this? Even adding labels to WorkflowService.list might be a lot.

Or, maybe remove the drawer if that data is missing.

@rbreeze
Copy link
Member Author

rbreeze commented Jun 3, 2020

I'm having trouble understanding what you mean by events coming from /workflow-events; I can't find any reference to it in workflows-list.tsx, is there data being passed from workflow-events that I'm missing? Either way, it does seem that there is extra data coming from the api call at line 26 in workflow-service.ts that wasn't requested, namely in the status portion. However I believe that the labels are included in the metadata portion of the request though so it makes sense that they'd be there.

The way the changes handle missing data is by checking if each parameter exists in the workflow object, and if they don't it just doesn't render that portion - so I think in the case of missing data it would be ok.

In case this helps clarify anything, I've included a screenshot of a workflow object that's part of the workflows state in the WorkflowsList React component. This is what I used as a reference when constructing the drawer, and I didn't request any additional data from the API but rather only used what was there.

Screen Shot 2020-06-03 at 10 45 24 AM

@alexec
Copy link
Contributor

alexec commented Jun 3, 2020

You're correct, we're talking about the same page. I was using the term "timeline"

I guess it is call the timeline then!

I suggest lazy-loading the workflow using WorkflowService.get - that way you'll have all the data you need without any problems.

I do like the idea of casually inspecting workflow like this. I think people will find it really useful.

@rbreeze
Copy link
Member Author

rbreeze commented Jun 3, 2020

great, sounds good! I'll start working on that. Do you think the lazy loading requires its own PR or should I include it in this one?

@rbreeze
Copy link
Member Author

rbreeze commented Jun 3, 2020

Upon inspection of the data returned directly from that API call, I'm finding that the response directly from the server (inspected with the Network dev tools) is exactly as expected without the additional data. However, somewhere between the server's response and the returned value of the services.workflows.list call, the extra data is being added somehow.

I'm thinking there are two places this could happen:

  1. On line 27 of workflows-service.ts where the response is cast as a WorkflowList return requests.get(...).then(res => res.body as WorkflowList); This seems unlikely since res.body doesn't contain the data that's appearing, and at most this typecast would just assign null to the values that were missing.

  2. The subscription is somehow filling in the gaps. However, I'm not sure how this would occur either as before the subscription is unsubscribed before the API call and only resubscribed after the spot where the data is appearing (the console.log statement below).

In workflows-list.tsx:

if (this.subscription) {
    this.subscription.unsubscribe();
}
...
if (!this.state.initialized) {
    workflowList = services.info.getInfo().then(info => {
        ...
        this.setState({initialized: true, managedNamespace: !!info.managedNamespace});
        return services.workflows.list(newNamespace, selectedPhases, selectedLabels, pagination);
    });
} else {
    ...
    workflowList = services.workflows.list(newNamespace, selectedPhases, selectedLabels, pagination);
}

workflowList
.then(wfList => {
    console.log(wfList)
    ...
}).then(() => {
    this.subscription = services.workflows
        .watch({namespace: newNamespace, phases: selectedPhases, labels: selectedLabels})
        .map(workflowChange => {
             ...

@rbreeze
Copy link
Member Author

rbreeze commented Jun 3, 2020

This console.log statement in workflows-service.ts also has the extra data in it. Yet, inspecting the actual network transaction shows that the server response doesn't have the extra data.

return requests.get(`api/v1/workflows/${namespace}?${params.join('&')}`).then(res => {
    console.log(res.body)
    return res.body as WorkflowList
});

Server response, from network inspector tab (the response we expect / want):
Screen Shot 2020-06-03 at 1 16 26 PM

Output of console.log statement from above:
Screen Shot 2020-06-03 at 1 17 12 PM

There are no additional requests to that endpoint, and while I suspect that the websocket is probably the culprit, I can't figure out how it would be injecting more data so soon after the return of that API call.

Screen Shot 2020-06-03 at 1 19 23 PM

@simster7
Copy link
Member

simster7 commented Jun 3, 2020

great, sounds good! I'll start working on that. Do you think the lazy loading requires its own PR or should I include it in this one?

I would do the lazy loading in this PR.

You seem to have gotten a great start in debugging the Workflow object issue. Would you like to own it? If so, I'd recommend trying to fix it in a separate PR. Also, if you need help feel free to ping me

@rbreeze
Copy link
Member Author

rbreeze commented Jun 3, 2020

I can definitely debug the Workflow object issue, I'll open an issue and PR this afternoon. Thanks!

@rbreeze rbreeze requested a review from jessesuen as a code owner June 3, 2020 23:52
Copy link
Member

@simster7 simster7 left a comment

Choose a reason for hiding this comment

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

Looking good so far! First round of comments

Comment on lines 35 to 39
const params = this.queryParams(filter);
params.push(
`fields=result.object.metadata.name,result.object.metadata.namespace,result.object.status.finishedAt,result.object.status.startedAt,result.object.status.phase`
);
const url = `api/v1/workflow-events/${filter.namespace || ''}?${params.join('&')}`;
Copy link
Member

Choose a reason for hiding this comment

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

This seems to be fixing the workflow-events endpoint issue. Shouldn't this be done in #3165 instead?

return (
<div className='tag' key={`${wf.metadata.namespace}-${wf.metadata.name}-${condition.type}-${condition.status}`}>
<div className='key'>{condition.type}</div>
<div className='value'>{condition.status}</div>
Copy link
Member

Choose a reason for hiding this comment

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

With Conditions, the Message field is often more important than the status field. In fact, we only show the status field at all only if the message field is empty. Furthermore, these message fields can be quite long... take a look at this example
image

So I'm not sure the tag class that we use to display "labels" would work here. What do you think?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah I see. With context, I agree - when I first saw that example, I thought that the SpecWarning portion was not itself a condition, but a constant warning displayed for every workflow.

)}
</div>
);
}

private fetchWorkflow(): void {
Copy link
Member

Choose a reason for hiding this comment

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

Nice. I would call this fetchFullWorkflow to emphasize that we have now is only a partial Workflow.


interface WorkflowsRowProps {
workflow: models.Workflow;
onChange: (key: string) => void;
}
export class WorkflowsRow extends React.Component<WorkflowsRowProps, {hideLabels: boolean}> {

export class WorkflowsRow extends React.Component<WorkflowsRowProps, {hideDrawer: boolean; workflow: models.Workflow}> {
Copy link
Member

Choose a reason for hiding this comment

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

Can we make {hideDrawer: boolean; workflow: models.Workflow} a format type like we do with props?

interface WorkflowRowState {
...
}

onChange: (key: string) => void;
}

export class WorkflowDrawer extends React.Component<WorkflowDrawerProps, {}> {
Copy link
Member

Choose a reason for hiding this comment

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

I would change the ordering things are displayed here to be

  1. Message
  2. Conditions
  3. Resource Durations
  4. Labels

@@ -89,6 +89,7 @@ message WorkflowDeleteResponse {
message WatchWorkflowsRequest {
string namespace = 1;
k8s.io.apimachinery.pkg.apis.meta.v1.ListOptions listOptions = 2;
string fields = 3;
Copy link
Member

Choose a reason for hiding this comment

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

Likewise here. Shouldn't this be done in #3165 instead?

Copy link
Member Author

Choose a reason for hiding this comment

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

This was due to a gap in my understanding of git - my commits from the #3165 branch were added to this branch. I was trying to debug this enhancement with the changes I made in #3165 without considering that accordingly those changes would be added to this branch.

To resolve this, should I simply delete the lines in question and recommit?

Copy link
Member

Choose a reason for hiding this comment

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

No worries. Yes, I would simply delete these lines and make sure that they are reverted exactly to what they were before by making sure they didn't change with git diff master

Copy link
Member

@simster7 simster7 left a comment

Choose a reason for hiding this comment

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

Almost there, just one more comment

@@ -806,6 +806,7 @@ var xxx_messageInfo_WorkflowDeleteResponse proto.InternalMessageInfo
type WatchWorkflowsRequest struct {
Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"`
ListOptions *v1.ListOptions `protobuf:"bytes,2,opt,name=listOptions,proto3" json:"listOptions,omitempty"`
Fields string `protobuf:"bytes,3,opt,name=fields,proto3" json:"fields,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

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

Still need to get rid of changes in this file. Doing a git checkout master pkg/apiclient/workflow/workflow.pb.go should suffice

Copy link
Member

@simster7 simster7 left a comment

Choose a reason for hiding this comment

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

Excellent work!

@sonarcloud
Copy link

sonarcloud bot commented Jun 4, 2020

Kudos, SonarCloud Quality Gate passed!

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities (and Security Hotspot 0 Security Hotspots to review)
Code Smell A 0 Code Smells

No Coverage information No Coverage information
No Duplication information No Duplication information

@simster7 simster7 dismissed alexec’s stale review June 4, 2020 22:22

Concerns addressed by lazy-loading full Workflow infomration

@simster7 simster7 merged commit a130d48 into argoproj:master Jun 4, 2020
@rbreeze rbreeze deleted the info-drawer branch June 4, 2020 22:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants