Skip to content

Commit

Permalink
added rough (almost concept) implementation of Yeet and Snag - error …
Browse files Browse the repository at this point in the history
…handling functions
  • Loading branch information
Dima Kossovich committed Oct 6, 2023
1 parent 46875e9 commit 8eba1ad
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 0 deletions.
9 changes: 9 additions & 0 deletions internal/internalpipe/pipe.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package internalpipe

import (
"math"
"unsafe"

"golang.org/x/exp/constraints"
)
Expand All @@ -17,6 +18,7 @@ type Pipe[T any] struct {
Len int
ValLim int
GoroutinesCnt int
y yeti
}

// Parallel set n - the amount of goroutines to run on.
Expand Down Expand Up @@ -58,6 +60,13 @@ func (p Pipe[T]) Count() int {
return cnt
}

// Sang ads error handler to a current Pipe step.
func (p Pipe[T]) Snag(h ErrHandler) Pipe[T] {
// FIXME: this pointer should be taken from p as the pointer to the previous Pipe step
p.y.SnagPipe(unsafe.Pointer(&p), h)
return p
}

// limit returns the upper border limit as the pipe evaluation limit.
func (p *Pipe[T]) limit() int {
switch {
Expand Down
Empty file added internal/internalpipe/snag.go
Empty file.
44 changes: 44 additions & 0 deletions internal/internalpipe/yeet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package internalpipe

import (
"sync"
"unsafe"
)

type ErrHandler func(err error)

type Yeti struct {
Errs []error
Handlers []ErrHandler
Pipe2Hdlrs map[unsafe.Pointer][]ErrHandler
EMx *sync.Mutex
HMx *sync.Mutex
}

func (y *Yeti) Yeet(err error) {
y.EMx.Lock()
y.Errs = append(y.Errs, err)
y.EMx.Unlock()
}

func (y *Yeti) Snag(handler ErrHandler) {
y.Handlers = append(y.Handlers, handler)
}

func (y *Yeti) SnagPipe(p unsafe.Pointer, h ErrHandler) {
y.HMx.Lock()
if hdlrs, ok := y.Pipe2Hdlrs[p]; ok {
y.Pipe2Hdlrs[p] = append(hdlrs, h)
} else {
// FIXME: use constant, remove else
y.Pipe2Hdlrs[p] = append(make([]ErrHandler, 0, 10), h)
}
y.HMx.Unlock()
}

type yeti interface {
Yeet(err error)
SnagPipe(p unsafe.Pointer, h ErrHandler)
// TODO: Handle should be called after each Pipe function eval
Handle(p unsafe.Pointer)
}
6 changes: 6 additions & 0 deletions pkg/pipe/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type Piper[T any] interface {

promicer[T]
eraser[Piper[any]]
snagger[Piper[T]]
}

// PiperNoLen represents methods available to a Pipe type with no length determened.
Expand All @@ -34,6 +35,7 @@ type PiperNoLen[T any] interface {
anier[T]

eraser[PiperNoLen[any]]
snagger[PiperNoLen[T]]
}

type paralleller[T, PiperT any] interface {
Expand Down Expand Up @@ -91,3 +93,7 @@ type eraser[PiperT any] interface {
type promicer[T any] interface {
Promices() []func() (T, bool)
}

type snagger[PiperT any] interface {
Snag(func(error)) PiperT
}
5 changes: 5 additions & 0 deletions pkg/pipe/pipe.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ func (p *Pipe[T]) Erase() Piper[any] {
return &Pipe[any]{p.Pipe.Erase()}
}

// Snag links an error handler to the previous Pipe method.
func (p *Pipe[T]) Snag(h func(error)) Piper[T] {
return &Pipe[T]{p.Pipe.Snag(internalpipe.ErrHandler(h))}
}

// Entrails is an out-of-Piper interface method to provide Map[T1 -> T2].
func (p *Pipe[T]) Entrails() *internalpipe.Pipe[T] {
return &p.Pipe
Expand Down
5 changes: 5 additions & 0 deletions pkg/pipe/pipenl.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ func (p *PipeNL[T]) Erase() PiperNoLen[any] {
return &PipeNL[any]{p.Pipe.Erase()}
}

// Snag links an error handler to the previous Pipe method.
func (p *PipeNL[T]) Snag(h func(error)) PiperNoLen[T] {
return &PipeNL[T]{p.Pipe.Snag(internalpipe.ErrHandler(h))}
}

// Entrails is an out of Piper interface method to provide Map[T1 -> T2].
func (p *PipeNL[T]) Entrails() *internalpipe.Pipe[T] {
return &p.Pipe
Expand Down
28 changes: 28 additions & 0 deletions pkg/pipe/yeet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package pipe

import (
"sync"

"github.com/koss-null/funcfrog/internal/internalpipe"
)

const (
initErrsAmount = 10
initHandlersAmount = 5
)

type Yeti interface {
// yeet an error
Yeet(err error)
// snag and handle the error
Snag(handler func(err error))
}

// FIXME
func Yeet() Yeti {
return &internalpipe.Yeti{
Errs: make(map[*any][]error, initErrsAmount),
Handlers: make(map[*any][]internalpipe.ErrHandler, initHandlersAmount),
Mx: &sync.Mutex{},
}
}

0 comments on commit 8eba1ad

Please sign in to comment.