worker.go

package main

import (
	"fmt"
	"strings"
)

type WorkerLauncher interface {
	LaunchWorker(in chan Request)
}

type PreffixSuffixWorker struct {
	id      int
	prefixS string
	suffixS string
}

func (w *PreffixSuffixWorker) LaunchWorker(in chan Request) {
	w.prefix(w.append(w.upperCase(in)))
}

func (w *PreffixSuffixWorker) upperCase(in <-chan Request) <-chan Request {
	out := make(chan Request)

	go func() {
		for msg := range in {
			s, ok := msg.Data.(string)

			if !ok {
				msg.handler(nil)
				continue
			}

			msg.Data = strings.ToUpper(s)
			out <- msg
		}
		close(out)
	}()
	return out
}

func (w *PreffixSuffixWorker) append(in <-chan Request) <-chan Request {
	out := make(chan Request)

	go func() {
		for msg := range in {
			uppercaseString, ok := msg.Data.(string)

			if !ok {
				msg.handler(nil)
				continue
			}
			msg.Data = fmt.Sprintf("%s%s", uppercaseString, w.suffixS)
			out <- msg
		}
		close(out)
	}()
	return out
}

func (w *PreffixSuffixWorker) prefix(in <-chan Request) {
	go func() {
		for msg := range in {
			uppercasedStringWithSuffix, ok := msg.Data.(string)
			if !ok {
				msg.handler(nil)
				continue
			}
			msg.handler(fmt.Sprintf("%s%S", w.prefixS, uppercasedStringWithSuffix))
		}
	}()
}

  

dispatcher.go

package main

import (
	"time"
)

type Dispatcher interface {
	LaunchWorker(w WorkerLauncher)
	MakeRequest(Request)
	Stop()
}

type dispatcher struct {
	inCh chan Request
}

func (d *dispatcher) LaunchWorker(w WorkerLauncher) {
	w.LaunchWorker(d.inCh)
}

func (d *dispatcher) Stop() {
	close(d.inCh)
}

func (d *dispatcher) MakeRequest(r Request) {
	select {
	case d.inCh <- r:
	case <-time.After(time.Second * 5):
		return
	}
}

func NewDispatcher(b int) Dispatcher {
	return &dispatcher{
		inCh: make(chan Request, b),
	}
}

  

workers_pipeline.go

package main

import (
	"fmt"
	"log"
	"sync"
)

type RequestHandler func(interface{})

type Request struct {
	Data    interface{}
	handler RequestHandler
}

func NewStringRequest(s string, id int, wg *sync.WaitGroup) Request {
	myRequest := Request{
		Data: "Hello",
		handler: func(i interface{}) {
			defer wg.Done()
			s, ok := i.(string)
			if !ok {
				log.Fatal("Invalid casting to string")
			}
			fmt.Println(s)
		},
	}
	return myRequest
}

func main() {
	bufferSize := 100
	var dispatcher Dispatcher = NewDispatcher(bufferSize)

	workers := 3
	for i := 0; i < workers; i++ {
		var w WorkerLauncher = &PreffixSuffixWorker{
			prefixS: fmt.Sprintf("WorkerID: %d -> ", i),
			suffixS: " World",
			id:      i,
		}
		dispatcher.LaunchWorker(w)
	}
	requests := 10
	var wg sync.WaitGroup
	wg.Add(requests)

	for i := 0; i < requests; i++ {
		req := NewStringRequest("(MSG_ID: %d) -> Hello", i, &wg)
		dispatcher.MakeRequest(req)
	}
	dispatcher.Stop()
	wg.Wait()
}

  

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

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

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

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

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

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

    barrier.go package barrier import ( "fmt" "io/ioutil" "net/http" " ...

  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. IT兄弟连 HTML5教程 和页面布局有关的CSS属性

    使用DIV+CSS对网页进行标准化布局前,除了要掌握盒子模型,还要掌握定位和浮动两个比较重要的概念,它们可以控制在页面上排列和显示元素的方式.一个盒子是装内容的区块,如果多个盒子组合在一起使用,再通过 ...

  2. 精通awk系列(2):本教程测试所用示例文件

    回到: Linux系列文章 Shell系列文章 Awk系列文章 本系列的awk教程中,将大量使用到如下示例文件a.txt. ID name gender age email phone 1 Bob m ...

  3. Python3 pickle模块用法

    pickle(python3.x)和cPickle(python2.x的模块)相当于java的序列化和反序列化操作. 常采用下面的方式使用: import pickle pickle.dump(obj ...

  4. ES-结构化查询

    参考: https://es.xiaoleilu.com/054_Query_DSL/55_Request_body_search.html 请求体查询 GET /_search {} 分页 GET ...

  5. GPS定位的偏移校正(WGS84与火星坐标互转)

    地图坐标系目前包括: 地球坐标 (WGS84) WGS84:World Geodetic System 1984,是为GPS全球定位系统使用而建立的坐标系统. 国际标准,从 GPS 设备中取出的数据的 ...

  6. 十分钟 CODING DevOps 全链路体验

    近期 CODING 团队在 2019 KubeCon 大会上发布 DevOps 一站式解决方案:CODING 2.0.此次 CODING 全新上线了持续集成与制品库模块,通过自动化与标准化的方式来帮助 ...

  7. MySQL解惑——GROUP BY隐式排序

    MySQL中GROUP BY隐式排序是什么概念呢? 主要是其它RDBMS没有这样的概念,如果没有认真了解过概念,对这个概念会感觉有点困惑,我们先来看看官方文档的介绍: 官方文档MySQL 5.7 Re ...

  8. vue项目空格报错,缩进不对报错,格式报错!!!

    vue-cli构建项目之后发现写几句代码就会报错,但是语法什么的都没有问题,只是因为缩进.空格之类的,对于初学者格式不规范的人来说是相当难受的 图中框住的位置都会报错!! 现在有两种办法: 1.是因为 ...

  9. PyCharm 快捷键失效解决办法

    PyCharm快捷键用着用着失效了 ......修改设置如下 重新启动Pycharm即可 原博客地址:https://blog.csdn.net/jacke121/article/details/82 ...

  10. 《软件安装》VMware Workstation 不注册 下载

    问答环节 问:为什么要下载安装VMware Workstation 答:VMware Workstation 可以安装虚拟机,我们可以把我们安装的一些软件装在虚拟机上面,防止自己的电脑卡顿(软件装多了 ...