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. Prometheus学习系列(四)之Prometheus 配置说明

    前言 本文来自Prometheus官网手册 和 Prometheus简介 说明 Prometheus通过命令行和配置文件进行配置,命令行配置不能修改的系统参数(例如存储位置,要保留在磁盘和内存中的数据 ...

  2. Android 获取当前IP地址

    首先设置用户权限 <uses-permission android:name="android.permission.INTERNET"></uses-permi ...

  3. Additional information: The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding elemen

    wcf service: <system.serviceModel> <bindings> <basicHttpBinding> <binding name= ...

  4. CSS雪碧图(精灵图)使用

    1:CSS雪碧图:CSS雪碧图 即 CSS Sprites,也有人叫它CSS精灵图. 2:雪碧图的由来:一个网站的页面需要大量的小图片或者小图标,但是大量的图片如果放在服务器上,每次当打开网站并且向服 ...

  5. 关于js的for in循环,慎用

    参考:http://www.cftea.com/c/2014/08/6290.asp作者:vkvi 如题我看到也有点诧异,测试了真的有这个问题,上代码 Array.prototype.a = func ...

  6. 一些实用的Django+HTML设置

    一.关于引入变量 1.变量引入方法: {% block 块名称 %} <p>{{变量名}}<p> {% endblock %} 2.引入变量的值中标签是否转义: 不转义: {% ...

  7. Python输出16进制不带0x补零,整数转16进制,字符串转16进制

    Python输出16进制不带0x补零,整数转16进制,字符串转16进制   在开发中,我们偶尔会遇到需要将数据通过控制台打印出来,以检查数据传输的准确性.例如调试服务端刚接到的二进制数据(里面包含很多 ...

  8. 误删mysql root账户

    看这个账户有点碍眼就删除了,结果异常了mysql> select user,host from mysql.user;+---------------+-------------+| user ...

  9. Java之ArrayList类(集合)

    集合的由来 我们想存储多个数据,选择的容器可以是数组.而数组的长度是固定的,无法适应数据变化的需求.为了解决这个问题,Java提供了另一个容器 java.util.ArrayList 集合类,让我们可 ...

  10. java实现排列组合(通俗易懂)

    个人感觉这篇文章(原文地址见文章尾)写的排列组合问题,非常的好,而且是一步一步引出排列组合问题,我也是看了这篇文章,一步一步按照这个思路来,最后会了自己的一套排列组合 也因此在算法竞赛中,两次用到了, ...