Skip to content

Instantly share code, notes, and snippets.

@hnakamur
Created March 9, 2018 03:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hnakamur/1b0e3c7fcd5e6b7050deab5380e77d0b to your computer and use it in GitHub Desktop.
Save hnakamur/1b0e3c7fcd5e6b7050deab5380e77d0b to your computer and use it in GitHub Desktop.
a go example for waiting file lock, based on github.com/lomik/go-carbon
package main
import (
"flag"
"fmt"
"log"
"os"
"syscall"
"time"
)
var pid = os.Getpid()
func main() {
lockFilename := flag.String("lock", "my.lock", "lock file path")
flag.Parse()
log.SetFlags(log.LstdFlags | log.Lmicroseconds)
err := run(*lockFilename)
if err != nil {
log.Fatalf("got error in run, pid=%d, err=%v", pid, err)
}
}
func run(lockFilename string) error {
file, err := openWithLock(lockFilename)
if err != nil {
if !os.IsNotExist(err) {
return fmt.Errorf("failed to open lock file=%s, err=%v", lockFilename, err)
}
file, err = createWithLock(lockFilename)
if err != nil {
return fmt.Errorf("failed to create lock file=%s, err=%v", lockFilename, err)
}
}
defer func() {
log.Printf("flock-example closing file=%s, now take some sleep, pid=%d", lockFilename, pid)
file.Close()
}()
err = writeSomeLog(file)
if err != nil {
return fmt.Errorf("failed to write to lock file=%s, err=%v", lockFilename, err)
}
return nil
}
func openWithLock(lockFilename string) (*os.File, error) {
log.Printf("flock-example try opening file=%s, pid=%d", lockFilename, pid)
file, err := os.OpenFile(lockFilename, os.O_RDWR|os.O_APPEND, 0666)
if err != nil {
return nil, err
}
log.Printf("flock-example try locking opened file=%s, pid=%d", lockFilename, pid)
err = syscall.Flock(int(file.Fd()), syscall.LOCK_EX)
if err != nil {
return nil, err
}
log.Printf("flock-example got lock for opened file=%s, pid=%d", lockFilename, pid)
return file, nil
}
func createWithLock(lockFilename string) (*os.File, error) {
log.Printf("flock-example check file exists before creating file=%s, pid=%d", lockFilename, pid)
_, err := os.Stat(lockFilename)
if err == nil {
return nil, os.ErrExist
}
log.Printf("flock-example try creating file=%s, pid=%d", lockFilename, pid)
file, err := os.Create(lockFilename)
if err != nil {
return nil, err
}
log.Printf("flock-example try locking created file=%s, pid=%d", lockFilename, pid)
err = syscall.Flock(int(file.Fd()), syscall.LOCK_EX)
if err != nil {
return nil, err
}
log.Printf("flock-example got lock for created file=%s, pid=%d", lockFilename, pid)
return file, nil
}
func writeSomeLog(file *os.File) error {
// Emulate some work.
time.Sleep(5 * time.Second)
_, err := fmt.Fprintf(file, "%s write some log from pid=%d\n", time.Now().Format(time.RFC3339Nano), pid)
return err
}
@hnakamur
Copy link
Author

hnakamur commented Mar 9, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment