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. Linux之shell详解

    Shell是什么 Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计语言.Shell 是指一种应用程序,这个应用程序提供了一个界 ...

  2. 痞子衡嵌入式:高性能MCU之人工智能物联网应用开发那些事 - 索引

    大家好,我是痞子衡,是正经搞技术的痞子.本系列痞子衡给大家介绍的是高性能MCU之人工智能物联网应用开发相关知识. 恩智浦半导体2017年开始推出的i.MX RT系列跨界处理器,这种高性能MCU给嵌入式 ...

  3. Centos 下安装 PHP (新)

    今天重新实践了下 CentOS 7.6 下安装 PHP7 并完成配置,总结了一条可以照其实现的套路. 安装 PHP 所需扩展 # yum install libxml2 libxml2-devel o ...

  4. ionic + cordova安装指南

    安装ionic --npm install -g ionic --cnpm install -g ionic --npm update -g ionic --cnpm update -g ionic ...

  5. 基于Redis扩展模块的布隆过滤器使用

    什么是布隆过滤器?它实际上是一个很长的二进制向量和一系列随机映射函数.把一个目标元素通过多个hash函数的计算,将多个随机计算出的结果映射到不同的二进制向量的位中,以此来间接标记一个元素是否存在于一个 ...

  6. Redis & memcached PK

    redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set ...

  7. redis cluster集群动态伸缩--删除主从节点

    目标:从集群中剔除一组主从(5007,5008) 经过上一节增加5007,5008主从服务节点后,目前集群的情况是这样的: b3363a81c3c59d57143cd3323481259c044e66 ...

  8. 表单生成器(Form Builder)之伪造表单数据番外篇——指定范围随机时间

    为了伪造一些尽量真实的假数据,也真是够费劲的.上一篇笔记记录了一下获取一个随机车辆牌照,这篇笔记记录一下怎么获取一个随机时间.这篇就不说那么多废话了,直接上代码 // 获取指定范围的随机数 var g ...

  9. 用iText5-1-生成PDF

    参考代码和图片出处 https://howtodoinjava.com/library/read-generate-pdf-java-itext/ pom引入jar包 <dependencies ...

  10. [CodeForces - 1225D]Power Products 【数论】 【分解质因数】

    [CodeForces - 1225D]Power Products [数论] [分解质因数] 标签:题解 codeforces题解 数论 题目描述 Time limit 2000 ms Memory ...