Browse Source

First version

Vova Tkach 5 years ago
parent
commit
af96fbbc73
6 changed files with 128 additions and 1 deletions
  1. 1 1
      .gitignore
  2. 17 0
      Makefile
  3. 3 0
      go.mod
  4. 51 0
      main.go
  5. 55 0
      worker/worker.go
  6. 1 0
      worker/worker_test.go

+ 1 - 1
.gitignore

@@ -9,7 +9,7 @@
 *.test
 
 # Output of the go coverage tool, specifically when used with LiteIDE
-*.out
+out
 
 # Dependency directories (remove the comment below to include it)
 # vendor/

+ 17 - 0
Makefile

@@ -0,0 +1,17 @@
+default: debug test run
+
+debug:
+	go vet ./...
+	gofmt -d ./
+	gofmt -w ./
+	go build -mod vendor -o ./out
+
+test:
+	go test ./...
+
+run:
+	@./out
+
+update:
+	go mod vendor
+	go mod download

+ 3 - 0
go.mod

@@ -0,0 +1,3 @@
+module github.com/vladimirok5959/golang-worker
+
+go 1.13

+ 51 - 0
main.go

@@ -0,0 +1,51 @@
+package main
+
+import (
+	"context"
+	"fmt"
+	"time"
+
+	"github.com/vladimirok5959/golang-worker/worker"
+)
+
+func main() {
+	fmt.Printf("Start!\n")
+
+	w1 := worker.New(func(ctx context.Context, w *worker.Worker) {
+		fmt.Printf("Worker #1 one tick\n")
+		for i := 0; i < 1000; i++ {
+			select {
+			case <-ctx.Done():
+				fmt.Printf("Worker #1 fine I will shutdown!\n")
+				return
+			default:
+				time.Sleep(1 * time.Millisecond)
+			}
+		}
+	})
+
+	w2 := worker.New(func(ctx context.Context, w *worker.Worker) {
+		fmt.Printf("Worker #2 one tick\n")
+		for i := 0; i < 1000; i++ {
+			select {
+			case <-ctx.Done():
+				fmt.Printf("Worker #2 fine I will shutdown!\n")
+				return
+			default:
+				time.Sleep(1 * time.Millisecond)
+			}
+		}
+	})
+
+	time.Sleep(3 * time.Second)
+
+	w1.Finish()
+
+	if err := w2.Shutdown(nil); err != nil {
+		fmt.Printf("Worker #2 shutdown error: %s\n", err.Error())
+	}
+
+	time.Sleep(1 * time.Second)
+
+	fmt.Printf("End!\n")
+}

+ 55 - 0
worker/worker.go

@@ -0,0 +1,55 @@
+package worker
+
+import (
+	"context"
+)
+
+type Worker struct {
+	ctx    context.Context
+	cancel context.CancelFunc
+	chDone chan bool
+}
+
+type Callback func(ctx context.Context, w *Worker)
+
+func New(f Callback) *Worker {
+	ctx, cancel := context.WithCancel(context.Background())
+	w := Worker{ctx: ctx, cancel: cancel, chDone: make(chan bool)}
+	return (&w).doit(f)
+}
+
+func (this *Worker) doit(f func(ctx context.Context, w *Worker)) *Worker {
+	go func() {
+		for {
+			select {
+			case <-this.ctx.Done():
+				this.chDone <- true
+				return
+			default:
+				f(this.ctx, this)
+			}
+		}
+	}()
+
+	return this
+}
+
+func (this *Worker) Shutdown(ctx context.Context) error {
+	ctxb := ctx
+	if ctxb == nil {
+		ctxb = context.Background()
+	}
+
+	this.cancel()
+
+	select {
+	case <-this.chDone:
+		return nil
+	case <-ctxb.Done():
+		return ctxb.Err()
+	}
+}
+
+func (this *Worker) Finish() {
+	this.cancel()
+}

+ 1 - 0
worker/worker_test.go

@@ -0,0 +1 @@
+package worker