github.com/ethersphere/bee/v2@v2.2.0/pkg/storageincentives/events.go (about)

     1  // Copyright 2022 The Swarm Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package storageincentives
     6  
     7  import (
     8  	"context"
     9  	"sync"
    10  )
    11  
    12  type PhaseType int
    13  
    14  const (
    15  	commit PhaseType = iota + 1
    16  	reveal
    17  	claim
    18  	sample
    19  )
    20  
    21  func (p PhaseType) String() string {
    22  	switch p {
    23  	case commit:
    24  		return "commit"
    25  	case reveal:
    26  		return "reveal"
    27  	case claim:
    28  		return "claim"
    29  	case sample:
    30  		return "sample"
    31  	default:
    32  		return "unknown"
    33  	}
    34  }
    35  
    36  type events struct {
    37  	mtx sync.Mutex
    38  	ev  map[PhaseType]*event
    39  }
    40  
    41  type event struct {
    42  	funcs  []func(context.Context)
    43  	ctx    context.Context
    44  	cancel context.CancelFunc
    45  }
    46  
    47  func newEvents() *events {
    48  	return &events{
    49  		ev: make(map[PhaseType]*event),
    50  	}
    51  }
    52  
    53  func (e *events) On(phase PhaseType, f func(context.Context)) {
    54  	e.mtx.Lock()
    55  	defer e.mtx.Unlock()
    56  
    57  	if _, ok := e.ev[phase]; !ok {
    58  		ctx, cancel := context.WithCancel(context.Background())
    59  		e.ev[phase] = &event{ctx: ctx, cancel: cancel}
    60  	}
    61  
    62  	e.ev[phase].funcs = append(e.ev[phase].funcs, f)
    63  }
    64  
    65  func (e *events) Publish(phase PhaseType) {
    66  	e.mtx.Lock()
    67  	defer e.mtx.Unlock()
    68  
    69  	if ev, ok := e.ev[phase]; ok {
    70  		for _, v := range ev.funcs {
    71  			go v(ev.ctx)
    72  		}
    73  	}
    74  }
    75  
    76  func (e *events) Cancel(phases ...PhaseType) {
    77  	e.mtx.Lock()
    78  	defer e.mtx.Unlock()
    79  
    80  	for _, phase := range phases {
    81  		if ev, ok := e.ev[phase]; ok {
    82  			ev.cancel()
    83  			ctx, cancel := context.WithCancel(context.Background())
    84  			ev.ctx = ctx
    85  			ev.cancel = cancel
    86  		}
    87  	}
    88  }
    89  
    90  func (e *events) Close() {
    91  	e.mtx.Lock()
    92  	defer e.mtx.Unlock()
    93  
    94  	for k, ev := range e.ev {
    95  		ev.cancel()
    96  		delete(e.ev, k)
    97  	}
    98  }