This repository has been archived by the owner on Jan 8, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 327
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1604 from hashicorp/server/refactor-poll-queuer
internal/server: Refactor how server queues poll jobs
- Loading branch information
Showing
3 changed files
with
169 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package singleprocess | ||
|
||
import ( | ||
"fmt" | ||
"time" | ||
|
||
"github.com/hashicorp/go-hclog" | ||
"github.com/hashicorp/go-memdb" | ||
"google.golang.org/grpc/codes" | ||
"google.golang.org/grpc/status" | ||
|
||
pb "github.com/hashicorp/waypoint/internal/server/gen" | ||
"github.com/hashicorp/waypoint/internal/server/singleprocess/state" | ||
) | ||
|
||
// projectPoll accepts a state management interface which provides access | ||
// to a projects current state implementation. Functions like Peek and Complete | ||
// need access to this state interface for peeking at the next available project | ||
// as well as marking a projects poll as complete. | ||
type projectPoll struct { | ||
// state is the state management interface that provides functions for | ||
// safely mutating server state. | ||
state *state.State | ||
} | ||
|
||
// Peek returns the latest project to poll on | ||
// If there is an error in the ProjectPollPeek, it will return nil | ||
// to allow the outer caller loop to continue and try again | ||
func (pp *projectPoll) Peek( | ||
log hclog.Logger, | ||
ws memdb.WatchSet, | ||
) (interface{}, time.Time, error) { | ||
p, pollTime, err := pp.state.ProjectPollPeek(ws) | ||
if err != nil { | ||
return nil, time.Time{}, err // continue loop | ||
} | ||
|
||
if p != nil { | ||
log = log.With("project", p.Name) | ||
} | ||
|
||
return p, pollTime, nil | ||
} | ||
|
||
// PollJob will generate a job to queue a project on | ||
func (pp *projectPoll) PollJob( | ||
log hclog.Logger, | ||
project interface{}, | ||
) (*pb.QueueJobRequest, error) { | ||
p, ok := project.(*pb.Project) | ||
if !ok || p == nil { | ||
log.Error("could not generate poll job for project, incorrect type passed in") | ||
return nil, status.Error(codes.FailedPrecondition, "incorrect type passed into Project PollJob") | ||
} | ||
|
||
jobRequest := &pb.QueueJobRequest{ | ||
Job: &pb.Job{ | ||
// SingletonId so that we only have one poll operation at | ||
// any time queued per project. | ||
SingletonId: fmt.Sprintf("poll/%s", p.Name), | ||
|
||
Application: &pb.Ref_Application{ | ||
Project: p.Name, | ||
// No Application set since PollOp is project-oriented | ||
}, | ||
|
||
// Polling always happens on the default workspace even | ||
// though the PollOp is across every workspace. | ||
Workspace: &pb.Ref_Workspace{Workspace: "default"}, | ||
|
||
// Poll! | ||
Operation: &pb.Job_Poll{ | ||
Poll: &pb.Job_PollOp{}, | ||
}, | ||
|
||
// Any runner is fine for polling. | ||
TargetRunner: &pb.Ref_Runner{ | ||
Target: &pb.Ref_Runner_Any{ | ||
Any: &pb.Ref_RunnerAny{}, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
return jobRequest, nil | ||
} | ||
|
||
// Complete will mark the job that was queued as complete, if it | ||
// fails to do so, it will return false with the err to continue the loop | ||
func (pp *projectPoll) Complete( | ||
log hclog.Logger, | ||
project interface{}, | ||
) error { | ||
p, ok := project.(*pb.Project) | ||
if !ok || p == nil { | ||
log.Error("could not mark project poll as complete, incorrect type passed in") | ||
return status.Error(codes.FailedPrecondition, "incorrect type passed into Project Complete") | ||
} | ||
|
||
// Mark this as complete so the next poll gets rescheduled. | ||
if err := pp.state.ProjectPollComplete(p, time.Now()); err != nil { | ||
return err | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters