You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
4.0 KiB
183 lines
4.0 KiB
// ------------------------------------------------------------------------
|
|
// Project atila
|
|
// Active Thing (activething.com) git.activething.com/go
|
|
//
|
|
// File name rkey.go
|
|
// Created by DEV
|
|
// Modified 05/02/2024
|
|
//
|
|
// Copyright 2024 activething.com
|
|
// ------------------------------------------------------------------------
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
// ------------------------------------------------------------------------
|
|
|
|
package cronus
|
|
|
|
import (
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
|
|
)
|
|
|
|
type (
|
|
|
|
|
|
Expiration struct {
|
|
timer *time.Timer
|
|
times Chrono
|
|
|
|
state uint32
|
|
source uint32
|
|
timeout int64
|
|
deadline int64
|
|
|
|
expireFn func()
|
|
}
|
|
)
|
|
|
|
|
|
func NewExpiration(duration time.Duration, expirer func()) *Expiration {
|
|
ex := &Expiration{
|
|
times: *NewChrono(false),
|
|
state: uint32(TimerStateCreated),
|
|
source: uint32(ExpirationSourceSelf),
|
|
timeout: int64(duration),
|
|
expireFn: expirer,
|
|
}
|
|
if duration > 0 {
|
|
atomic.StoreUint32(&ex.source,uint32(ExpirationSourceTimer))
|
|
}
|
|
return ex
|
|
}
|
|
|
|
|
|
|
|
func (e *Expiration) Reset() {
|
|
e.times.Reset()
|
|
atomic.StoreUint32(&e.state ,uint32(TimerStateCreated))
|
|
atomic.StoreUint32(&e.source,uint32(ExpirationSourceSelf))
|
|
atomic.StoreInt64 (&e.timeout ,0)
|
|
atomic.StoreInt64 (&e.deadline,0)
|
|
if e.timer != nil {
|
|
if !e.timer.Stop() {
|
|
select {
|
|
case <- e.timer.C:
|
|
default:
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func (e *Expiration) State() TimerState {
|
|
return TimerState(atomic.LoadUint32(&e.state)) }
|
|
|
|
|
|
|
|
func (e *Expiration) Chono() Chronometer {
|
|
return &e.times }
|
|
|
|
|
|
func (e *Expiration) Source() ExpirationSource {
|
|
return ExpirationSource(atomic.LoadUint32(&e.source)) }
|
|
|
|
|
|
|
|
func (e *Expiration) Timeout() time.Duration {
|
|
return time.Duration(atomic.LoadInt64(&e.timeout)) }
|
|
|
|
|
|
func (e *Expiration) Deadline() time.Time {
|
|
return time.Unix(0,atomic.LoadInt64(&e.deadline)) }
|
|
|
|
|
|
|
|
func (e *Expiration) Start(expirer Expirer) error {
|
|
if !atomic.CompareAndSwapUint32(&e.state,uint32(TimerStateCreated),uint32(TimerStateStarted)) {
|
|
return G.ErrAlreadyStarted
|
|
}
|
|
|
|
st := e.times.Start()
|
|
to := time.Duration(atomic.LoadInt64(&e.timeout))
|
|
dl := st.Add(to)
|
|
|
|
if expirer != nil {
|
|
pd, ph := expirer.Deadline()
|
|
if ph {
|
|
if pd.Before(st) {
|
|
atomic.StoreUint32(&e.state ,uint32(TimerStateExpired))
|
|
atomic.StoreUint32(&e.source,uint32(ExpirationSourceParent))
|
|
return G.ErrExpired
|
|
}
|
|
if pd.Before(dl) {
|
|
atomic.StoreInt64 (&e.deadline,pd.UnixNano())
|
|
atomic.StoreUint32(&e.source ,uint32(ExpirationSourceParent))
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
|
|
if atomic.LoadUint32(&e.source) == uint32(ExpirationSourceTimer) {
|
|
atomic.StoreInt64 (&e.deadline,dl.UnixNano())
|
|
if e.timer == nil {
|
|
e.timer = time.NewTimer(to)
|
|
} else {
|
|
e.timer.Reset(to)
|
|
}
|
|
go func(ex *Expiration) {
|
|
select {
|
|
case <-ex.timer.C:
|
|
atomic.StoreUint32(&ex.state,uint32(TimerStateExpired))
|
|
ex.times.Stop()
|
|
if ex.expireFn != nil {
|
|
ex.expireFn()
|
|
}
|
|
return
|
|
}
|
|
}(e)
|
|
|
|
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
|
|
func (e *Expiration) Stop() error {
|
|
if !atomic.CompareAndSwapUint32(&e.state,uint32(TimerStateStarted), uint32(TimerStateStopped)) {
|
|
return G.ErrNotStarted
|
|
}
|
|
e.times.Stop()
|
|
if e.timer != nil && !e.timer.Stop() {
|
|
select {
|
|
case <-e.timer.C:
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
/*
|
|
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
|
|
|
I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA.
|
|
"LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS.
|
|
|
|
SIDDHARTA
|
|
- HERMANN HESSE -
|
|
|
|
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
|
|
|
*/
|