Untitled

 avatar
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