mirror of
https://github.com/crazybber/awesome-patterns.git
synced 2025-02-21 07:53: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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var initialString string
|
var initialString string
|
||||||
@ -11,8 +10,7 @@ var initialBytes []byte
|
|||||||
var stringLength int
|
var stringLength int
|
||||||
var finalString string
|
var finalString string
|
||||||
var lettersProcessed int
|
var lettersProcessed int
|
||||||
var applicationStatus bool
|
var applicationStatusL bool
|
||||||
var wg sync.WaitGroup
|
|
||||||
|
|
||||||
func getLetters(gQ chan string) {
|
func getLetters(gQ chan string) {
|
||||||
for i := range initialBytes {
|
for i := range initialBytes {
|
||||||
@ -22,7 +20,7 @@ func getLetters(gQ chan string) {
|
|||||||
func capitalizeLetters(gQ chan string, sQ chan string) {
|
func capitalizeLetters(gQ chan string, sQ chan string) {
|
||||||
for {
|
for {
|
||||||
if lettersProcessed >= stringLength {
|
if lettersProcessed >= stringLength {
|
||||||
applicationStatus = false
|
applicationStatusL = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
@ -34,7 +32,7 @@ func capitalizeLetters(gQ chan string, sQ chan string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
func RunLetter() {
|
func RunLetter() {
|
||||||
applicationStatus = true
|
applicationStatusL = true
|
||||||
getQueue := make(chan string)
|
getQueue := make(chan string)
|
||||||
stackQueue := make(chan string)
|
stackQueue := make(chan string)
|
||||||
initialString = `Four score and seven years ago our fathers
|
initialString = `Four score and seven years ago our fathers
|
||||||
@ -50,7 +48,7 @@ created equal.`
|
|||||||
close(getQueue)
|
close(getQueue)
|
||||||
close(stackQueue)
|
close(stackQueue)
|
||||||
for {
|
for {
|
||||||
if applicationStatus == false {
|
if applicationStatusL == false {
|
||||||
fmt.Println("Done")
|
fmt.Println("Done")
|
||||||
fmt.Println(finalString)
|
fmt.Println(finalString)
|
||||||
break
|
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() {
|
func main() {
|
||||||
// ch1.Run()
|
// 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