barrier pattern in the book added

This commit is contained in:
Jian Han 2018-01-08 22:30:16 +10:00
parent f887bcedec
commit 0a1036f2c6
5 changed files with 191 additions and 7 deletions

View File

@ -3,7 +3,6 @@ package ch1
import (
"fmt"
"strings"
"sync"
)
var initialString string
@ -11,8 +10,7 @@ var initialBytes []byte
var stringLength int
var finalString string
var lettersProcessed int
var applicationStatus bool
var wg sync.WaitGroup
var applicationStatusL bool
func getLetters(gQ chan string) {
for i := range initialBytes {
@ -22,7 +20,7 @@ func getLetters(gQ chan string) {
func capitalizeLetters(gQ chan string, sQ chan string) {
for {
if lettersProcessed >= stringLength {
applicationStatus = false
applicationStatusL = false
break
}
select {
@ -34,7 +32,7 @@ func capitalizeLetters(gQ chan string, sQ chan string) {
}
}
func RunLetter() {
applicationStatus = true
applicationStatusL = true
getQueue := make(chan string)
stackQueue := make(chan string)
initialString = `Four score and seven years ago our fathers
@ -50,7 +48,7 @@ created equal.`
close(getQueue)
close(stackQueue)
for {
if applicationStatus == false {
if applicationStatusL == false {
fmt.Println("Done")
fmt.Println(finalString)
break

View File

@ -0,0 +1,101 @@
package ch1
import (
"fmt"
"io/ioutil"
"net/http"
"sync"
"time"
)
var applicationStatus bool
var urls []string
var urlsProcessed int
var foundUrls []string
var fullText string
var totalURLCount int
var wg sync.WaitGroup
var v1 int
func readURLs(statusChannel chan int, textChannel chan string) {
time.Sleep(time.Millisecond * 1)
fmt.Println("Grabbing", len(urls), "urls")
for i := 0; i < totalURLCount; i++ {
fmt.Println("Url", i, urls[i])
resp, _ := http.Get(urls[i])
text, err := ioutil.ReadAll(resp.Body)
textChannel <- string(text)
if err != nil {
fmt.Println("No HTML body")
}
statusChannel <- 0
}
}
func addToScrapedText(textChannel chan string, processChannel chan bool) {
for {
select {
case pC := <-processChannel:
if pC == true {
// hang on
}
if pC == false {
close(textChannel)
close(processChannel)
}
case tC := <-textChannel:
fullText += tC
}
}
}
func evaluateStatus(statusChannel chan int, textChannel chan string, processChannel chan bool) {
for {
select {
case status := <-statusChannel:
fmt.Print(urlsProcessed, totalURLCount)
urlsProcessed++
if status == 0 {
fmt.Println("Got url")
}
if status == 1 {
close(statusChannel)
}
if urlsProcessed == totalURLCount {
fmt.Println("Read all top-level URLs")
processChannel <- false
applicationStatus = false
}
}
}
}
func RunSpider() {
applicationStatus = true
statusChannel := make(chan int)
textChannel := make(chan string)
processChannel := make(chan bool)
totalURLCount = 0
urls = append(urls, "http://www.mastergoco.com/index1.html")
urls = append(urls, "http://www.mastergoco.com/index2.html")
urls = append(urls, "http://www.mastergoco.com/index3.html")
urls = append(urls, "http://www.mastergoco.com/index4.html")
urls = append(urls, "http://www.mastergoco.com/index5.html")
fmt.Println("Starting spider")
urlsProcessed = 0
totalURLCount = len(urls)
go evaluateStatus(statusChannel, textChannel, processChannel)
go readURLs(statusChannel, textChannel)
go addToScrapedText(textChannel, processChannel)
for {
if applicationStatus == false {
fmt.Println(fullText)
fmt.Println("Done!")
break
}
select {
case sC := <-statusChannel:
fmt.Println("Message on StatusChannel", sC)
}
}
}

View File

@ -4,5 +4,6 @@ import "github.com/jianhan/go-patterns/concurrency/mastering_concurrency_in_go/c
func main() {
// ch1.Run()
ch1.RunLetter()
// ch1.RunLetter()
ch1.RunSpider()
}

View File

@ -0,0 +1,69 @@
package main
import (
"fmt"
"io/ioutil"
"net/http"
"time"
)
func main() {
barrier("http://httpbin.org/headers", "http://httpbin.org/User-Agen")
}
var timeoutMilliseconds int = 5000
type barrierResp struct {
Err error
Resp string
}
func barrier(endpoints ...string) {
requestNumber := len(endpoints)
in := make(chan barrierResp, requestNumber)
defer close(in)
responses := make([]barrierResp, requestNumber)
for _, endpoint := range endpoints {
go makeRequest(in, endpoint)
}
var hasError bool
for i := 0; i < requestNumber; i++ {
resp := <-in
if resp.Err != nil {
fmt.Println("ERROR: ", resp.Err)
hasError = true
break
}
responses[i] = resp
}
if !hasError {
for _, resp := range responses {
fmt.Println(resp.Resp)
}
}
}
func makeRequest(out chan<- barrierResp, url string) {
res := barrierResp{}
client := http.Client{
Timeout: time.Duration(time.Duration(timeoutMilliseconds) * time.Millisecond),
}
resp, err := client.Get(url)
if err != nil {
res.Err = err
out <- res
return
}
byt, err := ioutil.ReadAll(resp.Body)
if err != nil {
res.Err = err
out <- res
return
}
res.Resp = string(byt)
out <- res
}

View File

@ -0,0 +1,15 @@
package main
import "testing"
func TestBarrier(t *testing.T) {
t.Run("Correct endpoints", func(t *testing.T) {
endpoints := []string{"http://httpbin.org/headers", "http://httpbin.org/User-Agent"}
})
t.Run("One endpoint incorrect", func(t *testing.T) {
endpoints := []string{"http://malformed-url", "http://httpbin.org/User-Agent"}
})
t.Run("Very Short Timeout", func(t *testing.T) {
endpoints := []string{"http://httpbin.org/headers", "http://httpbin.org/User-Agent"}
})
}