## DEV Community

Tony Metzidis

Posted on • Updated on

# Go Nuts with Channels: Prioritize a Channel with Middleware

update Added a deadline

Channels are great because you can easily rewire them from fifos into multiplexers , funnels and fan-outs.

In this case we want to implement a priority fifo-- the P could be a TTL or value indicator.

Not much is needed, just a custom `sort.Interface` impl. based on your ordering field `P`--for priority. Then just read `inChan` into the buf, sort , and write to `outChan`

``````package main

import (
"fmt"
"math/rand"
"sort"
"time"
"strconv"
"context"
)

type PriorityStruct struct {
P    int
name string
}

const BUFSIZE = 10

type PriorityChan chan PriorityStruct
type PriorityBuf []PriorityStruct

func (s PriorityBuf) Len() int {
return len(s)
}
func (s PriorityBuf) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s PriorityBuf) Less(i, j int) bool {
return s[i].P < s[j].P
}

func Sender(pchan PriorityChan) {
for {
randNum := rand.Intn(3)
pchan <- PriorityStruct{
P:    randNum,
name: "Bob-" + strconv.Itoa(randNum),
}
time.Sleep(10 * time.Millisecond)
}
}

func Prioritize(ctx context.Context, inChan PriorityChan, outChan PriorityChan) {
for {
buf := make(PriorityBuf, BUFSIZE)
var i int
for i = range buf {
select{
case buf[i] = <-inChan:
case <-ctx.Done():
break
}
buf[i] = <-inChan
}
sort.Sort(buf)
for j:= 0; j <= i; j++ {
outChan <- buf[j]
}
}
}

func Receiver(rchan PriorityChan) {
for {
fmt.Printf("%v\n", <-rchan)
}
}

func main() {
inChan := make(PriorityChan)
outChan := make(PriorityChan)

ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(50 * time.Millisecond))
defer cancel()
go Sender(inChan)
go Receiver(outChan)
go Prioritize(ctx, inChan, outChan)
<- time.After(5 * time.Second)
}

``````

### Run it

``````go run priority-channel.go |head -n 15
{0 Bob-0}
{0 Bob-0}
{0 Bob-0}
{1 Bob-1}
{1 Bob-1}
{1 Bob-1}
{2 Bob-2}
{2 Bob-2}
{2 Bob-2}
{2 Bob-2}
{0 Bob-0}
{0 Bob-0}
{1 Bob-1}
{1 Bob-1}
{2 Bob-2}
``````

Check it out: https://play.golang.org/p/wWgi5rPcIwb

If you're not on go-nuts -- it's a good community of go-users .