-
Notifications
You must be signed in to change notification settings - Fork 236
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
[YUNIKORN-2235] Add new RESTful API for retrieving application #750
Conversation
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.
See comments.
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## master #750 +/- ##
==========================================
- Coverage 77.94% 77.91% -0.03%
==========================================
Files 82 82
Lines 13373 13523 +150
==========================================
+ Hits 10424 10537 +113
- Misses 2622 2659 +37
Partials 327 327 ☔ View full report in Codecov by Sentry. |
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.
nice patch! a couple of comments left.
pkg/webservice/handlers.go
Outdated
@@ -60,6 +60,12 @@ const ( | |||
NodeDoesNotExists = "Node not found" | |||
) | |||
|
|||
var allowedAppStates = map[string]bool{ |
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.
Pardon me, why only partial states are allowed?
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 was discussed upstream w/ Wilfred. We don't want to return all kinds of states. A comment here would be useful.
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.
@laysfire could you share the discussion to me? Also, adding the comment here can helper readers in the future :)
@@ -56,3 +56,7 @@ type PlaceholderDAOInfo struct { | |||
Replaced int64 `json:"replaced,omitempty"` | |||
TimedOut int64 `json:"timedout,omitempty"` | |||
} | |||
|
|||
type ApplicationIDsDAOInfo struct { | |||
AppIDs []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.
Does it need json tag?
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.
For another, other responses name the id-related field "applicationId". Should we keep the consistency?
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.
yes, i will add json tag & keep consistency
@@ -425,6 +425,10 @@ func (pc *PartitionContext) removeAppInternal(appID string) *objects.Application | |||
return app | |||
} | |||
|
|||
func (pc *PartitionContext) GetApplication(appID string) *objects.Application { |
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.
this exposed method should get lock (pc.RLock()
/defer pc.RUnlock()
), and the internal method should be unlocked version.
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.
hi @chia7712 thanks for review.
The are so many places call the internal method.
Which way do you think is better?
First,
- Add RLock/RUnlock in exposed method & Remove RLock/RUnlock in internal method
- Add explicit RLock/RUnlock snippet in every place that call the internal method
Second,
Just change the exposed name
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.
Add RLock/RUnlock in exposed method & Remove RLock/RUnlock in internal method
yep
Add explicit RLock/RUnlock snippet in every place that call the internal method
How about just replacing internal method getApplication
by public version GetApplication
? Small change is good at avoiding new bugs :)
Also, you can file new Jira as follow-up to improve lock usage if you observe any weird use case.
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 might be a package internal method until this point. Lots of places calling it but they are all in the package. The partition is the place where the events from the shim get processed and the scheduling cycle runs from. That means we have multiple go routines that could be changing values stored in the partition. The locking makes sure we have no data races and a consistent view.
The internal method was locked for that reason and needs to stay like that.
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.
Some new comments.
pkg/webservice/handlers.go
Outdated
@@ -60,6 +60,12 @@ const ( | |||
NodeDoesNotExists = "Node not found" | |||
) | |||
|
|||
var allowedAppStates = map[string]bool{ |
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 was discussed upstream w/ Wilfred. We don't want to return all kinds of states. A comment here would be useful.
@laysfire I have shared my views in jira. Please check. |
e49ab1e
to
80417b4
Compare
@manirajv06 @chia7712 @pbacsko Address some comment, please help review this again. |
route{ | ||
"Scheduler", | ||
"GET", | ||
"/ws/v1/partition/:partition/applications/:state", |
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.
this endpoint is under discussion. https://issues.apache.org/jira/browse/YUNIKORN-2235
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.
Updated jira with more details. Please check.
Dropped in a large comment in the jira: |
684dd38
to
17c25b2
Compare
@manirajv06 @wilfred-s @chia7712 @pbacsko please help review again.
|
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.
Two questions.
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.
Almost. One more round.
pkg/webservice/handlers.go
Outdated
partition := vars.ByName(strings.ToLower("partition")) | ||
appState := vars.ByName(strings.ToLower("state")) |
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.
Partitions are case-sensitive, so drop that.
For appState
, the proper approach is:
appState := strings.ToLower(vars.ByName("state"))
@pbacsko Thanks for review. Have support case-insensitive for appState & activeState. But i add many strings.ToLower in code. I'm not sure if this is a good practice? |
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 agree that this change too much distracting stuff. Let's get rid of the ToLower()
calls and just use plain string literals. See my comments.
pkg/webservice/handlers.go
Outdated
allowedAppActiveStates[strings.ToLower(objects.New.String())] = true | ||
allowedAppActiveStates[strings.ToLower(objects.Accepted.String())] = true | ||
allowedAppActiveStates[strings.ToLower(objects.Starting.String())] = true | ||
allowedAppActiveStates[strings.ToLower(objects.Running.String())] = true | ||
allowedAppActiveStates[strings.ToLower(objects.Completing.String())] = true | ||
allowedAppActiveStates[strings.ToLower(objects.Failing.String())] = true | ||
allowedAppActiveStates[strings.ToLower(objects.Resuming.String())] = true |
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.
We might need a better naming here. It's a bit difficult to distingush between allowedAppStates
and allowedAppActiveStates
. At least some comments:
var allowedStatesMsg string // returned error message when the requested application state is invalid
var allowedActiveStatesMsg string // returned error message when the actual state of the application is not an active state like Running, Accepted, etc.
var allowedAppStates map[string]bool // ??? (this one is a bit tough to explain, we mix two existing states with a higher level one which)
var allowedAppActiveStates map[string]bool // list of application states that are valid for filtering
We can actually just drop allowedAppStates
because it only contains 3 values. Readability is important, so this is better:
if appState != "active" && appState != "rejected" && appState != "completed" {
buildJSONErrorResponse(w, "Only following application states are allowed: active, rejected, completed", http.StatusBadRequest)
return
}
You can also just drop the strings.ToLower()
calls, it makes the code a bit clumsy. Just write:
allowedAppActiveStates["new"] = true
allowedAppActiveStates["accepted"] = true
allowedAppActiveStates["starting"] = true
...
Obviously this is hard-coded and we no longer reference the code which define the states, but something for something. However, it's pretty unlikely that the state machine will ever change. You can add a comment to application_state.go
above the const
section:
// Application states are used for filtering in the webservice handlers. Please check&update the logic if needed if the state machine is modified
Sometimes we need to be pragmatic.
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.
+1 LGTM
I'll let others review it, too.
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.
@laysfire thanks for this nice feature. two small comments left. please take a look.
pkg/webservice/handlers.go
Outdated
return | ||
} | ||
if appState != "active" && appState != "rejected" && appState != "completed" { | ||
buildJSONErrorResponse(w, "Only following application states are allowed: active, rejected, completed", http.StatusBadRequest) |
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.
Could we move this line to line#683? for example:
case "active":
if status := strings.ToLower(r.URL.Query().Get("status")); status != "" {
if !allowedAppActiveStates[status] {
buildJSONErrorResponse(w, allowedActiveStatesMsg, http.StatusBadRequest)
return
}
for _, app := range partitionContext.GetApplications() {
if strings.ToLower(app.CurrentState()) == status {
appList = append(appList, app)
}
}
} else {
appList = partitionContext.GetApplications()
}
case "rejected":
appList = partitionContext.GetRejectedApplications()
case "completed":
appList = partitionContext.GetCompletedApplications()
default:
buildJSONErrorResponse(w, "Only following application states are allowed: active, rejected, completed", http.StatusBadRequest)
return
}
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.
Cool. Move #659 to "default" branch make code clearer and default branch would be possible to hit.
pkg/webservice/handlers.go
Outdated
case "active": | ||
if status := strings.ToLower(r.URL.Query().Get("status")); status != "" { | ||
if !allowedAppActiveStates[status] { | ||
buildJSONErrorResponse(w, allowedActiveStatesMsg, http.StatusBadRequest) |
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.
Should allowedActiveStatesMsg
be renamed to allowedActiveStatusMsg
if the query key is called "statue"?
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.
@laysfire sorry that I am overengineering today. one small comment left.
BTW, please file follow-up to doc the new APIs
pkg/webservice/handlers.go
Outdated
for k := range allowedAppActiveStates { | ||
activeStates = append(activeStates, k) | ||
} | ||
allowedActiveStatusMsg = fmt.Sprintf("Only following active states are allowed: %s", strings.Join(activeStates, ",")) |
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.
Could you change active states
to active statuses
? The query key is status
so I prefer naming consistency.
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.
@chia7712 Thanks for review. In order to keep consistency, should change allowedAppActiveStates to allowedAppActiveStatuses?
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.
yep!
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.
LGTM
What is this PR for?
This PR add 2 RESTful API.
One for retrieving one application object directly via /ws/v1/partition/{partitionName}/application/{applicationID}.
The other for listing application IDs via /ws/v1/partition/{partitionName}/applications/{state}.
What type of PR is it?
Todos
N/A
What is the Jira issue?
https://issues.apache.org/jira/browse/YUNIKORN-2235
How should this be tested?
It's been locally tested using go test
Screenshots (if appropriate)
N/A
Questions:
N/A