[Go] ์ผ์ • ์‹œ๊ฐ„๋งˆ๋‹ค ์Šค์ผ€์ค„๋Ÿฌ ๋™์ž‘ํ•˜๊ธฐ(Ticker)

2025. 11. 7. 18:22ยทํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด/Go

.

 


time.Ticker ๋˜๋Š” time.AfterFunc, time.Sleep ๋“ฑ์„ ์ด์šฉํ•ด ์ฃผ๊ธฐ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์•„๋ž˜์—์„œ๋Š” ์‹ค๋ฌด์—์„œ ์ž์ฃผ ์“ฐ์ด๋Š” n์ดˆ ๊ฐ„๊ฒฉ์œผ๋กœ ๋ฐ˜๋ณต ์‹คํ–‰๋˜๋Š” ์ž‘์—… ํ”„๋กœ์„ธ์Šค๋ฅผ ๋‹จ๊ณ„์ ์œผ๋กœ ์ •๋ฆฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์ธ time.Ticker ์‚ฌ์šฉ ์˜ˆ์‹œ

package main

import (
    "fmt"
    "time"
)

func main() {
    ticker := time.NewTicker(5 * time.Second) // 5์ดˆ๋งˆ๋‹ค ๋ฐ˜๋ณต
    defer ticker.Stop()

    for {
        select {
        case t := <-ticker.C:
            fmt.Println("์ž‘์—… ์‹คํ–‰ ์‹œ๊ฐ:", t.Format("15:04:05"))
            runTask()
        }
    }
}

func runTask() {
    // ์‹ค์ œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง
    fmt.Println("์‹คํ–‰ ์ค‘... (API ํ˜ธ์ถœ, DB ์—…๋ฐ์ดํŠธ ๋“ฑ)")
}

ํ•ต์‹ฌ ํฌ์ธํŠธ

  • time.NewTicker(d)๋Š” ์ผ์ • ์ฃผ๊ธฐ๋กœ ์ฑ„๋„์— ์ด๋ฒคํŠธ๋ฅผ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
  • for + select ๊ตฌ๋ฌธ์œผ๋กœ ์ฃผ๊ธฐ์  ์‹ ํ˜ธ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋ฉฐ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • defer ticker.Stop()์œผ๋กœ ์ข…๋ฃŒ ์‹œ ๋ฆฌ์†Œ์Šค ํ•ด์ œ.

 

๋ฐฑ๊ทธ๋ผ์šด๋“œ ๊ณ ๋ฃจํ‹ด์—์„œ ์‹คํ–‰ (์„œ๋ฒ„ ๋‚ด๋ถ€์šฉ)

package main

import (
    "fmt"
    "time"
)

func startScheduler(interval time.Duration, stopChan <-chan struct{}) {
    ticker := time.NewTicker(interval)
    defer ticker.Stop()

    for {
        select {
        case <-ticker.C:
            go func() {
                fmt.Println("๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—… ์‹œ์ž‘:", time.Now())
                runTask()
            }()
        case <-stopChan:
            fmt.Println("์Šค์ผ€์ค„๋Ÿฌ ์ข…๋ฃŒ ์š”์ฒญ")
            return
        }
    }
}

func runTask() {
    fmt.Println("์ž‘์—… ์ˆ˜ํ–‰ ์ค‘...")
    time.Sleep(2 * time.Second)
    fmt.Println("์ž‘์—… ์™„๋ฃŒ.")
}

func main() {
    stopChan := make(chan struct{})
    go startScheduler(10*time.Second, stopChan)

    // ์„œ๋ฒ„๊ฐ€ ๋Œ์•„๊ฐ€๋Š” ๋™์•ˆ ๊ณ„์† ์‹คํ–‰๋จ
    time.Sleep(35 * time.Second)
    close(stopChan)
}

