package api import ( "encoding/json" "os" "time" "git.eugeniocarvalho.dev/eugeniucarvalho/apicodegen/api/errs" "git.eugeniocarvalho.dev/eugeniucarvalho/apicodegen/api/sse" context "github.com/kataras/iris/v12/context" "go.mongodb.org/mongo-driver/bson/primitive" ) type DebugStage struct { DebugEvent `json:",inline"` Events []*DebugEvent `json:"events"` } type DebugEvent struct { ID string `json:"id"` Type string `json:"type"` Status string `json:"status"` Created int64 `json:"created"` Error *errs.Error `json:"error"` Data interface{} `json:"data"` } type DebugTaks struct { ID string `json:"id"` Status string `json:"status"` Created int64 `json:"created"` Stages []*DebugStage `json:"stages"` CurrentStage *DebugStage `json:"-"` Debug *Debugger `json:"-"` } func NewDebugTaks() *DebugTaks { return &DebugTaks{ Stages: []*DebugStage{}, CurrentStage: &DebugStage{}, } } func (debug *DebugTaks) Stage(id string) *DebugStage { stage := &DebugStage{} stage.ID = id debug.CurrentStage = stage return stage } func (stage *DebugStage) PushEvent(event *DebugEvent) { stage.Events = append(stage.Events, event) } func (debug *DebugTaks) Event(eventType, eventId string) *DebugEvent { event := &DebugEvent{ ID: eventId, Type: eventType, Created: time.Now().Unix(), } debug.CurrentStage.PushEvent(event) return event } func (task *DebugTaks) Finalize() { var ( debug = task.Debug out []byte err error channel = debug.Hub.GetChannel(debug.ChannelID) ) if out, err = json.Marshal(task); err != nil { channel.Emit(&sse.Event{ Kind: "debugger.error", Payload: err.Error(), }) } else { channel.Emit(&sse.Event{ Kind: "request", Payload: string(out), }) } } type Debugger struct { ChannelID string Tasks []*DebugTaks Hub *sse.SSEHub } func (debug *Debugger) Handler() func(context.Context) { return func(ctx context.Context) { ctx.Values().Set("#debug", debug.CreateTask()) ctx.Next() } } func (debug *Debugger) CreateTask() *DebugTaks { task := &DebugTaks{ ID: primitive.NewObjectID().Hex(), Status: "", Created: time.Now().Unix(), Debug: debug, } debug.Tasks = append(debug.Tasks, task) return task } func (debug *Debugger) EventStream() func(context.Context) (interface{}, *errs.Error) { return func(ctx context.Context) (resp interface{}, err *errs.Error) { if err = debug.Hub.UpgradeConnection( ctx, debug.ChannelID, ); err != nil { return } resp = true return } } func NewDebug() *Debugger { return &Debugger{ ChannelID: "debug", Tasks: []*DebugTaks{}, Hub: sse.NewSSEHub(&sse.SSEOptions{ URI: os.Getenv("REDIS_URI"), Password: os.Getenv("REDIS_PASSWD"), ChannelCollection: "debugger", }), } }