• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

snowplow / sql-runner / 15063404311

16 May 2025 07:46AM UTC coverage: 27.73% (+1.0%) from 26.721%
15063404311

push

github

jbeemster
Prepared for release

353 of 1273 relevant lines covered (27.73%)

2.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.44
/sql_runner/lock_file.go
1
// Copyright (c) 2015-2025 Snowplow Analytics Ltd. All rights reserved.
2
//
3
// This program is licensed to you under the Apache License Version 2.0,
4
// and you may not use this file except in compliance with the Apache License Version 2.0.
5
// You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
6
//
7
// Unless required by applicable law or agreed to in writing,
8
// software distributed under the Apache License Version 2.0 is distributed on an
9
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
// See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
11
package main
12

13
import (
14
        "fmt"
15
        "log"
16
        "os"
17
        "path/filepath"
18
        "time"
19
)
20

21
// LockFile holds information for a lock file.
22
type LockFile struct {
23
        Path          string
24
        SoftLock      bool
25
        ConsulAddress string
26
        locked        bool
27
}
28

29
// InitLockFile creates a LockFile object
30
// which is used to ensures jobs can not run
31
// at the same time.
32
func InitLockFile(path string, softLock bool, consulAddress string) (LockFile, error) {
15✔
33
        lockFile := LockFile{
15✔
34
                Path:          path,
15✔
35
                SoftLock:      softLock,
15✔
36
                ConsulAddress: consulAddress,
15✔
37
                locked:        false,
15✔
38
        }
15✔
39

15✔
40
        if lockFile.LockExists() {
17✔
41
                return lockFile, fmt.Errorf("%s found on start, previous run failed or is ongoing. Cannot start", path)
2✔
42
        }
2✔
43
        return lockFile, nil
13✔
44
}
45

46
// Lock creates a new lock file or kv entry
47
func (lf *LockFile) Lock() error {
7✔
48
        if lf.locked == true {
9✔
49
                return fmt.Errorf("cannot Lock: LockFile is already locked")
2✔
50
        }
2✔
51

52
        value := time.Now().UTC().Format("2006-01-02T15:04:05-0700")
5✔
53

5✔
54
        log.Printf("Checking and setting the lockfile at this key '%s'", lf.Path)
5✔
55

5✔
56
        if lf.ConsulAddress == "" {
7✔
57
                // Check if dir exists
2✔
58
                dirStr := filepath.Dir(lf.Path)
2✔
59
                if _, err := os.Stat(dirStr); os.IsNotExist(err) {
3✔
60
                        return fmt.Errorf("directory for key does not exist")
1✔
61
                }
1✔
62

63
                // Create the file
64
                f, err := os.OpenFile(lf.Path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
1✔
65
                defer f.Close()
1✔
66
                if err != nil {
1✔
67
                        return err
×
68
                }
×
69

70
                // Write a line to it
71
                _, err = f.WriteString(value)
1✔
72
                if err != nil {
1✔
73
                        return err
×
74
                }
×
75

76
                lf.locked = true
1✔
77
                return nil
1✔
78
        }
79

80
        // Create the KV pair
81
        err := PutStringValueToConsul(lf.ConsulAddress, lf.Path, value)
3✔
82
        if err != nil {
5✔
83
                return err
2✔
84
        }
2✔
85

86
        lf.locked = true
1✔
87
        return nil
1✔
88
}
89

90
// Unlock deletes the lock or kv entry
91
func (lf *LockFile) Unlock() error {
6✔
92

6✔
93
        log.Printf("Deleting lockfile at this key '%s'", lf.Path)
6✔
94

6✔
95
        if lf.ConsulAddress == "" {
8✔
96
                // Delete the file
2✔
97
                err := os.Remove(lf.Path)
2✔
98
                if err != nil {
3✔
99
                        return err
1✔
100
                }
1✔
101

102
                lf.locked = false
1✔
103
                return nil
1✔
104
        }
105

106
        // Delete the KV pair
107
        err := DeleteValueFromConsul(lf.ConsulAddress, lf.Path)
4✔
108
        if err != nil {
6✔
109
                return err
2✔
110
        }
2✔
111

112
        lf.locked = false
2✔
113
        return nil
2✔
114
}
115

116
// LockExists checks if the lock file
117
// exists already
118
func (lf *LockFile) LockExists() bool {
36✔
119
        if lf.ConsulAddress == "" {
54✔
120
                if _, err := os.Stat(lf.Path); os.IsNotExist(err) {
33✔
121
                        return false
15✔
122
                }
15✔
123
                return true
3✔
124
        }
125

126
        value, err := GetStringValueFromConsul(lf.ConsulAddress, lf.Path)
18✔
127
        if err != nil && value == "" {
33✔
128
                return false
15✔
129
        }
15✔
130
        return true
3✔
131
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc