-1

I have a background task (cleanUp) that deletes outdated files.

func main() {
    // 4 procs/childs max
    runtime.GOMAXPROCS(4)

    // start a cleanup cron-job
    go cleanUp()

    app := fiber.New(fiber.Config{
        Prefork:   true,
    })
    app.Post("/", handleFileupload)
    log.Fatal(app.Listen(":4000"))
}

func cleanUp() {
    fmt.Println("Cleaning Up..")
    for {
        // deletes old files here
        time.Sleep(60 * time.Second)
    }
}

At the moment cleanUp runs on all 4 processes and prints Cleaning Up.. 4 times.

But I want it to run only on a single process and print a single Cleaning Up... I have tried waitGroups and channels but failed to achieve what I wanted.

How can I run it only on a single process to avoid race conditions?

Here is the output:

Cleaning Up..

 ┌───────────────────────────────────────────────────┐  ┌───────────────────────────────────────────────────┐
 │                   Fiber v2.38.1                   │  │ Child PIDs ... 79378, 79379, 79380, 79381         │
 │               http://127.0.0.1:4000               │  └───────────────────────────────────────────────────┘
 │       (bound on host 0.0.0.0 and port 4000)       │ 
 │                                                   │ 
 │ Handlers ............. 5  Processes ........... 4 │ 
 │ Prefork ........ Enabled  PID ............. 79377 │ 
 └───────────────────────────────────────────────────┘ 

Cleaning Up..
Cleaning Up..
Cleaning Up..
Cleaning Up..
Eziz Durdyyev
  • 1,110
  • 2
  • 16
  • 34
  • What "threads" are we talking about here? You start a single `cleanUp` goroutine, which runs _once_. Are you running the same process multiple times? – JimB Oct 24 '22 at 19:36
  • Threads that I created with `runtime.GOMAXPROCS(4)`. No, it runs 4 times. – Eziz Durdyyev Oct 24 '22 at 19:40
  • 1
    If it runs 4 times, it is because you are executing it 4 times. The example shown here, regardless of `GOMAXPROCS`, will execute the `cleanUp` function one time. Are you certain you are not executing this code in multiple _processes_? – JimB Oct 24 '22 at 19:42
  • I guess so. I just build and run the executable. – Eziz Durdyyev Oct 24 '22 at 19:50
  • 2
    It looks like the `fiber` package is abusing GOMAXPROCS as a value to start that number of processes, or there is some other config you are not showing here. A quick google also shows that they provide a [`fiber.IsChild`](https://docs.gofiber.io/api/fiber#ischild) function to detect which process you are in. – JimB Oct 24 '22 at 19:52
  • 1
    omg, sorry.. may be this has smth to do with: `Prefork: true` – Eziz Durdyyev Oct 24 '22 at 19:56

1 Answers1

2

Fiber spawns several processes to handle incoming requests. What you need is launch the cleanup routine in the master process and skip it in the child processes.

Fiber provides fiber.IsChild function:

    // start a cleanup cron-job
    if !fiber.IsChild() {
        go cleanUp()
    }

I slightly modified your example to print process ID in the handler and the cleanup goroutine:

func main() {
    // 4 procs/childs max
    runtime.GOMAXPROCS(4)

    // start a cleanup cron-job
    if !fiber.IsChild() {
        go cleanUp()
    }

    app := fiber.New(fiber.Config{
        Prefork: true,
    })
    app.Post("/", handleFileupload)
    log.Fatal(app.Listen(":4000"))
}

func cleanUp() {
    fmt.Println("Cleaning Up.. Pid:", syscall.Getpid())
    for {
        // deletes old files here
        time.Sleep(1 * time.Second)
        fmt.Println("Cleaning Up.. Pid:", syscall.Getpid())
    }
}

func handleFileupload(ctx *fiber.Ctx) error {
    println("Upload: pid ", syscall.Getpid())
    return nil
}

Result:

Cleaning Up.. Pid: 27035

 ┌───────────────────────────────────────────────────┐  ┌───────────────────────────────────────────────────┐
 │                   Fiber v2.39.0                   │  │ Child PIDs ... 27041, 27042, 27044, 27045         │
 │               http://127.0.0.1:4000               │  └───────────────────────────────────────────────────┘
 │       (bound on host 0.0.0.0 and port 4000)       │ 
 │                                                   │ 
 │ Handlers ............. 1  Processes ........... 4 │ 
 │ Prefork ........ Enabled  PID ............. 27035 │ 
 └───────────────────────────────────────────────────┘ 

Cleaning Up.. Pid: 27035
Cleaning Up.. Pid: 27035
Cleaning Up.. Pid: 27035
Cleaning Up.. Pid: 27035
Cleaning Up.. Pid: 27035
Cleaning Up.. Pid: 27035
Cleaning Up.. Pid: 27035

As you see, cleanup runs in the master process only.

Pak Uula
  • 2,750
  • 1
  • 8
  • 13