Documentation
Overview ¶
Package prjmanager implements public API for Project Manager.
The Project Manager keeps track of the project config, incomplete runs, and CLs in flight, and notifies runs when the project config changes.
Index ¶
- Constants
- Variables
- func NotifyCLUpdated(ctx context.Context, luciProject string, clid common.CLID, eversion int) error
- func NotifyCLsUpdated(ctx context.Context, luciProject string, cls []*changelist.CL) error
- func NotifyRunCreated(ctx context.Context, runID common.RunID) error
- func NotifyRunFinished(ctx context.Context, runID common.RunID) error
- func Poke(ctx context.Context, luciProject string) error
- func UpdateConfig(ctx context.Context, luciProject string) error
- type Project
- type ProjectStateOffload
- type RunBuilder
- type RunBuilderCL
Constants ¶
const ProjectKind = "Project"
ProjectKind is the Datastore entity kind for Project.
Variables ¶
var StateChangedTag = errors.BoolTag{Key: errors.NewTagKey("the task should be dropped")}
StateChangedTag is an error tag used to indicate that state read from Datastore differs from the expected state.
Functions ¶
func NotifyCLUpdated ¶
NotifyCLUpdated tells ProjectManager to check latest version of a given CL.
func NotifyCLsUpdated ¶
NotifyCLsUpdated is a batch of NotifyCLUpdated for the same ProjectManager.
In each given CL, .ID and .EVersion must be set.
func NotifyRunCreated ¶
NotifyRunCreated is sent by ProjectManager to itself within a Run creation transaction.
Unlike other event-sending funcs, this only creates an event and doesn't create a task. This is fine because:
* if Run creation transaction fails, then this event isn't actually created anyways. * if ProjectManager observes the Run creation success, then it'll act as if this event was received in the upcoming state transition. Yes, it won't process this event immediately, but at this point the event is a noop, so it'll be cleared out from the eventbox upon next invocation of ProjectManager. So there is no need to create a TQ task. * else, namely Run creation succeeds but ProjectManager sees it as a failure OR ProjectManager fails at any point before it can act on RunCreation, then the existing TQ task running ProjectManager will be retried. So once again there is no need to create a TQ task.
func NotifyRunFinished ¶
NotifyRunFinished tells ProjectManager that a run has finalized its state.
Types ¶
type Project ¶
type Project struct { // ID is LUCI project name. ID string `gae:"$id"` // EVersion is entity version. Every update should increment it by 1. EVersion int `gae:",noindex"` // UpdateTime is exact time of when this entity was last updated. // // It's not indexed to avoid hot areas in the index. UpdateTime time.Time `gae:",noindex"` // State serializes internal Project Manager state. // // The `LuciProject` field isn't set as it duplicates Project.ID. State *prjpb.PState // contains filtered or unexported fields }
Project is an entity per LUCI Project in Datastore.
func Load ¶
Load loads LUCI project state from Datastore.
If project doesn't exist in Datastore, returns nil, nil, nil.
func (*Project) ConfigHash ¶
ConfigHash returns Project's Config hash.
func (*Project) IncompleteRuns ¶
IncompleteRuns are IDs of Runs which aren't yet completed.
type ProjectStateOffload ¶
type ProjectStateOffload struct { // ID is alaways the same, set/read only by the datastore ORM. ID string `gae:"$id,const"` Project *datastore.Key `gae:"$parent"` // Status of project manager {STARTED, STOPPING, STOPPED (disabled)}. Status prjpb.Status `gae:",noindex"` // ConfigHash is the latest processed Project Config hash. ConfigHash string `gae:",noindex"` // contains filtered or unexported fields }
ProjectStateOffload stores rarely-changed project state duplicated from the main Project entity for use in transactions creating Runs.
Although this is already stored in the main Project entity, doing so would result in retries of Run creation transactions, since Project entity is frequently modified in busy projects.
On the other hand, ProjectStateOffload is highly likely to remain unchanged by the time Run creation transaction commits, thus avoiding needless retries.
type RunBuilder ¶
type RunBuilder struct { // LUCIProject. Required. LUCIProject string // ConfigGroupID for the Run. Required. // // TODO(tandrii): support triggering via API calls by validating Run creation // request against the latest config *before* transaction. ConfigGroupID config.ConfigGroupID // InputCLs will reference the newly created Run via their IncompleteRuns // field, and Run's RunCL entities will reference these InputCLs back. // Required. InputCLs []RunBuilderCL // Mode is the Run's mode. Required. Mode run.Mode // Owner is the Run Owner. Required. Owner identity.Identity // ExpectedIncompleteRunIDs are a sorted slice of Run IDs which may be associated with // CLs. // // If CLs.IncompleteRuns reference any other Run ID, the creation will be // aborted and error tagged with StateChangedTag. // // Nil by default, which doesn't permit any incomplete Run. ExpectedIncompleteRunIDs common.RunIDs // OperationID is an arbitrary string uniquely identifying this creation // attempt. // // TODO(tandrii): for CV API, record this ID in a separate entity index by // this ID for full idempotency of CV API. OperationID string // contains filtered or unexported fields }
RunBuilder creates a new Run.
If Expected<...> parameters differ from what's read from Datastore during transaction, the creation is aborted with error tagged with StateChangedTag. See RunBuilder.Create doc.
func (*RunBuilder) Create ¶
Create atomically creates a new Run.
Returns the newly created Run.
Returns 3 kinds of errors:
* tagged with transient.Tag, meaning it's reasonable to retry. Typically due to contention on simultaneously updated CL entity or transient Datastore Get/Put problem. * tagged with StateChangedTag. This means the desired Run might still be possible to create, but it must be re-validated against updated CLs or Project config version. * all other errors are non retryable and typically indicate a bug or severe misconfiguration. For example, lack of ProjectStateOffload entity.
type RunBuilderCL ¶
type RunBuilderCL struct { ID common.CLID ExpectedEVersion int TriggerInfo *run.Trigger Snapshot *changelist.Snapshot // Only needed for compat with CQDaemon. }
RunBuilderCL is a helper struct for per-CL input for run creation.
Directories
Path | Synopsis |
---|---|
Package copyonwrite providers helpers for modifying slices in Copy-on-Write way.
|
Package copyonwrite providers helpers for modifying slices in Copy-on-Write way. |
Package impl implements a ProjectManager.
|
Package impl implements a ProjectManager. |
state
Package state implements state machine of a Project Manager.
|
Package state implements state machine of a Project Manager. |
state/componentactor
Package componentactor acts on a specific component by implementing state.componentActor.
|
Package componentactor acts on a specific component by implementing state.componentActor. |
Package pmtest implements tests for working with Project Manager.
|
Package pmtest implements tests for working with Project Manager. |
package prjinternal stores protos for event processing of ProjectManager.
|
package prjinternal stores protos for event processing of ProjectManager. |