github.com/l3x/learn-fp-go@v0.0.0-20171228022418-7639825d0b71/3-functional-techniques/ch08-pipelining/04_buffered_cpus/main.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	gc "github.com/go-goodies/go_currency"
     6  	"runtime"
     7  )
     8  
     9  func main() {
    10  	orders := GetOrders()
    11  	numberOfOrders := len(orders)
    12  	cpus := runtime.NumCPU()
    13  	runtime.GOMAXPROCS(cpus)
    14  	input := make(chan Order, cpus)
    15  	output := make(chan Order, cpus)
    16  	for i := 0; i < numberOfOrders; i++ {
    17  		go func() {
    18  			for order := range input {
    19  				output <- Pipeline(order)
    20  			}
    21  		}()
    22  	}
    23  	for _, order := range orders {
    24  		input <- *order
    25  	}
    26  	close(input)
    27  	for i := 0; i < numberOfOrders; i++ {
    28  		fmt.Println("The result is:", <-output)
    29  	}
    30  }
    31  
    32  func Pipeline(o Order) Order {
    33  	o = Authenticate(o)
    34  	o = Decrypt(o)
    35  	o = Charge(o)
    36  	return o
    37  }
    38  
    39  
    40  func Authenticate(o Order) Order  {
    41  	fmt.Printf("Order %d is Authenticated\n", o.OrderNumber)
    42  	return o
    43  }
    44  
    45  func Decrypt(o Order) Order {
    46  	fmt.Printf("Order %d is Decrypted\n", o.OrderNumber)
    47  	return o
    48  }
    49  
    50  func Charge(o Order) Order {
    51  	fmt.Printf("Order %d is Charged\n", o.OrderNumber)
    52  	return o
    53  }
    54  
    55  type Order struct {
    56  	OrderNumber int
    57  	IsValid bool
    58  	Credentials string
    59  	CCardNumber string
    60  	CCardExpDate string
    61  	LineItems []LineItem
    62  }
    63  
    64  type LineItem struct {
    65  	Description string
    66  	Count       int
    67  	PriceUSD    gc.USD
    68  }
    69  func GetOrders() []*Order {
    70  
    71  	order1 := &Order{
    72  		10001,
    73  		true,
    74  		"alice,secret",
    75  		"7b/HWvtIB9a16AYk+Yv6WWwer3GFbxpjoR+GO9iHIYY=",
    76  		"0922",
    77  		[]LineItem{
    78  			{"Apples", 1, gc.USD{4, 50}},
    79  			{"Oranges", 4, gc.USD{12, 00}},
    80  		},
    81  	}
    82  
    83  	order2 := &Order{
    84  		10002,
    85  		true,
    86  		"bob,secret",
    87  		"EOc3kF/OmxY+dRCaYRrey8h24QoGzVU0/T2QKVCHb1Q=",
    88  		"0123",
    89  		[]LineItem{
    90  			{"Milk", 2, gc.USD{8, 00}},
    91  			{"Sugar", 1, gc.USD{2, 25}},
    92  			{"Salt", 3, gc.USD{3, 75}},
    93  		},
    94  	}
    95  	orders := []*Order{order1, order2}
    96  	return orders
    97  }