barrier.go
package barrier

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"time"
)

var timeoutMillseconds 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
		}
		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(timeoutMillseconds) *
			time.Microsecond),
	}

	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
}

  

barrier_test.go
package barrier

import (
	"bytes"
	"io"
	"os"
	"strings"
	"testing"
)

func TestBarrier(t *testing.T) {
	t.Run("Correct endpoints", func(t *testing.T) {
		endpoints := []string{"https://www.baidu.com/",
			"https://www.sina.com.cn/"}

		result := captureBarrierOutput(endpoints...)

		if !strings.Contains(result, "Accept-Encoding") {
			t.Fail()
		}
		t.Log(result)
	})

	t.Run("One endpoints incorrect", func(t *testing.T) {
		endpoints := []string{"http://malformed-url",
			"http://httpbin.org/User-Agent"}

		result := captureBarrierOutput(endpoints...)

		if !strings.Contains(result, "ERROR") {
			t.Fail()
		}
		t.Log(result)
	})

	t.Run("Very short timeout", func(t *testing.T) {
		endpoints := []string{"http://httpbin.org/headers",
			"http://httpbin.org/User-Agent"}
		//timeoutMilliseconds := 1
		result := captureBarrierOutput(endpoints...)
		if !strings.Contains(result, "Timeout") {
			t.Fail()
		}
		t.Log(result)
	})
}

func captureBarrierOutput(endpoints ...string) string {
	reader, writer, _ := os.Pipe()
	os.Stdout = writer
	out := make(chan string)

	go func() {
		var buf bytes.Buffer
		io.Copy(&buf, reader)
		out <- buf.String()
	}()

	barrier(endpoints...)

	writer.Close()
	temp := <-out
	return temp
}

  

												

go语言设计模式之Concurrency barrier的更多相关文章

  1. go语言设计模式之Concurrency workers pool

    worker.go package main import ( "fmt" "strings" ) type WorkerLauncher interface ...

  2. go语言设计模式之Concurrency pipeline

    pipeline.go package pipeline func LaunchPipeline(amount int) int { firstCh := generator(amount) seco ...

  3. go语言设计模式之Concurrency future

    future.go package future type SuccessFunc func(string) type FailFunc func(error) type ExecuteStringF ...

  4. Go语言设计模式之函数式选项模式

    Go语言设计模式之函数式选项模式 本文主要介绍了Go语言中函数式选项模式及该设计模式在实际编程中的应用. 为什么需要函数式选项模式? 最近看go-micro/options.go源码的时候,发现了一段 ...

  5. C语言设计模式-封装-继承-多态

    快过年了,手头的工作慢慢也就少了,所以,研究技术的时间就多了很多时间,前些天在CSDN一博客看到有大牛在讨论C的设计模式,正好看到了,我也有兴趣转发,修改,研究一下. 记得读大学的时候,老师就告诉我们 ...

  6. Go语言设计模式实践:迭代器(Iterator)

    关于本系列 决定开个新坑. 这个系列首先是关于Go语言实践的.在项目中实际使用Go语言也有段时间了,一个体会就是不论是官方文档.图书还是网络资料,关于Go语言惯用法(idiom)的介绍都比较少,基本只 ...

  7. Go语言设计模式实践:组合(Composite)

    关于本系列 这个系列首先是关于Go语言实践的.在项目中实际使用Go语言也有段时间了,一个体会就是不论是官方文档.图书还是网络资料,关于Go语言惯用法(idiom)的介绍都比较少,基本只能靠看标准库源代 ...

  8. Go语言设计模式汇总

    目录 设计模式背景和起源 设计模式是什么 Go语言模式分类 个人观点 Go语言从面世就受到了业界的普遍关注,随着区块链的火热Go语言的地位也急速蹿升,为了让读者对设计模式在Go语言中有一个初步的了解和 ...

  9. C语言设计模式

    一 .C语言和设计模式(继承.封装.多态) C++有三个最重要的特点,即继承.封装.多态.我发现其实C语言也是可以面向对象的,也是可以应用设计模式的,关键就在于如何实现面向对象语言的三个重要属性. ( ...

随机推荐

  1. WPF之行为

    Behavior的运用扩展了”交互“功能,以下记录示例: 在的项目中添加两个引用:Microsoft.Expression.Interactions.dllSystem.Windows.Interac ...

  2. TensorFlow实现图像卷积并可视化示例

    图片尺寸要自己修改. 看起来好像没啥意思,不知道下一步能干什么,先卷了再说.由于weights是随机生成的(tf.random_normal作用:用于从服从指定正太分布的数值中取出随机数),所以每次卷 ...

  3. 小程序封装request请求,统一API

    程序开发中都会调用后端工程师开发的API,小程序的开发文档提供了相对实用的APIwx.request(),但是在开发的过程中,又遇到了一些问题,在小程序的项目开发时,调用的API不止一个,同一个API ...

  4. 【Cocos谁学谁会】定制属于自己的脚本模板

    版权申明: 本文原创首发于以下网站,您可以自由转载,但必须加入完整的版权声明 博客园:https://www.cnblogs.com/MogooStudio/ csdn博客:https://blog. ...

  5. [Go] golang定时器与redis结合

    golang定时器与redis结合,每隔1秒ping一下,每隔20秒llen一下队列的长度 package main import ( "fmt" "time" ...

  6. docker Dockerfile里使用的命令说明

    一,dockerfile格式 注释# 指令 参数 指令不区分大小写,但是推荐全部大写指令. 指令从上到下顺序被执行 第一个指令必须是[FROM],指示出要使用的基础镜像. 执行docker file时 ...

  7. C#的语法----程序结构(1)

    接下来的内容是整个C#学习的脉络,它将各个知识点串联了起来,是整个C#的重点,所以篇幅较长. 首先,我们类比一下PLC和C#执行代码的方式,其实不难发现都是顺序扫描,以Main为程序入口,从上到下一行 ...

  8. linux 源设置

    ubuntu 18.04.3 sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak cat > /etc/apt/sources.lis ...

  9. IDE开发小技巧-快速引包/替换关键词

    快速引包 Ctrl+Shift+O 快速搜索/查找替换   Ctrl+F

  10. vue.js 的 vue-element-admin 实践开发

    官方网址: https://panjiachen.github.io/vue-element-admin-site/zh/ 一:面包屑导航,根目录文字修改: 定位到文件 vue-element-sup ...