Use shared func for registering Sigterm on a context (#799)

This commit is contained in:
6543 2022-02-28 09:27:31 +01:00 committed by GitHub
parent a2315fe931
commit a3ac393264
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 50 additions and 73 deletions

View file

@ -23,8 +23,8 @@ import (
"github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/compiler" "github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/compiler"
"github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/linter" "github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/linter"
"github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/matrix" "github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/matrix"
"github.com/woodpecker-ci/woodpecker/pipeline/interrupt"
"github.com/woodpecker-ci/woodpecker/pipeline/multipart" "github.com/woodpecker-ci/woodpecker/pipeline/multipart"
"github.com/woodpecker-ci/woodpecker/shared/utils"
) )
// Command exports the exec command. // Command exports the exec command.
@ -192,7 +192,9 @@ func execWithAxis(c *cli.Context, file, repoPath string, axis matrix.Axis) error
ctx, cancel := context.WithTimeout(context.Background(), c.Duration("timeout")) ctx, cancel := context.WithTimeout(context.Background(), c.Duration("timeout"))
defer cancel() defer cancel()
ctx = interrupt.WithContext(ctx) ctx = utils.WithContextSigtermCallback(ctx, func() {
println("ctrl+c received, terminating process")
})
return pipeline.New(compiled, return pipeline.New(compiled,
pipeline.WithContext(ctx), pipeline.WithContext(ctx),

View file

@ -35,6 +35,7 @@ import (
"github.com/woodpecker-ci/woodpecker/agent" "github.com/woodpecker-ci/woodpecker/agent"
"github.com/woodpecker-ci/woodpecker/pipeline/backend" "github.com/woodpecker-ci/woodpecker/pipeline/backend"
"github.com/woodpecker-ci/woodpecker/pipeline/rpc" "github.com/woodpecker-ci/woodpecker/pipeline/rpc"
"github.com/woodpecker-ci/woodpecker/shared/utils"
) )
func loop(c *cli.Context) error { func loop(c *cli.Context) error {
@ -119,7 +120,7 @@ func loop(c *cli.Context) error {
context.Background(), context.Background(),
metadata.Pairs("hostname", hostname), metadata.Pairs("hostname", hostname),
) )
ctx = WithContextFunc(ctx, func() { ctx = utils.WithContextSigtermCallback(ctx, func() {
println("ctrl+c received, terminating process") println("ctrl+c received, terminating process")
sigterm.Set() sigterm.Set()
}) })

View file

@ -1,34 +0,0 @@
// Copyright 2017 Drone.IO Inc.
//
// This file is licensed under the terms of the MIT license.
// For a copy, see https://opensource.org/licenses/MIT.
package main
import (
"context"
"os"
"os/signal"
"syscall"
)
// WithContextFunc returns a copy of parent context that is canceled when
// an os interrupt signal is received. The callback function f is invoked
// before cancellation.
func WithContextFunc(ctx context.Context, f func()) context.Context {
ctx, cancel := context.WithCancel(ctx)
go func() {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
defer signal.Stop(c)
select {
case <-ctx.Done():
case <-c:
f()
cancel()
}
}()
return ctx
}

View file

@ -1,36 +0,0 @@
package interrupt
import (
"context"
"os"
"os/signal"
)
// WithContext returns a copy of parent context whose Done channel is closed
// when an os interrupt signal is received.
func WithContext(ctx context.Context) context.Context {
return WithContextFunc(ctx, func() {
println("ctrl+c received, terminating process")
})
}
// WithContextFunc returns a copy of parent context that is canceled when
// an os interrupt signal is received. The callback function f is invoked
// before cancellation.
func WithContextFunc(ctx context.Context, f func()) context.Context {
ctx, cancel := context.WithCancel(ctx)
go func() {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
defer signal.Stop(c)
select {
case <-ctx.Done():
case <-c:
f()
cancel()
}
}()
return ctx
}

44
shared/utils/context.go Normal file
View file

@ -0,0 +1,44 @@
// Copyright 2022 Woodpecker Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package utils
import (
"context"
"os"
"os/signal"
"syscall"
)
// Returns a copy of parent context that is canceled when
// an os interrupt signal is received.
func WithContextSigtermCallback(ctx context.Context, f func()) context.Context {
ctx, cancel := context.WithCancel(ctx)
go func() {
recivedSignal := make(chan os.Signal, 1)
signal.Notify(recivedSignal, syscall.SIGINT, syscall.SIGTERM)
defer signal.Stop(recivedSignal)
select {
case <-ctx.Done():
case <-recivedSignal:
cancel()
if f != nil {
f()
}
}
}()
return ctx
}