Untitled
unknown
golang
8 months ago
3.7 kB
6
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