-
Notifications
You must be signed in to change notification settings - Fork 84
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
Bug 1536629 - send job state and credentials from job #610
Bug 1536629 - send job state and credentials from job #610
Conversation
@eriknelson PR from conversation on IRC yesterday about subscribers setting state. |
Changes Unknown when pulling 98aa415 on maleck13:608-send-job-state-from-job into ** on openshift:master**. |
This pr is also part of the larger work being done for #475 |
pkg/broker/provision_job.go
Outdated
} | ||
|
||
// Provisioner defines a function that knows how to provision an apb | ||
type Provisioner func(si *apb.ServiceInstance) (string, *apb.ExtractedCredentials, error) |
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.
What are you thoughts on this being defined in the apb package?
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.
yeah no issue with that. The flow of dependencies seems to go from apb to broker.
pkg/broker/provision_job.go
Outdated
return &ProvisionJob{ | ||
serviceInstance: serviceInstance, | ||
provision: provision, |
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 like this approach
This looks really good to me, want to discuss the provisioner type being defined in the apb package. I like the way you have made it testable by making the |
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.
minor change
pkg/broker/provision_subscriber.go
Outdated
type ProvisionWorkSubscriber struct { | ||
dao *dao.Dao | ||
msgBuffer <-chan JobMsg | ||
dao SubcriberDAO |
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.
s/SubcriberDAO/SubscriberDAO/
@mhrivnak if you change your initial commit to say |
I'll review this and see what the impact is on my current outstanding async work. I'm currently knee deep in this area. |
98aa415
to
dd08f15
Compare
@shawn-hurley Will wait for @jmrodri review before changing the location of the provision type, in case there are further changes required. |
Changes Unknown when pulling dd08f15 on maleck13:608-send-job-state-from-job into ** on openshift:master**. |
@shawn-hurley thanks for the offer. I think though I will naturally end up creating the additional tests as part of the PR work as I want to be able to run them when iterating on the feature pr and a good bit of the work for the last operation feature is around the Jobs and subscribers. Funny enough almost all of my PRs are part of the feature :) its like building a feature in layers |
Partially-fixes #542 |
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.
Overall I like the approach. Some questions about why some things were changed. Also, the stuttering of State.State
is slightly annoying so I'd prefer we address that.
pkg/broker/deprovision_job.go
Outdated
@@ -43,42 +43,44 @@ func NewDeprovisionJob(serviceInstance *apb.ServiceInstance, | |||
// Run - will run the deprovision job. | |||
func (p *DeprovisionJob) Run(token string, msgBuffer chan<- JobMsg) { | |||
metrics.DeprovisionJobStarted() | |||
defer metrics.DeprovisionJobFinished() | |||
var jobMsg = JobMsg{ |
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.
any reason we do var jobMsg = ...
vs jobMsg :=
?
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.
Nothing specific, just a habit I have as it is accessed from several blocks within the function. Happy to change it
State: apb.JobState{ | ||
State: apb.StateInProgress, | ||
Method: apb.JobMethodDeprovision, | ||
Token: token, |
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.
something about this setup bothers me, but I don't see a cleaner way.
|
||
if p.skipApbExecution { | ||
log.Debug("skipping deprovision and sending complete msg to channel") | ||
msgBuffer <- JobMsg{InstanceUUID: p.serviceInstance.ID.String(), PodName: "", | ||
JobToken: token, SpecID: p.serviceInstance.Spec.ID, Error: ""} | ||
jobMsg.State.State = apb.StateSucceeded |
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'd rather see us add a SetState(JobState)
to the JobMsg
struct. I don't like the stuttering of State.State
. So it would look more like jobMsg.SetState(apb.StateSucceeded)
.
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.
Agree on stuttering struggled with it also, but not a big fan of using setters either though. I wondered if perhaps we could remove JobMsg entirely and just have JobState as their is some duplication between them?
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.
On a side note, I think we could simplify things by removing the subscribers and either have a set of observers registered for each job that act on JobState changes or simply give the Job access to the DAO to set the state itself.
Maybe better to discuss this outside of this PR though.
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 think it's worth a discussion @maleck13. I don't remember the issue where you first mentioned this idea, but it's worth bringing it up 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.
I will follow up with a clear separate issue to allow for that discussion
// an error type in a struct you want marshalled | ||
// https://github.com/golang/go/issues/5161 | ||
jobMsg.State.State = apb.StateFailed | ||
jobMsg.State.Error = errMsg |
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.
In addition to the SetState
I'd add a SetError
or SetErrorMsg
to the JobMsg
struct. That way it hides the implementation detail there there's a JobState hidden in there.
pkg/broker/deprovision_subscriber.go
Outdated
) | ||
setFailedDeprovisionJob(d.dao, msg) | ||
continue | ||
for msg := range msgBuffer { |
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.
any particular reason for change from the for {
to the for msg := range msgBuffer {
?
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.
2 reasons:
- When you close a channel and you use the for range method, the loop also closes, where as if you just use a for loop and receive from the channel, once the channel is closed you will continue to receive the default value for that channel. If you don't want that behaviour your code would need to check the second value on a channel receive:
msg,closed <- chan
if closed{
break
}
https://dave.cheney.net/2014/03/19/channel-axioms
- I am ok with checking if the channel is closed, but in my opinion it also reads a little better with the range statement.
pkg/broker/deprovision_subscriber.go
Outdated
continue | ||
for msg := range msgBuffer { | ||
log.Debug("received deprovision message from buffer") | ||
if msg.State.State == apb.StateSucceeded { |
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 would flip the check to look for the error conditions first and have escape valves, then do the success case afterwards without being in an if block.
func (d *DeprovisionWorkSubscriber) Subscribe(msgBuffer <-chan JobMsg) {
d.msgBuffer = msgBuffer
go func() {
log.Info("Listening for deprovision messages")
for msg := range msgBuffer {
log.Debug("received deprovision message from buffer")
if msg.State.State != apb.StateSucceeded {
if err := d.dao.SetState(msg.InstanceUUID, msg.State); err != nil {
log.Errorf("failed to set state after deprovision %v", err)
}
continue
}
instance, err := d.dao.GetServiceInstance(msg.InstanceUUID)
if err != nil {
log.Errorf(
"Error occurred getting service instance [ %s ] after deprovision job:",
msg.InstanceUUID,
)
setFailedDeprovisionJob(d.dao, msg)
continue
}
if err := cleanupDeprovision(instance, d.dao); err != nil {
log.Errorf("Failed cleaning up deprovision after job, error: %v", err)
// Cleanup is reporting something has gone wrong. Deprovision overall
// has not completed. Mark the job as failed.
setFailedDeprovisionJob(d.dao, msg)
continue
}
}
}()
}
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.
👍
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.
removed the if entirely as we always want the state to be set
}); err != nil { | ||
log.Errorf("failed to set state after deprovision %#v", err) | ||
// have to set the state here manually as the logic that triggers this is in the subscriber | ||
dmsg.State.State = apb.StateFailed |
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.
The stutter is definitely weird. If we don't want to add the method, then dmsg.JobState.State
might work.
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.
Yeah thought about doing that also, but see above comment on perhaps removing the JobMsg
and just having JobState.State
@@ -102,12 +77,12 @@ func cleanupDeprovision(instance *apb.ServiceInstance, dao *dao.Dao) error { | |||
id := instance.ID.String() | |||
|
|||
if err = dao.DeleteExtractedCredentials(id); err != nil { | |||
log.Error("failed to delete extracted credentials - %#v", err) | |||
log.Error("failed to delete extracted credentials - %v", err) |
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.
any reason you changed from %#v
to %v
? @shawn-hurley I think I've seen you use the %#v
variant, thoughts?
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.
There seemed to be different approaches to this across the code base with %v
seeming to be the most common. In my opinion, the %v is good for error messages as it will just print the error string, where as perhaps the %#v is good for debug statements as it prints the struct
&errors.errorString{s:"test error"}
see example https://play.golang.org/p/nkVaxztAG4_I
) | ||
|
||
// ProvisionWorkSubscriber - Lissten for provision messages | ||
// ProvisionWorkSubscriber - Listen for provision messages |
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.
👍 to fixing typos
Will rebase and bring the new Bind and Unbind jobs into line with these changes |
dd08f15
to
5229147
Compare
updated with refactored bind and unbind @jmrodri Any further thoughts based on the comments? I think the only outstanding things are the stutter, which I think could be resolved by removing the JobMsg and just sending through JobState (ie come up with a single type that suits the purposes). Maybe this could be a follow up issue and PR? |
Changes Unknown when pulling 5229147 on maleck13:608-send-job-state-from-job into ** on openshift:master**. |
5229147
to
658379f
Compare
Changes Unknown when pulling 658379f on maleck13:608-send-job-state-from-job into ** on openshift:master**. |
658379f
to
434f7ed
Compare
Changes Unknown when pulling 434f7ed on maleck13:608-send-job-state-from-job into ** on openshift:master**. |
Looks like we may need to add
|
I think this was an error on my part. My editor may have imported it accidentally. I have resolved that issue and rebased on master. Seems a ci job is timing out now
Craig
… On 18 Jan 2018, at 15:54, Ryan Hallisey ***@***.***> wrote:
Looks like we may need to add github.com/apex/log to glide. Travis turned up with this error:
pkg/broker/binding_job.go:24:2: cannot find package "github.com/apex/log" in any of:
/home/travis/gopath/src/github.com/openshift/ansible-service-broker/vendor/github.com/apex/log (vendor tree)
/home/travis/.gimme/versions/go1.8.5.linux.amd64/src/github.com/apex/log (from $GOROOT)
/home/travis/gopath/src/github.com/apex/log (from $GOPATH)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
|
Thanks Craig. I just restarted it. We'll see if it happens again. |
@maleck13 Sorry it's taken me a bit to review this. Trying to make my way through a review backlog. I'm guessing this still needs a rebase? |
434f7ed
to
fd5304a
Compare
rebased |
Changes Unknown when pulling fd5304a on maleck13:608-send-job-state-from-job into ** on openshift:master**. |
The CI build is failing, but it is not clear to me how best to find the issue. The log is quite large https://api.travis-ci.org/v3/job/330711368/log.txt |
It's failing on lint. The fix was merged an hour ago: #662 . Another rebase should fix it.
|
Apologies. I broke the build :) Will take a closer look at this today. |
I'll take another look at this one now that bind and unbind are in |
…tests. Address pr feedback on decided comments remove bad import. refactor job test to accept binding instance
fd5304a
to
fe0fd97
Compare
@rthallisey Thanks for pointer! have rebased again now |
My async bind scripts work fine with this deployed. I like the Binder interface func. |
Changes Unknown when pulling fe0fd97 on maleck13:608-send-job-state-from-job into ** on openshift:master**. |
Bug 1536629 - send job state and credentials from job fixes openshift#608
Note for Reviewer
There are two commits here
These commits are independent of each other so if the new tests are not wanted I can remove.
I am currently trying this out in my local cluster but wanted to create the PR to let the integration tests run.
Describe what this PR does and why we need it:
The subscribers were deciding on the state of the Job, rather than the job informing the subscriber of the job state. This pr follows on from issue #608
Also the Job was Marshalling the extracted credentials and sending them as a string on the Msg field, then the subscriber would Unmarshal it and save it. Instead of doing this we just send the credentials through
Changes proposed in this pull request
Which issue this PR fixes (This will close that issue when PR gets merged)
fixes #608