Explorar el Código

SVI Исправления, добавление умного канала

SVI hace 5 meses
padre
commit
23ed28756f

+ 8 - 3
v4/lev0/etypes/ebool/ebool.go

@@ -29,9 +29,14 @@ func NewEBoolMut(val bool) mKs.EBoolMut {
 	return sf
 }
 
-// Get -- возвращает хранимое значение.
-func (sf *EBool) Get() bool {
-	return sf.val
+// IsNot -- проверяет на false.
+func (sf *EBool) IsNot() bool {
+	return sf.val == false
+}
+
+// IsOk -- проверяет на true.
+func (sf *EBool) IsOk() bool {
+	return sf.val == true
 }
 
 // IsMut -- возвращает признак мутабельности.

+ 4 - 3
v4/lev0/kspec/ebool.go

@@ -2,9 +2,10 @@ package kspec
 
 // EBool -- расширенный бул.
 type EBool interface {
-	// Get -- возвращает булево.
-	Get() bool
-	// IsMut -- возвращает признак мутабельности.
+	// IsOk -- проверяет на true.
+	IsOk() bool
+	// IsNot -- проверяет на false.
+	IsNot() bool
 }
 
 // EBoolMut -- мутабельный расширенный бул.

+ 2 - 0
v4/lev1/dob/dob.go

@@ -0,0 +1,2 @@
+// package dob -- Data object of business logic
+package dob

+ 2 - 0
v4/lev1/dos/dos.go

@@ -0,0 +1,2 @@
+// package dos -- Data object of storage
+package dos

+ 2 - 0
v4/lev1/dot/dot.go

@@ -0,0 +1,2 @@
+// package dot -- Data object of transport
+package dot

+ 3 - 3
v4/lev1/safe_bool_react/safe_bool_react_test.go

@@ -108,7 +108,7 @@ func (sf *tester) del() {
 	sf.sbr.Delete("test")
 	sf.val.Reset()
 	sf.sbr.Set()
-	if sf.val.Get() {
+	if sf.val.IsOk() {
 		sf.t.Fatalf("del(): val==true")
 	}
 }
@@ -136,7 +136,7 @@ func (sf *tester) reset() {
 	if sf.sbr.Get() {
 		sf.t.Fatalf("reset(): SafeBool==true")
 	}
-	if sf.val.Get() {
+	if sf.val.IsOk() {
 		sf.t.Fatalf("reset(): val==true")
 	}
 }
@@ -152,7 +152,7 @@ func (sf *tester) set() {
 	if !sf.sbr.Get() {
 		sf.t.Fatalf("set(): SafeBool==true")
 	}
-	if !sf.val.Get() {
+	if sf.val.IsNot() {
 		sf.t.Fatalf("set(): val==false")
 	}
 }

+ 1 - 1
v4/lev2/kbus/dict_sub_hook/dict_sub_hook.go

@@ -45,7 +45,7 @@ func (sf *dictSubHook) Subscribe(handler mKs.IBusHandlerSubscribe) {
 	defer sf.block.Unlock()
 	mL0.Hassert(handler != nil, "dictSubHook.Subscribe(): handler==nil")
 	handlerName := handler.Name()
-	sf.dict[handlerName] = true
+	sf.dict[handlerName] = struct{}{}
 	sf.kCtx.Set(handlerName.Get(), handler, "subscribe handler")
 }
 

+ 2 - 2
v4/lev2/kbus_base/kbus_base_test.go

@@ -150,7 +150,7 @@ func (sf *tester) close() {
 	kCtx.Cancel()
 	kCtx.Wg().Wait()
 	sf.kBus.(*KBusBase).close()
-	if sf.kBus.IsWork().Get() {
+	if sf.kBus.IsWork().IsOk() {
 		sf.t.Fatalf("close(): bus work")
 	}
 	res := sf.kBus.Subscribe(sf.handSub)
@@ -176,7 +176,7 @@ func (sf *tester) newGood1() {
 	}()
 	sf.kBus = GetKernelBusBase()
 	sf.kBus = GetKernelBusBase()
-	if !sf.kBus.IsWork().Get() {
+	if sf.kBus.IsWork().IsNot() {
 		sf.t.Fatalf("newGood1(): bus not work")
 	}
 	if log := sf.kBus.Log(); log == nil {

+ 17 - 16
v4/lev2/kbus_http/client_bus_http/client_bus_http.go

@@ -12,6 +12,7 @@ import (
 
 	mL0 "gitp78su.ipnodns.ru/svi/kern/v4/lev0"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/topic"
+	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/etypes/ebool"
 	mKs "gitp78su.ipnodns.ru/svi/kern/v4/lev0/kspec"
 	mL1 "gitp78su.ipnodns.ru/svi/kern/v4/lev1"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev1/kbus_msg/msg_pub"
@@ -53,7 +54,7 @@ func NewClientBusHttp(urlRemote string) mKs.IBusClient {
 		lCtx:      mL1.NewLocalCtx(kCtx.Ctx()),
 		log:       log,
 		bus:       kBusHttp,
-		isWork:    mL1.NewSafeBool(),
+		isWork:    mL1.NewSafeBool(true),
 		urlRemote: strings.TrimSuffix(urlRemote, "/"),
 		urlLocal:  strings.TrimSuffix(urlLocal.Get(), "/"),
 	}
@@ -96,7 +97,7 @@ func (sf *ClientBusHttp) Unsubscribe(handler mKs.IBusHandlerSubscribe) {
 }
 
 // Subscribe -- подписывается на топик в дистанционной шине.
-func (sf *ClientBusHttp) Subscribe(handler mKs.IBusHandlerSubscribe) mKs.IResult[bool] {
+func (sf *ClientBusHttp) Subscribe(handler mKs.IBusHandlerSubscribe) mKs.IResult[mKs.EBool] {
 	_uuid, err := uuid.NewV6()
 	mL0.Hassert(err == nil, "ClientBusHttp.Subscribe(): in generate UUID v6, err=\n\t%v", err)
 	req := &msg_sub.SubscribeReq{
@@ -114,21 +115,21 @@ func (sf *ClientBusHttp) Subscribe(handler mKs.IBusHandlerSubscribe) mKs.IResult
 	resBody := sf.makePost(hReq)
 	if resBody.IsErr() {
 		err := fmt.Errorf("ClientBusHttp.Subscribe(): in make POST-request, err=\n\t%w", err)
-		return mL0.NewErr[bool](err)
+		return mL0.NewErr[mKs.EBool](err)
 	}
 	resp := &msg_sub.SubscribeResp{}
 	err = json.Unmarshal(resBody.Ok(), resp)
 	if err != nil {
 		err := fmt.Errorf("ClientBusHttp.Subscribe(): in unmarshal response, err=\n\t%v", err)
-		return mL0.NewErr[bool](err)
+		return mL0.NewErr[mKs.EBool](err)
 	}
 	if resp.Status_ != "ok" {
 		err := fmt.Errorf("ClientBusHttp.Subscribe(): resp!='ok', err=\n\t%v", resp.Status_)
-		return mL0.NewErr[bool](err)
+		return mL0.NewErr[mKs.EBool](err)
 	}
 	if resp.Uuid_ != req.Uuid_ {
 		err := fmt.Errorf("ClientBusHttp.Subscribe(): resp uuid(%v) bad", resp.Uuid_)
-		return mL0.NewErr[bool](err)
+		return mL0.NewErr[mKs.EBool](err)
 	}
 	res := sf.bus.Subscribe(handler)
 	return res
@@ -173,20 +174,20 @@ func (sf *ClientBusHttp) SendRequest(topic *topic.ATopic, binReq []byte) mL0.IRe
 }
 
 // RegisterServe -- регистрирует в локальной шине обработчик.
-func (sf *ClientBusHttp) RegisterServe(handler mKs.IBusHandlerServe) mL0.IResult[bool] {
+func (sf *ClientBusHttp) RegisterServe(handler mKs.IBusHandlerServe) mL0.IResult[mKs.EBool] {
 	if handler == nil {
-		return mL0.NewErr[bool](fmt.Errorf("ClientBusHttp.RegisterServe(): handler==nil"))
+		return mL0.NewErr[mKs.EBool](fmt.Errorf("ClientBusHttp.RegisterServe(): handler==nil"))
 	}
 	res := sf.bus.RegisterServe(handler)
 	if res.IsErr() {
 		err := fmt.Errorf("ClientBusHttp.RegisterServe(): in register serve to bus, err=\n\t%v", res.Err())
-		return mL0.NewErr[bool](err)
+		return mL0.NewErr[mKs.EBool](err)
 	}
-	return mL0.NewOk(true)
+	return mL0.NewOk(ebool.NewEBool(true))
 }
 
 // Publish -- публикует сообщение в дистанционной шину.
-func (sf *ClientBusHttp) Publish(topic *topic.ATopic, binMsg []byte) mL0.IResult[bool] {
+func (sf *ClientBusHttp) Publish(topic *topic.ATopic, binMsg []byte) mL0.IResult[mKs.EBool] {
 	_uuid, err := uuid.NewV6()
 	mL1.Hassert()(err == nil, "ClientBusHttp.Publish(): in generate UUID v6, err=\n\t%v", err)
 	req := &msg_pub.PublishReq{
@@ -204,23 +205,23 @@ func (sf *ClientBusHttp) Publish(topic *topic.ATopic, binMsg []byte) mL0.IResult
 	resBody := sf.makePost(hReq)
 	if resBody.IsErr() {
 		err := fmt.Errorf("ClientBusHttp.Publish(): in make request, err=\n\t%w", err)
-		return mL0.NewErr[bool](err)
+		return mL0.NewErr[mKs.EBool](err)
 	}
 	resp := &msg_pub.PublishResp{}
 	err = json.Unmarshal(resBody.Ok(), resp)
 	if err != nil {
 		err := fmt.Errorf("ClientBusHttp.Publish(): in unmarshal response, err=\n\t%v", err)
-		return mL0.NewErr[bool](err)
+		return mL0.NewErr[mKs.EBool](err)
 	}
 	if resp.Status_ != "ok" {
 		err := fmt.Errorf("ClientBusHttp.Publish(): resp!='ok', err=\n\t%v", resp.Status_)
-		return mL0.NewErr[bool](err)
+		return mL0.NewErr[mKs.EBool](err)
 	}
 	if resp.Uuid_ != req.Uuid_ {
 		err := fmt.Errorf("ClientBusHttp.Publish(): resp uuid(%v) bad", resp.Uuid_)
-		return mL0.NewErr[bool](err)
+		return mL0.NewErr[mKs.EBool](err)
 	}
-	return mL0.NewOk(true)
+	return mL0.NewOk(ebool.NewEBool(true))
 }
 
 // Единый обработчик запросов.

+ 1 - 1
v4/lev2/kbus_http/client_bus_http/client_bus_http_test.go

@@ -398,7 +398,7 @@ func (sf *tester) newGood1() {
 	if log := sf.cl.Log(); log == nil {
 		sf.t.Fatalf("newGood1(): log==nil")
 	}
-	if isWork := sf.cl.IsWork(); !isWork {
+	if isWork := sf.cl.IsWork(); isWork.IsNot() {
 		sf.t.Fatalf("newGood1(): isWork==false")
 	}
 }

+ 6 - 1
v4/lev2/kbus_http/kbus_http.go

@@ -14,6 +14,7 @@ import (
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev1/kbus_msg/msg_serve"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev1/kbus_msg/msg_sub"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev1/kbus_msg/msg_unsub"
+	"gitp78su.ipnodns.ru/svi/kern/v4/lev1/safe_bool"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev2/kbus_base"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev2/kctx"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev2/kserv_http"
@@ -38,7 +39,11 @@ func GetKernelBusHttp() mKs.IKernelBus {
 	if Bus_ != nil {
 		return Bus_
 	}
-	log := mL1.NewLogBuf(mL1.OptIsTerm(true), mL1.OptPrefix("kBusHttp"))
+	paramLogBuf := &mL1.LogBufParam{
+		IsTerm_: safe_bool.NewSafeBool(true),
+		Prefix_: "kBusHttp",
+	}
+	log := mL1.NewLogBuf(paramLogBuf)
 	log.Debug("GetKernelBusHttp(): new")
 	kCtx := kctx.GetKernelCtx()
 	kBus := kbus_base.GetKernelBusBase()

+ 1 - 1
v4/lev2/kbus_local/kbus_local_test.go

@@ -49,7 +49,7 @@ func (sf *tester) newGood1() {
 	if sf.lBus == nil {
 		sf.t.Fatalf("newGood1(): IKernelBus==nil")
 	}
-	if !sf.lBus.IsWork() {
+	if sf.lBus.IsWork().IsNot() {
 		sf.t.Fatalf("newGood1(): bus not work")
 	}
 }

+ 42 - 0
v4/lev2/kchan/kchan.go

@@ -0,0 +1,42 @@
+// package kchan -- умный потокобезопасный канал
+package kchan
+
+import (
+	"sync"
+
+	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/etypes/ebool"
+	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/kspec"
+)
+
+// KChan -- умный потокобезопасный канал
+//
+// Канал является резиновым, но лимит можно поставить сверху.
+// При необходимости лимит ёмкости можно поднять, но не снизить.
+// Умный канал можно безопасно закрывать многократно.
+// Умный канал можно использовать неблокирующим способом.
+// Умный канал точно знает своё состояние (длина, закрыт и т.п.)
+// При передаче инстанса канала -- из него можно только читать.
+// Умный канал строго типизирован и его тип видно из сигнатуры.
+// Кроме того, можно повесить хуки на события записи, чтения и закрытия
+// (например, для целей валидации).
+type KChan[T any] struct {
+	block sync.RWMutex
+	isClosed kspec.ISafeBool
+	lstMsg []T
+	onWrite func(T)
+	onRead  func(T)
+	onClose func()
+}
+
+// NewKChan -- создаёт новый безопасный умный канал
+func NewKChan[T any](fnWrite func()T) *KChan[T] {
+	sf := &KChan[T]{}
+	return sf
+}
+
+// Close -- закрывает канал
+func (sf *KChan[T]) Close() error {
+	if sf.block.TryLock() == false {
+		return nil
+	}
+	defer sf.block.Unlock()

+ 8 - 1
v4/lev2/kernel_keeper/kernel_keeper.go

@@ -12,6 +12,7 @@ import (
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/stream_name"
 	mKs "gitp78su.ipnodns.ru/svi/kern/v4/lev0/kspec"
 	mL1 "gitp78su.ipnodns.ru/svi/kern/v4/lev1"
+	"gitp78su.ipnodns.ru/svi/kern/v4/lev1/safe_bool"
 )
 
 // kernelKeeper -- сторож системных сигналов.
@@ -41,11 +42,17 @@ func GetKernelKeeper(ctx context.Context, fnCancel func(),
 	mL0.Hassert(ctx != nil, "NewKernelCtx(): ctx==nil")
 	mL0.Hassert(wg != nil, "NewKernelCtx(): IKernelWg==nil")
 	mL0.Hassert(fnCancel != nil, "NewKernelCtx(): fnCancel==nil")
+
+	paramLogBuf := &mL1.LogBufParam{
+		IsTerm_: safe_bool.NewSafeBool(true),
+		Prefix_: "kernelKeeper",
+	}
+
 	sf := &kernelKeeper{
 		ctx:      ctx,
 		fnCancel: fnCancel,
 		wg:       wg,
-		log:      mL1.NewLogBuf(mL1.OptIsTerm(true), mL1.OptPrefix("kernelKeeper")),
+		log:      mL1.NewLogBuf(paramLogBuf),
 		chSys_:   make(chan os.Signal, 2),
 	}
 	sf.log.Debug("GetKernelKeeper(): first run")

+ 3 - 2
v4/lev2/kmodule/kmodule.go

@@ -7,6 +7,7 @@ import (
 	mL0 "gitp78su.ipnodns.ru/svi/kern/v4/lev0"
 	mKd "gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/module_name"
+	"gitp78su.ipnodns.ru/svi/kern/v4/lev0/etypes/ebool"
 	mKs "gitp78su.ipnodns.ru/svi/kern/v4/lev0/kspec"
 	mL1 "gitp78su.ipnodns.ru/svi/kern/v4/lev1"
 	"gitp78su.ipnodns.ru/svi/kern/v4/lev2/kbus_local"
@@ -68,9 +69,9 @@ func (sf *kModule) Name() *module_name.AModuleName {
 }
 
 // IsWork -- возвращает признак состояния работы.
-func (sf *kModule) IsWork() bool {
+func (sf *kModule) IsWork() mKs.EBool {
 	mL0.Hassert(false, "kModule.IsWork(): module='%v', parent not realized this method", sf.name)
-	return false
+	return ebool.NewEBool(false)
 }
 
 // Live -- возвращает индикатор жизни модуля.

+ 1 - 1
v4/lev2/kserv_http/kserv_http_test.go

@@ -38,7 +38,7 @@ func (sf *tester) close() {
 	sf.kCtx.Cancel()
 	sf.wg.Wait()
 	kernServHttp.close()
-	if kernServHttp.IsWork() {
+	if kernServHttp.IsWork().IsOk() {
 		sf.t.Fatalf("close(): isWork==true")
 	}
 	kernServHttp.Run()

+ 1 - 1
v4/lev2/kstore_kv/kstore_kv.go

@@ -60,7 +60,7 @@ func GetKernelStore() mKs.IKernelStoreKv {
 		kCtx:   kCtx,
 		lCtx:   mL1.NewLocalCtx(kCtx.Ctx()),
 		wg:     kCtx.Wg(),
-		isWork: mL1.NewSafeBool(),
+		isWork: mL1.NewSafeBool(true),
 		log:    log,
 	}
 	sf.open()

+ 1 - 1
v4/lev2/kwg/kwg.go

@@ -48,7 +48,7 @@ func GetKernelWg(ctx context.Context) mKs.IKernelWg {
 	sf := &kernelWg{
 		ctx:        ctx,
 		dictStream: map[*stream_name.AStreamName]bool{},
-		isWork:     mL1.NewSafeBool(),
+		isWork:     mL1.NewSafeBool(false),
 		log:        mL1.NewLogBuf(paramLogBuf),
 	}
 	sf.log.Debug("GetKernelWg(): run")

+ 2 - 0
v4/lev2/lbi/lbi.go

@@ -0,0 +1,2 @@
+// package lbi -- слой интерфейса бизнес-логики
+package lbi

+ 2 - 0
v4/lev2/lsi/lsi.go

@@ -0,0 +1,2 @@
+// package lsi -- слой интерфейсов хранилищ
+package lsi

+ 2 - 0
v4/lev2/lti/lti.go

@@ -0,0 +1,2 @@
+// package lti -- слой интерфейсов транспортов
+package lti