These steps cover writing and running your application:
- From your Terminal or console application, create a new directory called ~/projects/go-programming-cookbook/chapter10/state and navigate to it.
- Run the following command:
$ go mod init github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter10/state
You should see a file called go.mod that contains the following content:
module github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter10/state
- Copy the tests from ~/projects/go-programming-cookbook-original/chapter10/state, or use this as an opportunity to write some of your own code!
- Create a file called state.go with the following content:
package state
type op string
const (
// Add values
Add op = "add"
// Subtract values
Subtract = "sub"
// Multiply values
Multiply = "mult"
// Divide values
Divide = "div"
)
// WorkRequest perform an op
// on two values
type WorkRequest struct {
Operation op
Value1 int64
Value2 int64
}
// WorkResponse returns the result
// and any errors
type WorkResponse struct {
Wr *WorkRequest
Result int64
Err error
}
- Create a file called processor.go with the following content:
package state
import "context"
// Processor routes work to Process
func Processor(ctx context.Context, in chan *WorkRequest, out
chan *WorkResponse) {
for {
select {
case <-ctx.Done():
return
case wr := <-in:
out <- Process(wr)
}
}
}
- Create a file called process.go with the following content:
package state
import "errors"
// Process switches on operation type
// Then does work
func Process(wr *WorkRequest) *WorkResponse {
resp := WorkResponse{Wr: wr}
switch wr.Operation {
case Add:
resp.Result = wr.Value1 + wr.Value2
case Subtract:
resp.Result = wr.Value1 - wr.Value2
case Multiply:
resp.Result = wr.Value1 * wr.Value2
case Divide:
if wr.Value2 == 0 {
resp.Err = errors.New("divide by 0")
break
}
resp.Result = wr.Value1 / wr.Value2
default:
resp.Err = errors.New("unsupported operation")
}
return &resp
}
- Create a new directory named example and navigate to it.
- Create a file named main.go with the following content:
package main
import (
"context"
"fmt"
"github.com/PacktPublishing/
Go-Programming-Cookbook-Second-Edition/
chapter10/state"
)
func main() {
in := make(chan *state.WorkRequest, 10)
out := make(chan *state.WorkResponse, 10)
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
go state.Processor(ctx, in, out)
req := state.WorkRequest{state.Add, 3, 4}
in <- &req
req2 := state.WorkRequest{state.Subtract, 5, 2}
in <- &req2
req3 := state.WorkRequest{state.Multiply, 9, 9}
in <- &req3
req4 := state.WorkRequest{state.Divide, 8, 2}
in <- &req4
req5 := state.WorkRequest{state.Divide, 8, 0}
in <- &req5
for i := 0; i < 5; i++ {
resp := <-out
fmt.Printf("Request: %v; Result: %v, Error: %vn",
resp.Wr, resp.Result, resp.Err)
}
}
- Run go run main.go.
- You may also run the following commands:
$ go build
$ ./example
You should now see the following output:
$ go run main.go
Request: &{add 3 4}; Result: 7, Error: <nil>
Request: &{sub 5 2}; Result: 3, Error: <nil>
Request: &{mult 9 9}; Result: 81, Error: <nil>
Request: &{div 8 2}; Result: 4, Error: <nil>
Request: &{div 8 0}; Result: 0, Error: divide by 0
- The go.mod file may be updated and the go.sum file should now be present in the top-level recipe directory.
- If you copied or wrote your own tests, go up one directory and run go test. Ensure that all the tests pass.