kchan.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. // package kchan -- умный потокобезопасный канал
  2. package kchan
  3. import (
  4. "sync"
  5. "gitp78su.ipnodns.ru/svi/kern/v4/lev0/etypes/ebool"
  6. "gitp78su.ipnodns.ru/svi/kern/v4/lev0/kspec"
  7. )
  8. // KChan -- умный потокобезопасный канал
  9. //
  10. // Канал является резиновым, но лимит можно поставить сверху.
  11. // При необходимости лимит ёмкости можно поднять, но не снизить.
  12. // Умный канал можно безопасно закрывать многократно.
  13. // Умный канал можно использовать неблокирующим способом.
  14. // Умный канал точно знает своё состояние (длина, закрыт и т.п.)
  15. // При передаче инстанса канала -- из него можно только читать.
  16. // Умный канал строго типизирован и его тип видно из сигнатуры.
  17. // Кроме того, можно повесить хуки на события записи, чтения и закрытия
  18. // (например, для целей валидации).
  19. type KChan[T any] struct {
  20. block sync.RWMutex
  21. isClosed kspec.ISafeBool
  22. lstMsg []T
  23. onWrite func(T)
  24. onRead func(T)
  25. onClose func()
  26. }
  27. // NewKChan -- создаёт новый безопасный умный канал
  28. func NewKChan[T any](fnWrite func()T) *KChan[T] {
  29. sf := &KChan[T]{}
  30. return sf
  31. }
  32. // Close -- закрывает канал
  33. func (sf *KChan[T]) Close() error {
  34. if sf.block.TryLock() == false {
  35. return nil
  36. }
  37. defer sf.block.Unlock()