test(utils): 添加事件驱动模型测试
- 在 sqrt_test.go 中添加了 fastSqr1 测试函数,用于测试事件驱动模型 - 新增了 Event 和 Uint32AsyncEvent 类型用于测试 - 更新了 go.work、go.mod 和
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
package events
|
||||
|
||||
type RequestEvent[T any] struct {
|
||||
Payload T
|
||||
Callback func() (*T, error)
|
||||
Done chan struct{}
|
||||
}
|
||||
|
||||
func NewRequestEvent[T any](payload T) *RequestEvent[T] {
|
||||
return &RequestEvent[T]{
|
||||
Payload: payload,
|
||||
Done: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
func (i *RequestEvent[T]) Async() bool {
|
||||
return true // this one is async
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package request_reply_callback
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/badu/bus/test_scenarios/request-reply-callback/orders"
|
||||
)
|
||||
|
||||
func TestRequestReplyCallback(t *testing.T) {
|
||||
var sb strings.Builder
|
||||
orders.NewRepository(&sb)
|
||||
svc := orders.NewService(&sb)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
newOrder0, err := svc.RegisterOrder(ctx, []int{1, 2, 3})
|
||||
if err != nil {
|
||||
t.Fatalf("error creating order : %#v", err)
|
||||
}
|
||||
|
||||
t.Logf("new order #0 : %#v", newOrder0)
|
||||
|
||||
newOrder1, err := svc.RegisterOrder(ctx, []int{4, 5, 6})
|
||||
if err != nil {
|
||||
t.Fatalf("error creating order : %#v", err)
|
||||
}
|
||||
|
||||
t.Logf("new order #1 : %#v", newOrder1)
|
||||
newOrder2, err := svc.RegisterOrder(ctx, []int{7, 8, 9})
|
||||
if err != nil {
|
||||
t.Fatalf("error creating order : %#v", err)
|
||||
}
|
||||
|
||||
t.Logf("new order #2 : %#v", newOrder2)
|
||||
|
||||
stat0, err := svc.GetOrderStatus(ctx, newOrder0.OrderID)
|
||||
if err != nil {
|
||||
t.Fatalf("error getting order status : %#v", err)
|
||||
}
|
||||
t.Logf("order #0 status : %s", stat0.Status)
|
||||
|
||||
stat1, err := svc.GetOrderStatus(ctx, newOrder1.OrderID)
|
||||
if err != nil {
|
||||
t.Fatalf("error getting order status : %#v", err)
|
||||
}
|
||||
|
||||
t.Logf("order #1 status : %s", stat1.Status)
|
||||
|
||||
stat2, err := svc.GetOrderStatus(ctx, newOrder2.OrderID)
|
||||
if err != nil {
|
||||
t.Fatalf("error getting order status : %#v", err)
|
||||
}
|
||||
t.Logf("order #2 status : %s", stat2.Status)
|
||||
|
||||
t.Logf("%s", sb.String())
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package orders
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/badu/bus"
|
||||
"github.com/badu/bus/test_scenarios/request-reply-callback/events"
|
||||
)
|
||||
|
||||
type Order struct {
|
||||
OrderID int
|
||||
ProductIDs []int
|
||||
}
|
||||
|
||||
type OrderStatus struct {
|
||||
OrderID int
|
||||
Status string
|
||||
}
|
||||
|
||||
type RepositoryImpl struct {
|
||||
sb *strings.Builder
|
||||
calls int
|
||||
}
|
||||
|
||||
func NewRepository(sb *strings.Builder) RepositoryImpl {
|
||||
result := RepositoryImpl{sb: sb}
|
||||
bus.Sub(result.onCreateOrder)
|
||||
bus.Sub(result.onGetOrderStatus)
|
||||
return result
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) onCreateOrder(event *events.RequestEvent[Order]) {
|
||||
defer func() { r.calls++ }()
|
||||
|
||||
<-time.After(500 * time.Millisecond) // simulate heavy database call
|
||||
|
||||
event.Callback = func() (*Order, error) {
|
||||
return &Order{OrderID: r.calls, ProductIDs: event.Payload.ProductIDs}, nil
|
||||
}
|
||||
|
||||
close(event.Done)
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) onGetOrderStatus(event *events.RequestEvent[OrderStatus]) {
|
||||
<-time.After(300 * time.Millisecond) // simulate heavy database call
|
||||
|
||||
event.Callback = func() (*OrderStatus, error) {
|
||||
status := "in_progress"
|
||||
if event.Payload.OrderID == 3 {
|
||||
status = "cancelled"
|
||||
}
|
||||
return &OrderStatus{OrderID: event.Payload.OrderID, Status: status}, nil
|
||||
}
|
||||
|
||||
close(event.Done)
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package orders
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/badu/bus"
|
||||
"github.com/badu/bus/test_scenarios/request-reply-callback/events"
|
||||
)
|
||||
|
||||
type ServiceImpl struct {
|
||||
sb *strings.Builder
|
||||
}
|
||||
|
||||
func NewService(sb *strings.Builder) ServiceImpl {
|
||||
result := ServiceImpl{sb: sb}
|
||||
return result
|
||||
}
|
||||
|
||||
func (s *ServiceImpl) RegisterOrder(ctx context.Context, productIDs []int) (*Order, error) {
|
||||
event := events.NewRequestEvent[Order](Order{ProductIDs: productIDs})
|
||||
s.sb.WriteString(fmt.Sprintf("dispatching event typed %T\n", event))
|
||||
bus.Pub(event)
|
||||
<-event.Done // wait for "reply"
|
||||
return event.Callback() // return the callback, which is containing the actual result
|
||||
}
|
||||
|
||||
func (s *ServiceImpl) GetOrderStatus(ctx context.Context, orderID int) (*OrderStatus, error) {
|
||||
event := events.NewRequestEvent[OrderStatus](OrderStatus{OrderID: orderID})
|
||||
s.sb.WriteString(fmt.Sprintf("dispatching event typed %T\n", event))
|
||||
bus.Pub(event)
|
||||
<-event.Done // wait for "reply"
|
||||
return event.Callback() // return the callback, which is containing the actual result
|
||||
}
|
||||
Reference in New Issue
Block a user