mirror of
https://github.com/crazybber/awesome-patterns.git
synced 2025-02-16 13:43:13 +03:00
barrier pattern in the book added
This commit is contained in:
parent
f887bcedec
commit
0a1036f2c6
@ -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
|
||||
|
101
concurrency/mastering_concurrency_in_go/ch1/spider.go
Normal file
101
concurrency/mastering_concurrency_in_go/ch1/spider.go
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
@ -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()
|
||||
}
|
||||
|
69
go_design_pattern_book/concurrent_pattern/barrier/main.go
Normal file
69
go_design_pattern_book/concurrent_pattern/barrier/main.go
Normal 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
|
||||
}
|
@ -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"}
|
||||
})
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user