Untitled
unknown
golang
5 days ago
3.7 kB
3
Indexable
package server import ( "context" "fmt" "time" ) type Call2 struct { ConversationID string PhoneNumber string Status string } func UpdateConversationStatus(ctx context.Context, conversationID string, status string) { panic("not implemented") } func CallHandlerLoop(ctx context.Context, ccuChan chan Call2) { for { select { case <-ctx.Done(): return case call := <-ccuChan: fmt.Printf("Processing call: %s\n", call.ConversationID) } } } type CampaignState struct { CCU int cancelFuncs []context.CancelFunc callChan chan Call2 ctx context.Context } func NewCampaignState(ctx context.Context, callChan chan Call2) *CampaignState { return &CampaignState{ CCU: 0, cancelFuncs: make([]context.CancelFunc, 0), callChan: callChan, ctx: ctx, } } func (c *CampaignState) UpdateCCU() { if c.CCU > len(c.cancelFuncs) { for i := c.CCU; i < c.CCU; i++ { cancelCtx, cancel := context.WithCancel(c.ctx) go CallHandlerLoop(cancelCtx, c.callChan) c.cancelFuncs = append(c.cancelFuncs, cancel) } return } for i := len(c.cancelFuncs); i > c.CCU; i-- { lastIndex := len(c.cancelFuncs) - 1 c.cancelFuncs[lastIndex]() c.cancelFuncs = c.cancelFuncs[:lastIndex] } } func (c *CampaignState) SetCCU(newCCU int) *CampaignState { c.CCU = newCCU return c } func doesCampaignHaveCallLeft() bool { /* Campaign còn có khả năng call không, ví dụ hiện tại ko có call ready nhưng vẫn có call chờ thì return true ngược lại return false */ return true } func doesAutoCampaignHaveCallLeft() bool { /* Auto Campaign còn có khả năng call không, ví dụ hiện tại ko có call ready, tức là ko có khả năng call thì return false ngược lại return true */ return true } func getCampaignType() string { return "chiến dịch thường" } func getConversations() []Call2 { allConversations := []Call2{ { ConversationID: "1", PhoneNumber: "1234567890", Status: "pending", }, { ConversationID: "2", PhoneNumber: "0987654321", Status: "pending", }, } return allConversations } func Handle(ctx context.Context, eventChan chan string) { initCCU := 30 fixedSizeCallChan := 100 callChan := make(chan Call2, fixedSizeCallChan) campaignState := NewCampaignState(ctx, callChan) campaignState.SetCCU(initCCU).UpdateCCU() for { batchConversations := getConversations() if len(batchConversations) == 0 { switch getCampaignType() { case "chiến dịch thường": if doesCampaignHaveCallLeft() { campaignState.SetCCU(0).UpdateCCU() // Tạm thời giải phóng thread } else { return } case "chiến dịch tự động": if doesAutoCampaignHaveCallLeft() { campaignState.SetCCU(0).UpdateCCU() // Tạm thời giải phóng thread } else { return } } } // Ticker để tránh scan db liên tục khi quét conversation mà ko có cái nào delayScanDBTicker := time.After(10 * time.Second) for _, call := range batchConversations { UpdateConversationStatus(ctx, call.ConversationID, "processing") select { case event := <-eventChan: switch event { case "change-ccu-40": campaignState.SetCCU(40).UpdateCCU() case "change-ccu-20": campaignState.SetCCU(20).UpdateCCU() case "pause": campaignState.SetCCU(0).UpdateCCU() case "resume": panic("resume sẽ giống như change-ccu-40 thôi, nên ko cần implement") default: fmt.Printf("Unknown event: %s\n", event) } case campaignState.callChan <- call: continue case <-ctx.Done(): return } } <-delayScanDBTicker } }
Editor is loading...
Leave a Comment