Skip to content

Commit

Permalink
♻️ mod(lock): file locked with concurrent
Browse files Browse the repository at this point in the history
  • Loading branch information
daijinru committed Jan 10, 2024
1 parent d5bc66f commit 209498f
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 104 deletions.
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,8 @@ require (
github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31
gopkg.in/yaml.v3 v3.0.1
)

require (
github.com/gofrs/flock v0.8.1 // indirect
golang.org/x/sys v0.16.0 // indirect
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
github.com/daijinru/mango-packages-command v0.0.1 h1:4YXYUHwyZLK93+AfycLnTwmzR85TglpsHptq1VEr2pU=
github.com/daijinru/mango-packages-command v0.0.1/go.mod h1:CnVxN6XRNWmY1E67ZHj+vKPQ2C3ZEAp8uo7zqsemmQ4=
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31 h1:OXcKh35JaYsGMRzpvFkLv/MEyPuL49CThT1pZ8aSml4=
github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
12 changes: 2 additions & 10 deletions http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,29 +32,21 @@ func (CiS *CiService) CreatePipeline(w http.ResponseWriter, r *http.Request) {
return
}

running, err := runner.ReadStatus()
err = runner.Lock.Lock()
if err != nil {
runner.Logger.Warn(err.Error())
}
if running {
message := "🔒 ci is running, No further operations allowed until it ends"
runner.Logger.Warn(message)
http.Error(w, message, http.StatusLocked)
return
}

err = runner.Complete()
if err != nil {
runner.Logger.Warn(err.Error())
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

go func() {
err = runner.Create()
if err != nil {
runner.Logger.Warn(err.Error())
}
runner.Complete()
}()

reply := PipelineReply{
Expand Down
63 changes: 13 additions & 50 deletions runner/lock.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,80 +4,43 @@ import (
"fmt"
"os"
"path/filepath"
"strconv"
"strings"

"github.com/daijinru/mango-runner/utils"
"github.com/gofrs/flock"
)

var (
PID_FILE_NAME = ".pid.lock"
)

type Lock struct {
Timestamp string
FilePath string
FileLock *flock.Flock
}

func NewLock(path string) *Lock {
return &Lock{
Timestamp: utils.TimeNow(),
FilePath: filepath.Join(path, "running.lock"),
}
}

type ReadLockContent struct {
PID string
Tag string
Timestamp string
}
func (lock *Lock) Read() (*ReadLockContent, error) {
bytes, err := os.ReadFile(lock.FilePath)
if err != nil {
return nil, err
}

lines := strings.Split(string(bytes), "\n")
if len(lines) < 2 {
return nil, fmt.Errorf("warning: os.Pid and pipline.Tag should be content of the running.lock")
}

return &ReadLockContent{
PID: lines[0],
Tag: lines[1],
Timestamp: lines[2],
}, nil
}

func (lock *Lock) Write(tag string) error {
file, err := os.Create(lock.FilePath)
if err != nil {
return err
}

defer file.Close()

pid := os.Getpid()
_, err = file.WriteString(strconv.Itoa(pid) + "\n")
func (lock *Lock) Lock() error {
_, err := os.OpenFile(lock.FilePath, os.O_CREATE, 0666)
if err != nil {
return err
}
_, err = file.WriteString(tag + "\n")
fileLock := flock.New(lock.FilePath)
locked, err := fileLock.TryLock()
if err != nil {
return err
return fmt.Errorf("failed to lock file: %v", lock.FilePath)
}
_, err = file.WriteString(lock.Timestamp)
if err != nil {
return err
if locked {
lock.FileLock = fileLock
} else {
return fmt.Errorf("file is already locked by another process")
}

return nil
}

func (lock *Lock) remove() error {
err := os.Remove(lock.FilePath)
if err != nil {
return err
}
func (lock *Lock) Unlock() error {
defer lock.FileLock.Unlock()
return nil
}
45 changes: 1 addition & 44 deletions runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ package runner

import (
"fmt"
"os"
"strconv"
"syscall"
"time"
)

Expand Down Expand Up @@ -62,33 +59,6 @@ func NewRunner(args *RunnerArgs) (*Runner, error) {

type RunnerContent struct {
Status bool

}
func (runner *Runner) ReadStatus() (bool, error) {
_, err := os.Stat(runner.Lock.FilePath)
if err != nil && os.IsNotExist(err) {
return false, nil
}

lock, err := runner.Lock.Read()
if err != nil {
return false, err
}

pid, err := strconv.Atoi(lock.PID)
if err != nil {
return false, err
}
process, err := os.FindProcess(pid)
if err != nil {
return false, err
}
err = process.Signal(syscall.Signal(0))
if err == nil {
return true, nil
}

return false, nil
}

func (runner *Runner) Create() error {
Expand All @@ -99,11 +69,6 @@ func (runner *Runner) Create() error {
return err
}

err = runner.Lock.Write(runner.Pipeline.Tag)
if err != nil {
return err
}

execution := &Execution{
PrintLine: true,
Pipeline: runner.Pipeline,
Expand Down Expand Up @@ -136,20 +101,12 @@ func (runner *Runner) Create() error {
if err != nil {
return err
}
err = runner.Complete()

if err != nil {
return err
}
return nil
}

func (runner *Runner) Complete() error {
_, err := os.Stat(runner.Lock.FilePath)
if err != nil && os.IsNotExist(err) {
return nil
}
err = runner.Lock.remove()
err := runner.Lock.Unlock()
if err != nil {
return err
}
Expand Down

0 comments on commit 209498f

Please sign in to comment.