Browse Source

Session cleaner by worker

Vova Tkach 5 years ago
parent
commit
a7b2128c4a

+ 1 - 0
go.mod

@@ -7,6 +7,7 @@ require (
 	github.com/vladimirok5959/golang-server-resources v1.0.6
 	github.com/vladimirok5959/golang-server-sessions v1.0.6
 	github.com/vladimirok5959/golang-server-static v1.0.2
+	github.com/vladimirok5959/golang-worker v1.0.0
 	google.golang.org/appengine v1.4.0 // indirect
 )
 

+ 2 - 0
go.sum

@@ -13,6 +13,8 @@ github.com/vladimirok5959/golang-server-sessions v1.0.6 h1:i5W1hnWZ63B6x3mTvPK8g
 github.com/vladimirok5959/golang-server-sessions v1.0.6/go.mod h1:H99PB5Va7fw+Iljgne/f4ISsjg+V18Gq+9cNp+R6gaQ=
 github.com/vladimirok5959/golang-server-static v1.0.2 h1:pNR+vy+z2g73ETyx+50WxM4x2vqku3J1QCcRp7DnORo=
 github.com/vladimirok5959/golang-server-static v1.0.2/go.mod h1:NN4wQ3UjLdeQA14S8REpAjtXZxMS1o8Fs7XxomDP1Q4=
+github.com/vladimirok5959/golang-worker v1.0.0 h1:Qu29qWnpy0eXn4dKMd5mEjH+by1o7JWErvcIkMhNQ50=
+github.com/vladimirok5959/golang-worker v1.0.0/go.mod h1:WQitGjRYwCuS1/AoOQvHHbvYXCqR+FSzFW0LsunkBy4=
 golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81 h1:00VmoueYNlNz/aHIilyyQz/MHSqGoWJzpFv/HW8xpzI=
 golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=

+ 10 - 3
main.go

@@ -26,6 +26,7 @@ import (
 	"github.com/vladimirok5959/golang-server-resources/resource"
 	"github.com/vladimirok5959/golang-server-sessions/session"
 	"github.com/vladimirok5959/golang-server-static/static"
+	"github.com/vladimirok5959/golang-worker/worker"
 )
 
 func init() {
@@ -64,8 +65,7 @@ func main() {
 	mpool := mysqlpool.New()
 
 	// Session cleaner
-	sess_cl_ch, sess_cl_stop := session_clean_start(consts.ParamWwwDir)
-	defer session_clean_stop(sess_cl_ch, sess_cl_stop)
+	wSessCl := session_cleaner(consts.ParamWwwDir)
 
 	// Image processing
 	imgs_cl_ch, imgs_cl_stop := image_start(consts.ParamWwwDir)
@@ -284,9 +284,15 @@ func main() {
 		var errs []string
 
 		// ---
+		if wSessCl, ok := (*o)[2].(*worker.Worker); ok {
+			if err := wSessCl.Shutdown(ctx); err != nil {
+				errs = append(errs, fmt.Sprintf("(%T): %s", wSessCl, err.Error()))
+			}
+		}
+
 		if mpool, ok := (*o)[1].(*mysqlpool.MySqlPool); ok {
 			if err := mpool.Close(); err != nil {
-				errs = append(errs, err.Error())
+				errs = append(errs, fmt.Sprintf("(%T): %s", mpool, err.Error()))
 			}
 		}
 
@@ -316,6 +322,7 @@ func main() {
 			Objects: &[]bootstrap.Iface{
 				lg,
 				mpool,
+				wSessCl,
 				res,
 				stat,
 				mods,

+ 20 - 40
session.go

@@ -1,7 +1,7 @@
 package main
 
 import (
-	"fmt"
+	"context"
 	"io/ioutil"
 	"os"
 	"time"
@@ -9,15 +9,31 @@ import (
 	"golang-fave/utils"
 
 	"github.com/vladimirok5959/golang-server-sessions/session"
+	"github.com/vladimirok5959/golang-worker/worker"
 )
 
-func session_clean_do(www_dir string, stop chan bool) {
+func session_cleaner(www_dir string) *worker.Worker {
+	return worker.New(func(ctx context.Context, w *worker.Worker, o *[]worker.Iface) {
+		if www_dir, ok := (*o)[0].(string); ok {
+			session_clean(ctx, www_dir)
+		}
+		select {
+		case <-ctx.Done():
+		case <-time.After(1 * time.Hour):
+			return
+		}
+	}, &[]worker.Iface{
+		www_dir,
+	})
+}
+
+func session_clean(ctx context.Context, www_dir string) {
 	files, err := ioutil.ReadDir(www_dir)
 	if err == nil {
 		for _, file := range files {
 			select {
-			case <-stop:
-				break
+			case <-ctx.Done():
+				return
 			default:
 				tmpdir := www_dir + string(os.PathSeparator) + file.Name() + string(os.PathSeparator) + "tmp"
 				if utils.IsDirExists(tmpdir) {
@@ -27,39 +43,3 @@ func session_clean_do(www_dir string, stop chan bool) {
 		}
 	}
 }
-
-func session_clean_start(www_dir string) (chan bool, chan bool) {
-	ch := make(chan bool)
-	stop := make(chan bool)
-
-	// Cleanup at start
-	session_clean_do(www_dir, stop)
-
-	go func() {
-		for {
-			select {
-			case <-time.After(1 * time.Hour):
-				// Cleanup every one hour
-				session_clean_do(www_dir, stop)
-			case <-ch:
-				ch <- true
-				return
-			}
-		}
-	}()
-	return ch, stop
-}
-
-func session_clean_stop(ch, stop chan bool) {
-	for {
-		select {
-		case stop <- true:
-		case ch <- true:
-			<-ch
-			return
-		case <-time.After(3 * time.Second):
-			fmt.Println("Session error: force exit by timeout after 3 seconds")
-			return
-		}
-	}
-}

+ 21 - 0
vendor/github.com/vladimirok5959/golang-worker/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 Vova Tkach
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 60 - 0
vendor/github.com/vladimirok5959/golang-worker/worker/worker.go

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

+ 2 - 0
vendor/modules.txt

@@ -12,6 +12,8 @@ github.com/vladimirok5959/golang-server-resources/resource
 github.com/vladimirok5959/golang-server-sessions/session
 # github.com/vladimirok5959/golang-server-static v1.0.2
 github.com/vladimirok5959/golang-server-static/static
+# github.com/vladimirok5959/golang-worker v1.0.0
+github.com/vladimirok5959/golang-worker/worker
 # golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81
 golang.org/x/image/bmp
 golang.org/x/image/tiff