Job Wrapper / Add RMutex Locks

Signed-off-by: Sherif Abdel-Naby <sherifabdlnaby@gmail.com>
This commit is contained in:
Sherif Abdel-Naby 2021-04-03 06:43:16 +02:00
parent 095b56b46d
commit e7bf70c3e0
2 changed files with 40 additions and 14 deletions

View file

@ -1,17 +1,17 @@
package Job
package job
type ErrorJobPanic struct {
Name string
Message string
}
func (e ErrorJobPanic) Error() string {
return e.Name
return e.Message
}
type ErrorJobNotStarted struct {
Name string
type ErrorJobStarted struct {
Message string
}
func (e ErrorJobNotStarted) Error() string {
return e.Name
func (e ErrorJobStarted) Error() string {
return e.Message
}

View file

@ -1,12 +1,13 @@
package Job
package job
import (
"fmt"
"github.com/google/uuid"
"sync"
"time"
)
type State int
type State int64
const (
NEW State = iota
@ -22,6 +23,11 @@ type Job struct {
startTime time.Time
finishTime time.Time
state State
mx sync.RWMutex
}
func (j *Job) State() State {
return j.state
}
func NewJobWithID(id string, jobFunc func()) *Job {
@ -43,14 +49,17 @@ func (j *Job) ID() string {
return j.id
}
func (j *Job) Duration() (time.Duration, error) {
func (j *Job) Duration() time.Duration {
j.mx.RLock()
defer j.mx.RUnlock()
if !j.startTime.IsZero() {
if j.finishTime.IsZero() {
return time.Since(j.startTime), nil
return time.Since(j.startTime)
}
return j.finishTime.Sub(j.startTime), nil
return j.finishTime.Sub(j.startTime)
}
return -1, fmt.Errorf("job hasn't started yet")
return -1
}
func (j *Job) Start() error {
@ -58,20 +67,37 @@ func (j *Job) Start() error {
}
func (j *Job) start() (err error) {
j.mx.RLock()
if j.state != NEW {
if j.state == STARTED {
err = ErrorJobStarted{Message: "job already started"}
return err
}
err = ErrorJobStarted{Message: "job finished execution"}
return err
}
j.mx.RUnlock()
j.mx.Lock()
j.state = STARTED
j.startTime = time.Now()
// Handle Panics and set correct state
defer func() {
j.mx.Lock()
if r := recover(); r != nil {
err = fmt.Errorf("job panicked: %v", r)
err = ErrorJobPanic{Message: fmt.Sprintf("job panicked: %v", r)}
j.state = PANICKED
} else {
j.state = FINISHED
}
j.finishTime = time.Now()
j.mx.Unlock()
}()
// Unlock State
j.mx.Unlock()
// Start Job
j.jobFunc()