├── go.sum
├── go.mod
├── doc.go
├── codecov.yml
├── examples_test.go
├── Makefile
├── .github
├── settings.yml
├── release.yml
└── workflows
│ ├── lint.yml
│ ├── go.yml
│ ├── tweet-release.yml
│ └── atomicgo.yml
├── LICENSE
├── Taskfile.yml
├── .gitignore
├── schedule.go
├── README.md
└── .golangci.yml
/go.sum:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module atomicgo.dev/schedule
2 |
3 | go 1.18
4 |
--------------------------------------------------------------------------------
/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | Package schedule provides a simple scheduler for Go.
3 |
4 | It can run a function at a given time, in a given duration, or repeatedly at a given interval.
5 | */
6 | package schedule
7 |
--------------------------------------------------------------------------------
/codecov.yml:
--------------------------------------------------------------------------------
1 | # ┌───────────────────────────────────────────────────────────────────┐
2 | # │ │
3 | # │ IMPORTANT NOTE │
4 | # │ │
5 | # │ This file is synced with https://github.com/atomicgo/template │
6 | # │ │
7 | # │ Please apply all changes to the template repository │
8 | # │ │
9 | # └───────────────────────────────────────────────────────────────────┘
10 |
11 | coverage:
12 | status:
13 | project:
14 | default:
15 | informational: true
16 | patch:
17 | default:
18 | informational: true
19 |
--------------------------------------------------------------------------------
/examples_test.go:
--------------------------------------------------------------------------------
1 | package schedule_test
2 |
3 | import (
4 | "fmt"
5 | "time"
6 |
7 | "atomicgo.dev/schedule"
8 | )
9 |
10 | func ExampleAfter() {
11 | task := schedule.After(5*time.Second, func() {
12 | fmt.Println("5 seconds are over!")
13 | })
14 |
15 | fmt.Println("Some stuff happening...")
16 |
17 | task.Wait()
18 | }
19 |
20 | func ExampleAt() {
21 | task := schedule.At(time.Now().Add(5*time.Second), func() {
22 | fmt.Println("5 seconds are over!")
23 | })
24 |
25 | fmt.Println("Some stuff happening...")
26 |
27 | task.Wait()
28 | }
29 |
30 | func ExampleEvery() {
31 | task := schedule.Every(time.Second, func() bool {
32 | fmt.Println("1 second is over!")
33 |
34 | return true // return false to stop the task
35 | })
36 |
37 | fmt.Println("Some stuff happening...")
38 |
39 | time.Sleep(10 * time.Second)
40 |
41 | task.Stop()
42 | }
43 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # ┌───────────────────────────────────────────────────────────────────┐
2 | # │ │
3 | # │ IMPORTANT NOTE │
4 | # │ │
5 | # │ This file is synced with https://github.com/atomicgo/template │
6 | # │ │
7 | # │ Please apply all changes to the template repository │
8 | # │ │
9 | # └───────────────────────────────────────────────────────────────────┘
10 |
11 | test:
12 | @echo "# Running tests..."
13 | @go test -v ./...
14 |
15 | lint:
16 | @echo "# Linting..."
17 | @echo "## Go mod tidy..."
18 | @go mod tidy
19 | @echo "## Fixing whitespaces..."
20 | @wsl --allow-cuddle-declarations --force-err-cuddling --force-case-trailing-whitespace 3 --fix ./...
21 | @echo "## Running golangci-lint..."
22 | @golangci-lint run
23 |
--------------------------------------------------------------------------------
/.github/settings.yml:
--------------------------------------------------------------------------------
1 | _extends: .github
2 |
3 | repository:
4 | # See https://developer.github.com/v3/repos/#edit for all available settings.
5 |
6 | # A short description of the repository that will show up on GitHub
7 | description: ⏰ Easily schedule non-blocking tasks in Go. Supports durations, specific times and intervals.
8 |
9 | # A comma-separated list of topics to set on the repository
10 | topics: atomicgo, go, golang, golang-library, scheduler, time, ticker, schedule, timer, hacktoberfest
11 |
12 | # Either `true` to make the repository private, or `false` to make it public.
13 | private: false
14 |
15 | # Either `true` to enable issues for this repository, `false` to disable them.
16 | has_issues: true
17 |
18 | # Either `true` to enable projects for this repository, or `false` to disable them.
19 | # If projects are disabled for the organization, passing `true` will cause an API error.
20 | has_projects: false
21 |
22 | # Either `true` to enable the wiki for this repository, `false` to disable it.
23 | has_wiki: false
24 |
--------------------------------------------------------------------------------
/.github/release.yml:
--------------------------------------------------------------------------------
1 | # ┌───────────────────────────────────────────────────────────────────┐
2 | # │ │
3 | # │ IMPORTANT NOTE │
4 | # │ │
5 | # │ This file is synced with https://github.com/atomicgo/template │
6 | # │ │
7 | # │ Please apply all changes to the template repository │
8 | # │ │
9 | # └───────────────────────────────────────────────────────────────────┘
10 |
11 | changelog:
12 | exclude:
13 | labels:
14 | - ignore-for-release
15 | authors:
16 | - octocat
17 | categories:
18 | - title: Breaking Changes 🛠
19 | labels:
20 | - breaking
21 | - title: Exciting New Features 🎉
22 | labels:
23 | - feature
24 | - title: Fixes 🔧
25 | labels:
26 | - fix
27 | - title: Other Changes
28 | labels:
29 | - "*"
30 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Marvin Wendt (aka. MarvinJWendt)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Taskfile.yml:
--------------------------------------------------------------------------------
1 | # ┌───────────────────────────────────────────────────────────────────┐
2 | # │ │
3 | # │ IMPORTANT NOTE │
4 | # │ │
5 | # │ This file is synced with https://github.com/atomicgo/template │
6 | # │ │
7 | # │ Please apply all changes to the template repository │
8 | # │ │
9 | # └───────────────────────────────────────────────────────────────────┘
10 |
11 | version: "3"
12 |
13 | tasks:
14 | test:
15 | desc: Run all tests
16 | cmds:
17 | - go test ./...
18 | tdd:
19 | desc: Test Driven Development - Watch tests
20 | watch: true
21 | sources:
22 | - "**/*.go"
23 | cmds:
24 | - go test ./...
25 |
26 | lint:
27 | desc: Run all linters
28 | cmds:
29 | - go mod tidy
30 | - wsl --allow-cuddle-declarations --force-err-cuddling --force-case-trailing-whitespace 3 --fix ./...
31 | - golangci-lint run
32 |
--------------------------------------------------------------------------------
/.github/workflows/lint.yml:
--------------------------------------------------------------------------------
1 | # ┌───────────────────────────────────────────────────────────────────┐
2 | # │ │
3 | # │ IMPORTANT NOTE │
4 | # │ │
5 | # │ This file is synced with https://github.com/atomicgo/template │
6 | # │ │
7 | # │ Please apply all changes to the template repository │
8 | # │ │
9 | # └───────────────────────────────────────────────────────────────────┘
10 |
11 | name: Code Analysis
12 |
13 | on: [push, pull_request]
14 |
15 | jobs:
16 | lint:
17 | if: "!contains(github.event.head_commit.message, 'autoupdate')"
18 | runs-on: ubuntu-latest
19 | steps:
20 | - uses: actions/checkout@v3
21 |
22 | - name: Set up Go
23 | uses: actions/setup-go@v4
24 | with:
25 | go-version: "stable"
26 |
27 | - name: golangci-lint
28 | uses: golangci/golangci-lint-action@v3
29 | with:
30 | version: latest
31 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # ┌───────────────────────────────────────────────────────────────────┐
2 | # │ │
3 | # │ IMPORTANT NOTE │
4 | # │ │
5 | # │ This file is synced with https://github.com/atomicgo/template │
6 | # │ │
7 | # │ Please apply all changes to the template repository │
8 | # │ │
9 | # └───────────────────────────────────────────────────────────────────┘
10 |
11 | # Binaries
12 | *.exe
13 | *.exe~
14 | *.so
15 |
16 | # Go specifics
17 |
18 | ## Test binary, built with `go test -c`
19 | *.test
20 |
21 | ## Output of the go coverage tool
22 | *.out
23 |
24 | ## Vendored dependencies
25 | vendor/
26 |
27 | # IDEs
28 |
29 | ## IntelliJ
30 | .idea
31 | *.iml
32 | out
33 | gen
34 |
35 | ## Visual Studio Code
36 | .vscode
37 | *.code-workspace
38 |
39 | # Operating System Files
40 |
41 | ## macOS
42 | .DS_Store
43 |
44 | # Other
45 |
46 | ## Experimenting folder
47 | experimenting
48 |
49 | ## CI assets
50 | .templates
51 |
52 | ## Taskfile
53 | .task
54 |
--------------------------------------------------------------------------------
/.github/workflows/go.yml:
--------------------------------------------------------------------------------
1 | # ┌───────────────────────────────────────────────────────────────────┐
2 | # │ │
3 | # │ IMPORTANT NOTE │
4 | # │ │
5 | # │ This file is synced with https://github.com/atomicgo/template │
6 | # │ │
7 | # │ Please apply all changes to the template repository │
8 | # │ │
9 | # └───────────────────────────────────────────────────────────────────┘
10 |
11 | name: Go
12 |
13 | on:
14 | pull_request:
15 |
16 | jobs:
17 | test:
18 | name: Test Go code
19 | runs-on: ${{ matrix.os }}
20 | strategy:
21 | matrix:
22 | os: [ubuntu-latest, windows-latest, macos-latest]
23 | steps:
24 | - name: Set up Go
25 | uses: actions/setup-go@v4
26 | with:
27 | go-version: stable
28 |
29 | - name: Check out code into the Go module directory
30 | uses: actions/checkout@v3
31 |
32 | - name: Get dependencies
33 | run: go get -v -t -d ./...
34 |
35 | - name: Build
36 | run: go build -v .
37 |
38 | - name: Test
39 | run: go test -coverprofile="coverage.txt" -covermode=atomic -v -p 1 .
40 |
41 | - name: Upload coverage to Codecov
42 | uses: codecov/codecov-action@v1
43 |
--------------------------------------------------------------------------------
/.github/workflows/tweet-release.yml:
--------------------------------------------------------------------------------
1 | # ┌───────────────────────────────────────────────────────────────────┐
2 | # │ │
3 | # │ IMPORTANT NOTE │
4 | # │ │
5 | # │ This file is synced with https://github.com/atomicgo/template │
6 | # │ │
7 | # │ Please apply all changes to the template repository │
8 | # │ │
9 | # └───────────────────────────────────────────────────────────────────┘
10 |
11 | name: Tweet release
12 |
13 | # Listen to the `release` event
14 | on:
15 | release:
16 | types: [published]
17 |
18 | jobs:
19 | tweet:
20 | runs-on: ubuntu-latest
21 | steps:
22 | - uses: Eomm/why-don-t-you-tweet@v1
23 | # We don't want to tweet if the repository is not a public one
24 | if: ${{ !github.event.repository.private }}
25 | with:
26 | tweet-message:
27 | "New ${{ github.event.repository.name }} release: ${{ github.event.release.tag_name }}! 🎉
28 |
29 | Try it out: atomicgo.dev/${{ github.event.repository.name }}
30 |
31 | #go #golang #opensource #library #release #atomicgo"
32 | env:
33 | TWITTER_CONSUMER_API_KEY: ${{ secrets.TWITTER_CONSUMER_API_KEY }}
34 | TWITTER_CONSUMER_API_SECRET: ${{ secrets.TWITTER_CONSUMER_API_SECRET }}
35 | TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }}
36 | TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
37 |
--------------------------------------------------------------------------------
/schedule.go:
--------------------------------------------------------------------------------
1 | package schedule
2 |
3 | import (
4 | "sync"
5 | "sync/atomic"
6 | "time"
7 | )
8 |
9 | // Task holds information about the running task and can be used to stop running tasks.
10 | type Task struct {
11 | stop chan struct{}
12 | nextExecution time.Time
13 | startedAt time.Time
14 | stopped int32 // 0 means active, 1 means stopped
15 | once sync.Once
16 | }
17 |
18 | // newTask creates a new Task.
19 | func newTask() *Task {
20 | return &Task{
21 | stop: make(chan struct{}),
22 | startedAt: time.Now(),
23 | }
24 | }
25 |
26 | // StartedAt returns the time when the scheduler was started.
27 | func (s *Task) StartedAt() time.Time {
28 | return s.startedAt
29 | }
30 |
31 | // NextExecutionTime returns the time when the next execution will happen.
32 | func (s *Task) NextExecutionTime() time.Time {
33 | return s.nextExecution
34 | }
35 |
36 | // ExecutesIn returns the duration until the next execution.
37 | func (s *Task) ExecutesIn() time.Duration {
38 | return time.Until(s.nextExecution)
39 | }
40 |
41 | // IsActive returns true if the scheduler is active.
42 | func (s *Task) IsActive() bool {
43 | return atomic.LoadInt32(&s.stopped) == 0
44 | }
45 |
46 | // Wait blocks until the scheduler is stopped.
47 | // After and At will stop automatically after the task is executed.
48 | func (s *Task) Wait() {
49 | <-s.stop
50 | }
51 |
52 | // Stop stops the scheduler.
53 | func (s *Task) Stop() {
54 | s.once.Do(func() {
55 | atomic.StoreInt32(&s.stopped, 1)
56 | close(s.stop)
57 | })
58 | }
59 |
60 | // After executes the task after the given duration.
61 | // The function is non-blocking. If you want to wait for the task to be executed, use the Task.Wait method.
62 | func After(duration time.Duration, task func()) *Task {
63 | scheduler := newTask()
64 | scheduler.nextExecution = time.Now().Add(duration)
65 | timer := time.NewTimer(duration)
66 |
67 | go func() {
68 | select {
69 | case <-timer.C:
70 | task()
71 | scheduler.Stop()
72 | case <-scheduler.stop:
73 | // If the task is stopped before the timer fires, stop the timer.
74 | if !timer.Stop() {
75 | <-timer.C // drain if necessary
76 | }
77 | return
78 | }
79 | }()
80 |
81 | return scheduler
82 | }
83 |
84 | // At executes the task at the given time.
85 | // The function is non-blocking. If you want to wait for the task to be executed, use the Task.Wait method.
86 | func At(t time.Time, task func()) *Task {
87 | scheduler := newTask()
88 | scheduler.nextExecution = t
89 | d := time.Until(t)
90 | if d < 0 {
91 | d = 0
92 | }
93 | timer := time.NewTimer(d)
94 |
95 | go func() {
96 | select {
97 | case <-timer.C:
98 | task()
99 | scheduler.Stop()
100 | case <-scheduler.stop:
101 | if !timer.Stop() {
102 | <-timer.C
103 | }
104 | return
105 | }
106 | }()
107 |
108 | return scheduler
109 | }
110 |
111 | // Every executes the task in the given interval, as long as the task function returns true.
112 | // The function is non-blocking. If you want to wait for the task to be executed, use the Task.Wait method.
113 | func Every(interval time.Duration, task func() bool) *Task {
114 | scheduler := newTask()
115 | scheduler.nextExecution = time.Now().Add(interval)
116 | ticker := time.NewTicker(interval)
117 |
118 | go func() {
119 | for {
120 | select {
121 | case <-ticker.C:
122 | if !task() {
123 | scheduler.Stop()
124 | ticker.Stop()
125 | return
126 | }
127 | scheduler.nextExecution = time.Now().Add(interval)
128 | case <-scheduler.stop:
129 | ticker.Stop()
130 | return
131 | }
132 | }
133 | }()
134 |
135 | return scheduler
136 | }
137 |
--------------------------------------------------------------------------------
/.github/workflows/atomicgo.yml:
--------------------------------------------------------------------------------
1 | # ┌───────────────────────────────────────────────────────────────────┐
2 | # │ │
3 | # │ IMPORTANT NOTE │
4 | # │ │
5 | # │ This file is synced with https://github.com/atomicgo/template │
6 | # │ │
7 | # │ Please apply all changes to the template repository │
8 | # │ │
9 | # └───────────────────────────────────────────────────────────────────┘
10 |
11 | name: AtomicGo
12 |
13 | on:
14 | push:
15 | branches:
16 | - main
17 |
18 | permissions:
19 | contents: write
20 | packages: write
21 |
22 | jobs:
23 | test:
24 | name: Test Go Code
25 | runs-on: ${{ matrix.os }}
26 | strategy:
27 | matrix:
28 | os: [ubuntu-latest, windows-latest, macos-latest]
29 | steps:
30 | - name: Set up Go
31 | uses: actions/setup-go@v4
32 | with:
33 | go-version: stable
34 |
35 | - name: Check out code into the Go module directory
36 | uses: actions/checkout@v3
37 |
38 | - name: Get dependencies
39 | run: go get -v -t -d ./...
40 |
41 | - name: Build
42 | run: go build -v .
43 |
44 | - name: Test
45 | run: go test -coverprofile="coverage.txt" -covermode=atomic -v -p 1 .
46 |
47 | - name: Upload coverage to Codecov
48 | uses: codecov/codecov-action@v3
49 |
50 | build:
51 | name: Build AtomicGo Package
52 | runs-on: ubuntu-latest
53 | needs: test
54 |
55 | env:
56 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
57 |
58 | steps:
59 | - name: Checkout repository
60 | uses: actions/checkout@v3
61 | with:
62 | fetch-depth: 0
63 |
64 | - name: Download assets
65 | run: |
66 | mkdir -p .templates
67 | wget https://raw.githubusercontent.com/atomicgo/atomicgo/main/templates/example.gotxt -O .templates/example.gotxt
68 | wget https://raw.githubusercontent.com/atomicgo/atomicgo/main/templates/readme.md -O .templates/readme.md
69 |
70 | - name: Set up Go
71 | uses: actions/setup-go@v4
72 | with:
73 | go-version: stable
74 |
75 | - name: Install Go tools
76 | run: |
77 | go install github.com/robertkrimen/godocdown/godocdown@latest
78 | go install github.com/princjef/gomarkdoc/cmd/gomarkdoc@latest
79 | go install github.com/caarlos0/svu@latest
80 |
81 | - name: Set up Git configuration
82 | run: |
83 | REPO_FULLNAME="${{ github.repository }}"
84 | echo "::group::Setup git"
85 | git config --global --add safe.directory /github/workspace
86 |
87 | echo "::notice::Login into git"
88 | git config --global user.email "git@marvinjwendt.com"
89 | git config --global user.name "MarvinJWendt"
90 |
91 | echo "::notice::Ignore workflow files (we may not touch them)"
92 | git update-index --assume-unchanged .github/workflows/*
93 |
94 | - name: Generate README.md
95 | run: |
96 | echo "::group::Generate README.md"
97 | FILE=./.github/atomicgo/custom_readme
98 | INCLUDE_UNEXPORTED=./.github/atomicgo/include_unexported
99 | if test -f "$FILE"; then
100 | echo "::notice::.github/custom_readme is present. Not generating a new readme."
101 | else
102 | echo "::notice::Running Godocdown"
103 | $(go env GOPATH)/bin/godocdown -template ./.templates/readme.md >README.md
104 | echo "::notice::Running gomarkdoc"
105 | GOMARKDOC_FLAGS="--template-file example=./.templates/example.gotxt"
106 | if test -f "$INCLUDE_UNEXPORTED"; then
107 | GOMARKDOC_FLAGS+=" -u"
108 | fi
109 |
110 | $(go env GOPATH)/bin/gomarkdoc $GOMARKDOC_FLAGS --repository.url "https://github.com/${{ github.repository }}" --repository.default-branch main --repository.path / -e -o README.md .
111 | fi
112 | echo "::endgroup::"
113 |
114 | - name: Run custom CI system
115 | run: |
116 | echo "::group::Run custom CI system"
117 | echo "::notice::Counting unit tests"
118 | unittest_count=$(go test -v -p 1 ./... | tee /dev/tty | grep -c "RUN")
119 |
120 | echo "::notice::Replacing badge in README.md"
121 | sed -i 's|> $GITHUB_ENV
148 | echo "::notice::Current version is $(svu current)"
149 |
150 | - name: Calculate next version
151 | id: next_version
152 | run: |
153 | echo "next_version=$(svu next)" >> $GITHUB_ENV
154 | echo "::notice::Next version is $(svu next)"
155 |
156 | - name: Check if release is needed
157 | id: check_release
158 | run: |
159 | echo "release_needed=$( [ '${{ env.current_version }}' != '${{ env.next_version }}' ] && echo true || echo false )" >> $GITHUB_ENV
160 |
161 | - name: Create tag
162 | if: env.release_needed == 'true'
163 | run: |
164 | git tag -a ${{ env.next_version }} -m "Release v${{ env.next_version }}"
165 | git push origin ${{ env.next_version }}
166 | sleep 5 # sleep for 5 seconds to allow GitHub to process the tag
167 |
168 | - name: Release
169 | if: env.release_needed == 'true'
170 | uses: softprops/action-gh-release@v2
171 | with:
172 | token: ${{ secrets.GITHUB_TOKEN }}
173 | generate_release_notes: true
174 | tag_name: ${{ env.next_version }}
175 |
176 | - name: Tweet release
177 | if: env.release_needed == 'true' && !github.event.repository.private
178 | uses: Eomm/why-don-t-you-tweet@v1
179 | with:
180 | tweet-message:
181 | "New ${{ github.event.repository.name }} release: ${{ env.next_version }} 🚀
182 |
183 | Try it out: atomicgo.dev/${{ github.event.repository.name }}
184 |
185 | #go #golang #opensource #library #release #atomicgo"
186 | env:
187 | TWITTER_CONSUMER_API_KEY: ${{ secrets.TWITTER_CONSUMER_API_KEY }}
188 | TWITTER_CONSUMER_API_SECRET: ${{ secrets.TWITTER_CONSUMER_API_SECRET }}
189 | TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }}
190 | TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
191 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
35 | Documentation 36 | | 37 | Contributing 38 | | 39 | Code of Conduct 40 |
41 | 42 | --- 43 | 44 |
45 |
46 |
49 |
go get atomicgo.dev/schedule
56 |
112 | 113 | 114 | 115 | ```go 116 | package main 117 | 118 | import ( 119 | "fmt" 120 | "time" 121 | 122 | "atomicgo.dev/schedule" 123 | ) 124 | 125 | func main() { 126 | task := schedule.After(5*time.Second, func() { 127 | fmt.Println("5 seconds are over!") 128 | }) 129 | 130 | fmt.Println("Some stuff happening...") 131 | 132 | task.Wait() 133 | } 134 | ``` 135 | 136 |
137 |150 | 151 | 152 | 153 | ```go 154 | package main 155 | 156 | import ( 157 | "fmt" 158 | "time" 159 | 160 | "atomicgo.dev/schedule" 161 | ) 162 | 163 | func main() { 164 | task := schedule.At(time.Now().Add(5*time.Second), func() { 165 | fmt.Println("5 seconds are over!") 166 | }) 167 | 168 | fmt.Println("Some stuff happening...") 169 | 170 | task.Wait() 171 | } 172 | ``` 173 | 174 |
175 |188 | 189 | 190 | 191 | ```go 192 | package main 193 | 194 | import ( 195 | "fmt" 196 | "time" 197 | 198 | "atomicgo.dev/schedule" 199 | ) 200 | 201 | func main() { 202 | task := schedule.Every(time.Second, func() bool { 203 | fmt.Println("1 second is over!") 204 | 205 | return true // return false to stop the task 206 | }) 207 | 208 | fmt.Println("Some stuff happening...") 209 | 210 | time.Sleep(10 * time.Second) 211 | 212 | task.Stop() 213 | } 214 | ``` 215 | 216 |
217 |