From 8e5724aac1e49f9974104b166ac5c8eb76f9d447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BA=90=E6=96=87=E9=9B=A8?= <41315874+fumiama@users.noreply.github.com> Date: Tue, 1 Oct 2024 15:43:19 +0900 Subject: [PATCH] init --- errors.go | 7 +++++++ go.mod | 3 +++ job.go | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 errors.go create mode 100644 go.mod create mode 100644 job.go diff --git a/errors.go b/errors.go new file mode 100644 index 0000000..ebb780f --- /dev/null +++ b/errors.go @@ -0,0 +1,7 @@ +package slowdo + +import "errors" + +var ( + ErrWaitTimeTooShort = errors.New("wait time too short") +) diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..448bcc4 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/fumiama/slowdo + +go 1.22.1 diff --git a/job.go b/job.go new file mode 100644 index 0000000..1151e04 --- /dev/null +++ b/job.go @@ -0,0 +1,58 @@ +package slowdo + +import ( + "sync" + "time" +) + +type Job[item any] struct { + maxmait time.Duration + commit func([]item) + itemmu sync.Mutex + items []item + timer *time.Timer +} + +func NewJob[item any]( + maxwait time.Duration, commit func([]item), +) (*Job[item], error) { + if maxwait <= time.Millisecond { + return nil, ErrWaitTimeTooShort + } + return &Job[item]{ + maxmait: maxwait, + commit: commit, + }, nil +} + +func (jb *Job[item]) Add(it item) { + jb.itemmu.Lock() + defer jb.itemmu.Unlock() + if len(jb.items) == 0 { + defer jb.collect() + } + jb.items = append(jb.items, it) +} + +func (jb *Job[item]) Commit() { + jb.itemmu.Lock() + if jb.timer != nil { + jb.timer.Stop() + jb.timer = nil + } + if len(jb.items) == 0 { + jb.itemmu.Unlock() + return + } + itemscp := make([]item, len(jb.items)) + copy(itemscp, jb.items) + jb.items = jb.items[:0] + jb.itemmu.Unlock() + jb.commit(itemscp) +} + +func (jb *Job[item]) collect() { + jb.itemmu.Lock() + defer jb.itemmu.Unlock() + jb.timer = time.AfterFunc(jb.maxmait, jb.Commit) +}