mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-12-23 00:46:30 +00:00
Fix pipeline timestamps (#730)
* only calculate time on running builds * Add updated timestamp into database and use it in frontend * add more trace logging * refactor (move grpc unrelated func into related package) * fix xorm schema * add todo
This commit is contained in:
parent
6af94d79e3
commit
2a5159f7fe
5 changed files with 58 additions and 39 deletions
|
@ -321,6 +321,12 @@ func (s *RPC) Done(c context.Context, id string, state rpc.State) error {
|
|||
return err
|
||||
}
|
||||
|
||||
log.Trace().
|
||||
Str("repo_id", fmt.Sprint(repo.ID)).
|
||||
Str("build_id", fmt.Sprint(build.ID)).
|
||||
Str("proc_id", id).
|
||||
Msgf("gRPC Done with state: %#v", state)
|
||||
|
||||
if proc, err = shared.UpdateProcStatusToDone(s.store, *proc, state); err != nil {
|
||||
log.Error().Msgf("error: done: cannot update proc_id %d state: %s", proc.ID, err)
|
||||
}
|
||||
|
@ -341,8 +347,8 @@ func (s *RPC) Done(c context.Context, id string, state rpc.State) error {
|
|||
}
|
||||
s.completeChildrenIfParentCompleted(procs, proc)
|
||||
|
||||
if !isThereRunningStage(procs) {
|
||||
if build, err = shared.UpdateStatusToDone(s.store, *build, buildStatus(procs), proc.Stopped); err != nil {
|
||||
if !model.IsThereRunningStage(procs) {
|
||||
if build, err = shared.UpdateStatusToDone(s.store, *build, model.BuildStatus(procs), proc.Stopped); err != nil {
|
||||
log.Error().Err(err).Msgf("error: done: cannot update build_id %d final state", build.ID)
|
||||
}
|
||||
}
|
||||
|
@ -361,23 +367,13 @@ func (s *RPC) Done(c context.Context, id string, state rpc.State) error {
|
|||
s.buildCount.WithLabelValues(repo.FullName, build.Branch, string(build.Status), "total").Inc()
|
||||
s.buildTime.WithLabelValues(repo.FullName, build.Branch, string(build.Status), "total").Set(float64(build.Finished - build.Started))
|
||||
}
|
||||
if isMultiPipeline(procs) {
|
||||
if model.IsMultiPipeline(procs) {
|
||||
s.buildTime.WithLabelValues(repo.FullName, build.Branch, string(proc.State), proc.Name).Set(float64(proc.Stopped - proc.Started))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func isMultiPipeline(procs []*model.Proc) bool {
|
||||
countPPIDZero := 0
|
||||
for _, proc := range procs {
|
||||
if proc.PPID == 0 {
|
||||
countPPIDZero++
|
||||
}
|
||||
}
|
||||
return countPPIDZero > 1
|
||||
}
|
||||
|
||||
// Log implements the rpc.Log function
|
||||
func (s *RPC) Log(c context.Context, id string, line *rpc.Line) error {
|
||||
entry := new(logging.Entry)
|
||||
|
@ -398,31 +394,6 @@ func (s *RPC) completeChildrenIfParentCompleted(procs []*model.Proc, completedPr
|
|||
}
|
||||
}
|
||||
|
||||
func isThereRunningStage(procs []*model.Proc) bool {
|
||||
for _, p := range procs {
|
||||
if p.PPID == 0 {
|
||||
if p.Running() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func buildStatus(procs []*model.Proc) model.StatusValue {
|
||||
status := model.StatusSuccess
|
||||
|
||||
for _, p := range procs {
|
||||
if p.PPID == 0 {
|
||||
if p.Failing() {
|
||||
status = p.State
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status
|
||||
}
|
||||
|
||||
func (s *RPC) updateRemoteStatus(ctx context.Context, repo *model.Repo, build *model.Build, proc *model.Proc) {
|
||||
user, err := s.store.GetUser(repo.UserID)
|
||||
if err != nil {
|
||||
|
|
|
@ -28,6 +28,7 @@ type Build struct {
|
|||
Error string `json:"error" xorm:"build_error"`
|
||||
Enqueued int64 `json:"enqueued_at" xorm:"build_enqueued"`
|
||||
Created int64 `json:"created_at" xorm:"build_created"`
|
||||
Updated int64 `json:"updated_at" xorm:"updated NOT NULL DEFAULT 0 'updated'"`
|
||||
Started int64 `json:"started_at" xorm:"build_started"`
|
||||
Finished int64 `json:"finished_at" xorm:"build_finished"`
|
||||
Deploy string `json:"deploy_to" xorm:"build_deploy"`
|
||||
|
|
|
@ -68,6 +68,20 @@ func (p *Proc) IsParent() bool {
|
|||
return p.PPID == 0
|
||||
}
|
||||
|
||||
// IsMultiPipeline checks if proc list contain more than one parent proc
|
||||
func IsMultiPipeline(procs []*Proc) bool {
|
||||
c := 0
|
||||
for _, proc := range procs {
|
||||
if proc.IsParent() {
|
||||
c++
|
||||
}
|
||||
if c > 1 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Tree creates a process tree from a flat process list.
|
||||
func Tree(procs []*Proc) ([]*Proc, error) {
|
||||
var nodes []*Proc
|
||||
|
@ -93,6 +107,32 @@ func Tree(procs []*Proc) ([]*Proc, error) {
|
|||
return nodes, nil
|
||||
}
|
||||
|
||||
// BuildStatus determine build status based on corresponding proc list
|
||||
func BuildStatus(procs []*Proc) StatusValue {
|
||||
status := StatusSuccess
|
||||
|
||||
for _, p := range procs {
|
||||
if p.IsParent() && p.Failing() {
|
||||
status = p.State
|
||||
}
|
||||
}
|
||||
|
||||
return status
|
||||
}
|
||||
|
||||
// IsThereRunningStage determine if it contains procs running or pending to run
|
||||
// TODO: return false based on depends_on (https://github.com/woodpecker-ci/woodpecker/pull/730#discussion_r795681697)
|
||||
func IsThereRunningStage(procs []*Proc) bool {
|
||||
for _, p := range procs {
|
||||
if p.IsParent() {
|
||||
if p.Running() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func findNode(nodes []*Proc, pid int) (*Proc, error) {
|
||||
for _, node := range nodes {
|
||||
if node.PID == pid {
|
||||
|
|
|
@ -40,13 +40,17 @@ export default (build: Ref<Build | undefined>) => {
|
|||
}
|
||||
|
||||
const start = build.value.started_at || 0;
|
||||
const end = build.value.finished_at || 0;
|
||||
const end = build.value.finished_at || build.value.updated_at || 0;
|
||||
|
||||
if (start === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (end === 0) {
|
||||
// only calculate time on running builds
|
||||
if (build.value.status !== 'running') {
|
||||
return 0;
|
||||
}
|
||||
return Date.now() - start * 1000;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@ export type Build = {
|
|||
// When the build request was received.
|
||||
created_at: number;
|
||||
|
||||
// When the build was updated last time in database.
|
||||
updated_at: number;
|
||||
|
||||
// When the build was enqueued.
|
||||
enqueued_at: number;
|
||||
|
||||
|
|
Loading…
Reference in a new issue