ํŠน์ง•

  • ์Šค์ผ€์ค„ ์ž‘์—…์ด ๊ณ ๋ฃจํ‹ด์œผ๋กœ ๋น„๋™๊ธฐ ์‹คํ–‰๋˜์–ด, ๋‹ค์Œ ์ฃผ๊ธฐ์™€ ๊ฒน์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • stopChan์„ ํ†ตํ•ด graceful stop์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

 

3๋‹จ๊ณ„: ๊ณ ๊ธ‰ํ˜• (์ง€์—ฐ, ์˜ค๋ฅ˜ ๋ณต๊ตฌ ํฌํ•จ)

์‹ค๋ฌด์—์„œ๋Š” ์ž‘์—…์ด ์‹คํŒจํ–ˆ์„ ๋•Œ ์žฌ์‹œ๋„ ๋กœ์ง์„ ๋„ฃ๊ฑฐ๋‚˜, ์ž‘์—…์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋ฉด ๋‹ค์Œ ์ฃผ๊ธฐ๋ฅผ ์ง€์—ฐ์‹œํ‚ค๋Š” ๊ตฌ์กฐ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

func startSafeScheduler(interval time.Duration, stopChan <-chan struct{}) {
    ticker := time.NewTicker(interval)
    defer ticker.Stop()

    for {
        select {
        case <-ticker.C:
            func() {
                defer func() {
                    if r := recover(); r != nil {
                        fmt.Println("์ž‘์—… ์ค‘ panic ๋ฐœ์ƒ:", r)
                    }
                }()
                if err := runTask(); err != nil {
                    fmt.Println("์—๋Ÿฌ:", err)
                }
            }()
        case <-stopChan:
            fmt.Println("์Šค์ผ€์ค„๋Ÿฌ ์ข…๋ฃŒ")
            return
        }
    }
}

func runTask() error {
    fmt.Println("DB ์—…๋ฐ์ดํŠธ ๋˜๋Š” API ํ˜ธ์ถœ ์ค‘...")
    // ์—ฌ๊ธฐ์— ์‹ค์ œ ๋กœ์ง
    return nil
}

์ด ๋ฐฉ์‹์€:

  • panic ๋ฐœ์ƒ ์‹œ ๋ณต๊ตฌ ๊ฐ€๋Šฅ
  • ๋‹ค์Œ ์ฃผ๊ธฐ์™€ ๊ฒน์น˜์ง€ ์•Š์Œ
  • ์‹คํŒจํ•œ ์ž‘์—… ๋กœ๊ทธ ๋‚จ๊น€

 

๋Œ€์ฒด ๋ฐฉ์‹ – Cron ์Šคํƒ€์ผ (github.com/robfig/cron/v3)

๋” ๋ณต์žกํ•œ ์Šค์ผ€์ค„์ด ํ•„์š”ํ•  ๋•Œ๋Š” cron ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

import (
    "github.com/robfig/cron/v3"
)

func main() {
    c := cron.New()
    c.AddFunc("@every 10s", func() { runTask() })
    c.Start()

    select {} // ํ”„๋กœ๊ทธ๋žจ ์œ ์ง€
}

 

@every 10s, 0 0 * * * ๋“ฑ ๋‹ค์–‘ํ•œ ์Šค์ผ€์ค„ ํ‘œํ˜„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

 

์ €์ž‘์žํ‘œ์‹œ (์ƒˆ์ฐฝ์—ด๋ฆผ)

'ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด > Go' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Go] enum ์‚ฌ์šฉํ•˜๊ธฐ  (0) 2025.11.10
[Go] ์‹ค๋ฌด ํ™˜๊ฒฝ์—์„œ ๋กœ๊ทธ ์ œ๋Œ€๋กœ ๋‚จ๊ธฐ๊ธฐ(Logging)  (0) 2025.11.10
[Go] ํ˜•์‹์ง€์ •์ž Format ์ •๋ฆฌ(%v,%s,%d ๋“ฑ)  (0) 2025.11.07
[Go] Map ์›๋ฆฌ์™€ ํ™œ์šฉ(feat. hash)  (0) 2025.11.05
[Go] ์Šฌ๋ผ์ด์Šค(slice)์—๋Š” ํฌ์ธํ„ฐ๊ฐ€ ์žˆ๋‹ค  (0) 2025.10.14
'ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด/Go' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [Go] enum ์‚ฌ์šฉํ•˜๊ธฐ
  • [Go] ์‹ค๋ฌด ํ™˜๊ฒฝ์—์„œ ๋กœ๊ทธ ์ œ๋Œ€๋กœ ๋‚จ๊ธฐ๊ธฐ(Logging)
  • [Go] ํ˜•์‹์ง€์ •์ž Format ์ •๋ฆฌ(%v,%s,%d ๋“ฑ)
  • [Go] Map ์›๋ฆฌ์™€ ํ™œ์šฉ(feat. hash)
์„œ์•„๋ž‘๐Ÿ˜ƒ
์„œ์•„๋ž‘๐Ÿ˜ƒ
Just Do It๐Ÿ’ช
  • ์„œ์•„๋ž‘๐Ÿ˜ƒ
    G-Stack
    ์„œ์•„๋ž‘๐Ÿ˜ƒ
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • ์ „์ฒด๋ณด๊ธฐ (144)
      • ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด (78)
        • C++ ๊ธฐ์ดˆ (28)
        • C++ ์‘์šฉ (18)
        • Python (18)
        • JavaScript & NodeJS (0)
        • Go (12)
        • React & NextJS (2)
        • Java (0)
      • AI (2)
      • ์ปดํ“จํ„ฐ ๊ตฌ์กฐ & ์šด์˜์ฒด์ œ (31)
      • ์•Œ๊ณ ๋ฆฌ์ฆ˜ (12)
      • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค (5)
      • ๋„คํŠธ์›Œํฌ (3)
      • ๋””์ž์ธํŒจํ„ด (5)
      • ์„œ๋น„์Šค & ํˆด (7)
      • ํŠธ๋ Œ๋“œ&์ด์Šˆ (1)
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ํ™ˆ
    • ํƒœ๊ทธ
    • ๋ฐฉ๋ช…๋ก
  • ๋งํฌ

  • ๊ณต์ง€์‚ฌํ•ญ

    • G์Šคํƒ์˜ ๊ธฐ์ˆ  ๋ธ”๋กœ๊ทธ
  • ์ธ๊ธฐ ๊ธ€

  • ํƒœ๊ทธ

    ๋ฐ˜๋ณต๋ฌธ
    ์ƒ์†
    ์Šคํƒ
    ์•Œ๊ณ ๋ฆฌ์ฆ˜
    c
    ๋””์ž์ธํŒจํ„ด
    ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค
    ๋ฐฐ์—ด
    fork
    component
    ๋ฉ”๋ชจ๋ฆฌ
    ํŒŒ์ด์ฌ
    cpu
    ํฌ์ธํ„ฐ
    pointer
    ํŒจํ‚ค์ง€
    c++
    init
    ํ•จ์ˆ˜
    RAM
    ์ปดํ“จํ„ฐ
    ์กฐ๊ฑด๋ฌธ
    ํŒŒ์ผ์ž…์ถœ๋ ฅ
    ๊ฐ€์ƒ๋ฉ”๋ชจ๋ฆฌ
    Thread
    ํ•˜๋“œ๋””์Šคํฌ
    go
    STD
    ์žฌ๊ท€
    ๋ณ€์ˆ˜
  • ์ตœ๊ทผ ๋Œ“๊ธ€

  • ์ตœ๊ทผ ๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.6
์„œ์•„๋ž‘๐Ÿ˜ƒ
[Go] ์ผ์ • ์‹œ๊ฐ„๋งˆ๋‹ค ์Šค์ผ€์ค„๋Ÿฌ ๋™์ž‘ํ•˜๊ธฐ(Ticker)
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”