aregm / nff-go

NFF-Go -Network Function Framework for GO (former YANFF)
BSD 3-Clause "New" or "Revised" License
1.38k stars 156 forks source link

QoS queueing example #646

Open zartbot opened 5 years ago

zartbot commented 5 years ago

Is there any qos queueing example ? which container can we use in packet handler to get packet store in queue, and how to dequeue ? go chan ? or container/ring ?

gshimansky commented 5 years ago

No we don't currently have an example on QoS.

You can implement a queue in Go either using an array or a linked list like it is done in this example https://yourbasic.org/golang/implement-fifo-queue/

There is also a Heap package which could be used to implement priority queue, check this example for reference https://golang.org/pkg/container/heap/#example__priorityQueue

zartbot commented 5 years ago

Hi

I find some problem on create flows

The flow chart is just like Port1 --->flow:p1in----> Queue ,

    //Port1--> Port2: enQueue
    p1in, _ := flow.SetReceiver(uint16(*Port1))
    flow.CheckFatal(flow.SetHandler(p1in, enQueue, nil))
    flow.SetStopper(p1in)

func enQueue(pkt *packet.Packet, context flow.UserContext) {
    pktQueue.Lock.Lock()
    pktQueue.Queue = append(pktQueue.Queue, pkt)
    pktQueue.Lock.Unlock()
}

but how to write the deQueue part ? Queue-->flow:p1out--->Port2

    //Port1--> Port2: deQueue
    p1out := flow.SetGenerator(deQueue, nil)
    flow.CheckFatal(flow.SetSender(p1out, uint16(*Port2)))

func deQueue(pkt *packet.Packet, context flow.UserContext) {
    pktQueue.Lock.Lock()
    if len(pktQueue.Queue) > 0 {
        pktQueue.Queue = pktQueue.Queue[1:]
    }
    pktQueue.Lock.Unlock()
}

but it seems does not work. with soem print debug on deQueue function , I could saw the packet. but seems does not send out.

zartbot commented 5 years ago

is possible to add a new Flow type like


func SetTXRing(f GenerateFunction, context UserContext) (OUT *Flow, Rings low.Rings) {
    rings := low.CreateRings(burstSize*sizeMultiplier, 1)
    return newFlow(rings, 1), rings
}

p1out,p1rings := flow.SetTXRing(enqueue, ctx)

Then we can have another goroutine to get packet and execute

func enqueue(){
C.rte_ring_sp_enqueue(p1ring , pkt)
}