How to do it...

These steps cover writing and running your application:

  1. From your Terminal or console application, create a new directory called ~/projects/go-programming-cookbook/chapter10/pipeline and navigate to it.
  2. Run the following command:
$ go mod init github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter10/pipeline

You should see a file called go.mod that contains the following content:

module github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter10/pipeline    
  1. Copy the tests from ~/projects/go-programming-cookbook-original/chapter10/pipeline, or use this as an opportunity to write some of your own code!
  2. Create a file called worker.go with the following content:
        package pipeline

import "context"

// Worker have one role
// that is determined when
// Work is called
type Worker struct {
in chan string
out chan string
}

// Job is a job a worker can do
type Job string

const (
// Print echo's all input to
// stdout
Print Job = "print"
// Encode base64 encodes input
Encode Job = "encode"
)

// Work is how to dispatch a worker, they are assigned
// a job here
func (w *Worker) Work(ctx context.Context, j Job) {
switch j {
case Print:
w.Print(ctx)
case Encode:
w.Encode(ctx)
default:
return
}
}
  1. Create a file called print.go with the following content:
        package pipeline

import (
"context"
"fmt"
)

// Print prints w.in and repalys it
// on w.out
func (w *Worker) Print(ctx context.Context) {
for {
select {
case <-ctx.Done():
return
case val := <-w.in:
fmt.Println(val)
w.out <- val
}
}
}
  1. Create a file called encode.go with the following content:
        package pipeline

import (
"context"
"encoding/base64"
"fmt"
)

// Encode takes plain text as int
// and returns "string => <base64 string encoding>
// as out
func (w *Worker) Encode(ctx context.Context) {
for {
select {
case <-ctx.Done():
return
case val := <-w.in:
w.out <- fmt.Sprintf("%s => %s", val,
base64.StdEncoding.EncodeToString([]byte(val)))
}
}
}
  1. Create a file called pipeline.go with the following content:
        package pipeline

import "context"

// NewPipeline initializes the workers and
// connects them, it returns the input of the pipeline
// and the final output
func NewPipeline(ctx context.Context, numEncoders, numPrinters
int) (chan string, chan string) {
inEncode := make(chan string, numEncoders)
inPrint := make(chan string, numPrinters)
outPrint := make(chan string, numPrinters)
for i := 0; i < numEncoders; i++ {
w := Worker{
in: inEncode,
out: inPrint,
}
go w.Work(ctx, Encode)
}

for i := 0; i < numPrinters; i++ {
w := Worker{
in: inPrint,
out: outPrint,
}
go w.Work(ctx, Print)
}
return inEncode, outPrint
}
  1. Create a new directory named example and navigate to it.
  2. Create a file named main.go with the following content:
        package main

import (
"context"
"fmt"

"github.com/PacktPublishing/
Go-Programming-Cookbook-Second-Edition/
chapter10/pipeline"
)

func main() {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()

in, out := pipeline.NewPipeline(ctx, 10, 2)

go func() {
for i := 0; i < 20; i++ {
in <- fmt.Sprint("Message", i)
}
}()

for i := 0; i < 20; i++ {
<-out
}
}
  1. Run go run main.go.
  2. You may also run the following commands:
$ go build
$ ./example

You should now see the following output:

$ go run main.go
Message3 => TWVzc2FnZTM=
Message7 => TWVzc2FnZTc=
Message8 => TWVzc2FnZTg=
Message9 => TWVzc2FnZTk=
Message5 => TWVzc2FnZTU=
Message11 => TWVzc2FnZTEx
Message10 => TWVzc2FnZTEw
Message4 => TWVzc2FnZTQ=
Message12 => TWVzc2FnZTEy
Message6 => TWVzc2FnZTY=
Message14 => TWVzc2FnZTE0
Message13 => TWVzc2FnZTEz
Message0 => TWVzc2FnZTA=
Message15 => TWVzc2FnZTE1
Message1 => TWVzc2FnZTE=
Message17 => TWVzc2FnZTE3
Message16 => TWVzc2FnZTE2
Message19 => TWVzc2FnZTE5
Message18 => TWVzc2FnZTE4
Message2 => TWVzc2FnZTI=
  1. The go.mod file may be updated and the go.sum file should now be present in the top-level recipe directory.
  2. If you copied or wrote your own tests, go up one directory and run go test. Ensure that all the tests pass.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.128.199.162