chore: update project structure and enhance plugin functionality
- Added new entries to .gitignore for database files. - Updated go.mod and go.sum to include new indirect dependencies for database and ORM support. - Refactored event handling to improve message reply functionality in the protocol. - Enhanced the dispatcher to allow for better event processing and logging. - Removed outdated plugin documentation and unnecessary files to streamline the codebase. - Improved welcome message formatting and screenshot options for better user experience.
This commit is contained in:
@@ -33,41 +33,26 @@ type Dispatcher struct {
|
||||
scheduler *Scheduler
|
||||
metrics DispatcherMetrics
|
||||
mu sync.RWMutex
|
||||
workerPool chan struct{} // 工作池,限制并发数
|
||||
maxWorkers int
|
||||
async bool // 是否异步处理
|
||||
totalTime int64 // 总处理时间(纳秒)
|
||||
}
|
||||
|
||||
// NewDispatcher 创建事件分发器
|
||||
func NewDispatcher(eventBus *EventBus, logger *zap.Logger) *Dispatcher {
|
||||
return NewDispatcherWithConfig(eventBus, logger, 100, true)
|
||||
}
|
||||
|
||||
// NewDispatcherWithScheduler 创建带调度器的事件分发器
|
||||
func NewDispatcherWithScheduler(eventBus *EventBus, logger *zap.Logger, scheduler *Scheduler) *Dispatcher {
|
||||
dispatcher := NewDispatcherWithConfig(eventBus, logger, 100, true)
|
||||
dispatcher.scheduler = scheduler
|
||||
return dispatcher
|
||||
}
|
||||
|
||||
// NewDispatcherWithConfig 使用配置创建事件分发器
|
||||
func NewDispatcherWithConfig(eventBus *EventBus, logger *zap.Logger, maxWorkers int, async bool) *Dispatcher {
|
||||
if maxWorkers <= 0 {
|
||||
maxWorkers = 100
|
||||
}
|
||||
|
||||
return &Dispatcher{
|
||||
handlers: make([]protocol.EventHandler, 0),
|
||||
middlewares: make([]protocol.Middleware, 0),
|
||||
logger: logger.Named("dispatcher"),
|
||||
eventBus: eventBus,
|
||||
workerPool: make(chan struct{}, maxWorkers),
|
||||
maxWorkers: maxWorkers,
|
||||
async: async,
|
||||
}
|
||||
}
|
||||
|
||||
// NewDispatcherWithScheduler 创建带调度器的事件分发器
|
||||
func NewDispatcherWithScheduler(eventBus *EventBus, logger *zap.Logger, scheduler *Scheduler) *Dispatcher {
|
||||
dispatcher := NewDispatcher(eventBus, logger)
|
||||
dispatcher.scheduler = scheduler
|
||||
return dispatcher
|
||||
}
|
||||
|
||||
// RegisterHandler 注册事件处理器
|
||||
func (d *Dispatcher) RegisterHandler(handler protocol.EventHandler) {
|
||||
d.mu.Lock()
|
||||
@@ -155,29 +140,42 @@ func (d *Dispatcher) GetScheduler() *Scheduler {
|
||||
|
||||
// eventLoop 事件循环
|
||||
func (d *Dispatcher) eventLoop(ctx context.Context, eventChan chan protocol.Event) {
|
||||
// 使用独立的 context,避免应用关闭时取消正在处理的事件
|
||||
// 即使应用关闭,也要让正在处理的事件完成
|
||||
shutdown := false
|
||||
|
||||
for {
|
||||
select {
|
||||
case event, ok := <-eventChan:
|
||||
if !ok {
|
||||
d.logger.Info("Event channel closed, stopping event loop")
|
||||
return
|
||||
}
|
||||
|
||||
if d.IsAsync() {
|
||||
// 异步处理,使用工作池限制并发
|
||||
d.workerPool <- struct{}{} // 获取工作槽位
|
||||
go func(e protocol.Event) {
|
||||
defer func() {
|
||||
<-d.workerPool // 释放工作槽位
|
||||
}()
|
||||
d.handleEvent(ctx, e)
|
||||
}(event)
|
||||
} else {
|
||||
// 同步处理
|
||||
d.handleEvent(ctx, event)
|
||||
}
|
||||
d.logger.Debug("Event received in eventLoop",
|
||||
zap.String("type", string(event.GetType())),
|
||||
zap.String("detail_type", event.GetDetailType()),
|
||||
zap.String("self_id", event.GetSelfID()),
|
||||
zap.Bool("shutdown", shutdown))
|
||||
|
||||
// 为每个事件创建独立的 context,避免应用关闭时取消正在处理的事件
|
||||
// 使用独立的 context,允许处理完成
|
||||
handlerCtx, handlerCancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
||||
|
||||
// 直接使用 goroutine 处理事件,Go 的调度器会自动管理
|
||||
go func(e protocol.Event) {
|
||||
defer handlerCancel()
|
||||
d.handleEvent(handlerCtx, e)
|
||||
}(event)
|
||||
|
||||
case <-ctx.Done():
|
||||
return
|
||||
// 当应用关闭时,标记为关闭状态,但继续处理 channel 中的事件
|
||||
if !shutdown {
|
||||
d.logger.Info("Context cancelled, will continue processing events until channel closes")
|
||||
shutdown = true
|
||||
}
|
||||
// 继续处理 channel 中的事件,直到 channel 关闭
|
||||
// 不再检查 ctx.Done(),只等待 channel 关闭
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -347,17 +345,3 @@ func (d *Dispatcher) LogMetrics() {
|
||||
zap.Int("handler_count", d.GetHandlerCount()),
|
||||
zap.Int("middleware_count", d.GetMiddlewareCount()))
|
||||
}
|
||||
|
||||
// SetAsync 设置是否异步处理
|
||||
func (d *Dispatcher) SetAsync(async bool) {
|
||||
d.mu.Lock()
|
||||
defer d.mu.Unlock()
|
||||
d.async = async
|
||||
}
|
||||
|
||||
// IsAsync 是否异步处理
|
||||
func (d *Dispatcher) IsAsync() bool {
|
||||
d.mu.RLock()
|
||||
defer d.mu.RUnlock()
|
||||
return d.async
|
||||
}
|
||||
|
||||
@@ -243,7 +243,16 @@ func (eb *EventBus) dispatchEvent(event protocol.Event) {
|
||||
atomic.AddInt64(&eb.metrics.DroppedTotal, 1)
|
||||
eb.logger.Warn("Subscription channel full, event dropped",
|
||||
zap.String("sub_id", sub.ID),
|
||||
zap.String("event_type", key))
|
||||
zap.String("event_type", key),
|
||||
zap.String("detail_type", event.GetDetailType()),
|
||||
zap.String("raw_message", func() string {
|
||||
if data := event.GetData(); data != nil {
|
||||
if msg, ok := data["raw_message"].(string); ok {
|
||||
return msg
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user