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.
175 lines
3.8 KiB
175 lines
3.8 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 timers
|
|
|
|
import (
|
|
"activething.com/go/gogo/core/contexts"
|
|
"context"
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
|
|
|
|
|
|
|
|
)
|
|
|
|
type (
|
|
|
|
|
|
Pulsar struct {
|
|
state uint32
|
|
pulse int64
|
|
err atomic.Value
|
|
cancel contexts.Cancel
|
|
workFn PulsarWorkFnc
|
|
}
|
|
|
|
|
|
PulsarWorkFnc func(ctx context.Context) error
|
|
|
|
)
|
|
|
|
|
|
func NewPulsar(pulse time.Duration, work PulsarWorkFnc) *Pulsar {
|
|
return &Pulsar{
|
|
state: uint32(TimerStateCreated),
|
|
cancel: *contexts.NewCancel(),
|
|
pulse: int64(pulse),
|
|
workFn: work,
|
|
}
|
|
}
|
|
|
|
|
|
func (p *Pulsar) State() TimerState {
|
|
return TimerState(atomic.LoadUint32(&p.state)) }
|
|
|
|
|
|
func (p *Pulsar) Pulse() time.Duration {
|
|
return time.Duration(atomic.LoadInt64(&p.pulse)) }
|
|
|
|
|
|
func (p *Pulsar) Err() error {
|
|
if v := p.err.Load(); v != nil {
|
|
return v.(error)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
|
|
func (p *Pulsar) Start(ctx context.Context) error {
|
|
if !atomic.CompareAndSwapUint32(&p.state,uint32(TimerStateCreated),uint32(TimerStateStarted)) {
|
|
return G.ErrAlreadyStarted
|
|
}
|
|
to := atomic.LoadInt64(&p.pulse)
|
|
if to <= 0 {
|
|
atomic.StoreUint32(&p.state,uint32(TimerStateExpired))
|
|
return G.ErrIntervalInvalid
|
|
}
|
|
|
|
cx := ctx
|
|
if cx == nil {
|
|
cx = context.Background()
|
|
} else if ctx.Err() != nil {
|
|
atomic.StoreUint32(&p.state,uint32(TimerStateCanceled))
|
|
return context.Canceled
|
|
}
|
|
|
|
go func(pl *Pulsar, tk *time.Ticker, cx context.Context) {
|
|
EXIT:
|
|
for {
|
|
select {
|
|
case <-cx.Done():
|
|
atomic.StoreUint32(&pl.state,uint32(TimerStateCanceled))
|
|
break EXIT
|
|
|
|
case <-pl.cancel.Done():
|
|
break EXIT
|
|
|
|
case <-tk.C:
|
|
if TimerState(atomic.LoadUint32(&pl.state)) == TimerStateStarted {
|
|
if er := pl.workFn(cx); er != nil {
|
|
pl.err.Store(er)
|
|
atomic.StoreUint32(&pl.state,uint32(TimerStateCanceled))
|
|
break EXIT
|
|
}
|
|
}
|
|
}
|
|
}
|
|
tk.Stop()
|
|
pl.cancel.Cancel()
|
|
|
|
}(p, time.NewTicker(time.Duration(to)), cx)
|
|
|
|
return nil
|
|
}
|
|
|
|
|
|
func (p *Pulsar) Stop() error {
|
|
if atomic.CompareAndSwapUint32(&p.state,uint32(TimerStateStarted), uint32(TimerStateStopped)) ||
|
|
atomic.CompareAndSwapUint32(&p.state,uint32(TimerStatePaused), uint32(TimerStateStopped)) {
|
|
p.cancel.Cancel()
|
|
return nil
|
|
}
|
|
return G.ErrNotStarted
|
|
}
|
|
|
|
|
|
func (p *Pulsar) Pause() error {
|
|
if atomic.CompareAndSwapUint32(&p.state,uint32(TimerStateStarted), uint32(TimerStatePaused)) {
|
|
return nil
|
|
}
|
|
return G.ErrNotStarted
|
|
}
|
|
|
|
|
|
func (p *Pulsar) Continue() error {
|
|
if atomic.CompareAndSwapUint32(&p.state,uint32(TimerStatePaused), uint32(TimerStateStarted)) {
|
|
return nil
|
|
}
|
|
return G.ErrNotPaused
|
|
}
|
|
|
|
|
|
func (p *Pulsar) Done() <-chan struct{} {
|
|
return p.cancel.Done() }
|
|
|
|
|
|
func (p *Pulsar) Wait() {
|
|
<-p.cancel.Done() }
|
|
|
|
|
|
/*
|
|
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
|
|
|
I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA.
|
|
"LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS.
|
|
|
|
SIDDHARTA
|
|
- HERMANN HESSE -
|
|
|
|
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
|
|
|
*/
|