samber/lo 库的使用方法: 处理 channel
samber/lo 库的使用方法: 处理 channel
samber/lo 是一个 Go 语言库,提供了一些常用的集合操作函数,如 Filter、Map 和 FilterMap。汇总目录页面
这个库函数太多,因此我决定按照功能分别介绍,本文介绍的是 samber/lo 库中channel相关的函数。
ChannelDispatcher
将信息从输入通道消息分发到 N 个子通道中。当输入通道关闭时,这个关闭事件会被传播到所有的子通道,也就是说,所有的子通道也会被关闭。这些通道可以有一个固定的缓冲容量,或者当 cap(容量)为 0 时,它们是无缓冲的。
// 创建了一个带有 42 个缓冲区的整数通道 ch,并向其中发送 0 到 10 的整数。
ch := make(chan int, 42)
for i := 0; i <= 10; i++ {ch <- i
}// 使用 lo.ChannelDispatcher 函数创建了 5 个子通道,每个通道的缓冲区大小为 10。
// 这个函数会将 ch 中的数据按照轮询策略分发到这些子通道中。
children := lo.ChannelDispatcher(ch, 5, 10, DispatchingStrategyRoundRobin[int])
// []<-chan int{...}// 定义了一个 consumer 函数,这个函数会从给定的通道中读取数据,直到通道关闭。
// 如果通道已经关闭,ok 会为 false,我们就打印 "closed" 并退出循环。
consumer := func(c <-chan int) {for {msg, ok := <-cif !ok {println("closed")break}println(msg)}
}// 为每个子通道启动一个 consumer goroutine。
// 这样,我们就创建了 5 个并发的消费者,它们会并行地从 ch 中读取数据。
for i := range children {go consumer(children[i])
}
有很多分发策略可用:
- lo.DispatchingStrategyRoundRobin: 使用轮询策略将消息分发到子通道中。
- lo.DispatchingStrategyRandom: 使用随机策略将消息分发到子通道中。
- lo.DispatchingStrategyWeightedRandom: 使用加权随机策略将消息分发到子通道中。
- lo.DispatchingStrategyFirst: 分发消息到第一个非满的子通道中。
- lo.DispatchingStrategyLeast: 分发消息到最空的子通道中。
- lo.DispatchingStrategyMost: 分发消息到最满的子通道中。
其中一些策略会带有回退机制,以便优先考虑非阻塞行为。请参阅实现。
对于自定义策略,只需实现 lo.DispatchingStrategy 原型即可:
type DispatchingStrategy[T any] func(message T, messageIndex uint64, channels []<-chan T) int
-
DispatchingStrategy 是一个函数,它接受三个参数:
-
message T:这是要分发的消息,其类型为泛型 T。
-
messageIndex uint64:这是消息的索引,通常用于确定将消息分发到哪个通道。
-
channels []<-chan T:这是一个通道切片,消息将被分发到这些通道中的一个。
-
这个函数返回一个 int,表示消息应该被分发到 channels 切片中的哪个通道。
Eg:
type Message struct {TenantID uuid.UUID
}func hash(id uuid.UUID) int {h := fnv.New32a()h.Write([]byte(id.String()))return int(h.Sum32())
}// Routes messages per TenantID.
customStrategy := func(message string, messageIndex uint64, channels []<-chan string) int {destination := hash(message) % len(channels)// check if channel is fullif len(channels[destination]) < cap(channels[destination]) {return destination}// fallback when child channel is fullreturn utils.DispatchingStrategyRoundRobin(message, uint64(destination), channels)
}children := lo.ChannelDispatcher(ch, 5, 10, customStrategy)
...
SliceToChannel
返回一个只读的通道,其中包含了集合中的元素。当最后一个元素被读取后,通道会被关闭。第一个参数是通道的容量,第二个参数是集合。
list := []int{1, 2, 3, 4, 5}for v := range lo.SliceToChannel(2, list) {println(v)
}
// prints 1, then 2, then 3, then 4, then 5
ChannelToSlice
返回一个由通道中的元素构建的切片。阻塞直到通道关闭。
list := []int{1, 2, 3, 4, 5}
ch := lo.SliceToChannel(2, list)items := ChannelToSlice(ch)
// []int{1, 2, 3, 4, 5}
Generator
实现了生成器设计模式。通道在最后一个元素被读取后会被关闭。通道的容量可以被定制。 Generator的第一个参数是通道的容量,第二个参数是生成器函数, 返回一个通道。 其中,生成器函数的参数是一个函数,这个函数用于向通道中发送元素。
generator := func(yield func(int)) {yield(1)yield(2)yield(3)
}for v := range lo.Generator(2, generator) {println(v)
}
// prints 1, then 2, then 3
Buffer
创建一个包含 n 个元素的切片,这些元素来自通道。返回切片、切片长度、读取时间和通道状态(打开/关闭)。第一个参数是通道,第二个参数是切片的长度。
ch := lo.SliceToChannel(2, []int{1, 2, 3, 4, 5})items1, length1, duration1, ok1 := lo.Buffer(ch, 3)
// []int{1, 2, 3}, 3, 0s, true
items2, length2, duration2, ok2 := lo.Buffer(ch, 3)
// []int{4, 5}, 2, 0s, false
示例:RabbitMQ 消费者
ch := readFromQueue()for {// read 1k itemsitems, length, _, ok := lo.Buffer(ch, 1000)// do batching stuffif !ok {break}
}
BufferWithTimeout
和Buffer函数类似, 但是增加了一个超时参数, 如果超时,返回已经读取的元素。
generator := func(yield func(int)) {for i := 0; i < 5; i++ {yield(i)time.Sleep(35*time.Millisecond)}
}ch := lo.Generator(0, generator)items1, length1, duration1, ok1 := lo.BufferWithTimeout(ch, 3, 100*time.Millisecond)
// []int{1, 2}, 2, 100ms, true
items2, length2, duration2, ok2 := lo.BufferWithTimeout(ch, 3, 100*time.Millisecond)
// []int{3, 4, 5}, 3, 75ms, true
items3, length3, duration2, ok3 := lo.BufferWithTimeout(ch, 3, 100*time.Millisecond)
// []int{}, 0, 10ms, false
示例:RabbitMQ 消费者
ch := readFromQueue()for {// read 1k items// wait up to 1 seconditems, length, _, ok := lo.BufferWithTimeout(ch, 1000, 1*time.Second)// do batching stuffif !ok {break}
}
示例:多线程的 RabbitMQ 消费者
ch := readFromQueue()// 5 workers
// prefetch 1k messages per worker
children := lo.ChannelDispatcher(ch, 5, 1000, lo.DispatchingStrategyFirst[int])consumer := func(c <-chan int) {for {// read 1k items// wait up to 1 seconditems, length, _, ok := lo.BufferWithTimeout(ch, 1000, 1*time.Second)// do batching stuffif !ok {break}}
}for i := range children {go consumer(children[i])
}
FanIn
合并多个输入通道的消息到一个缓冲通道中。输出消息没有优先级。当所有的上游通道到达 EOF 时,下游通道关闭。
stream1 := make(chan int, 42)
stream2 := make(chan int, 42)
stream3 := make(chan int, 42)all := lo.FanIn(100, stream1, stream2, stream3)
// <-chan int
FanOut
广播所有上游消息到多个下游通道。当上游通道到达 EOF 时,下游通道关闭。如果任何下游通道已满,广播将暂停。
stream := make(chan int, 42)all := lo.FanOut(5, 100, stream)
// [5]<-chan int
相关文章:
samber/lo 库的使用方法: 处理 channel
samber/lo 库的使用方法: 处理 channel samber/lo 是一个 Go 语言库,提供了一些常用的集合操作函数,如 Filter、Map 和 FilterMap。汇总目录页面 这个库函数太多,因此我决定按照功能分别介绍,本文介绍的是 samber/lo…...
铌酸锂芯片与精密划片机:科技突破引领半导体制造新潮流
在当今快速发展的半导体行业中,一种结合了铌酸锂芯片与精密划片机的创新技术正在崭露头角。这种技术不仅引领着半导体制造领域的进步,更为其他产业带来了前所未有的变革。 铌酸锂芯片是一种新型的微电子芯片,它使用铌酸锂作为基底材料&#x…...
大数据计算技术秘史(上篇)
在之前的文章《2024 年,一个大数据从业者决定……》《存储技术背后的那些事儿》中,我们粗略地回顾了大数据领域的存储技术。在解决了「数据怎么存」之后,下一步就是解决「数据怎么用」的问题。 其实在大数据技术兴起之前,对于用户…...
论文精读--word2vec
word2vec从大量文本语料中以无监督方式学习语义知识,是用来生成词向量的工具 把文本分散嵌入到另一个离散空间,称作分布式表示,又称为词嵌入(word embedding)或词向量 Abstract We propose two novel model architec…...
Android13 针对low memory killer内存调优
引入概念 在旧版本的安卓系统中,当触发lmk(low memory killer)的时候一般认为就是内存不足导致,但是随着安卓版本的增加lmk的判断标准已经不仅仅是内存剩余大小,io,cpu同样会做评判,从而保证设备…...
【深入理解设计模式】 工厂设计模式
工厂设计模式 工厂设计模式是一种创建型设计模式,它提供了一种在不指定具体类的情况下创建对象的接口。在工厂设计模式中,我们定义一个创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。 工厂设计模式的目…...
Windows下搭建EFK实例
资源下载 elasticSearch :下载最新版本的就行 kibana filebeat:注意选择压缩包下载 更新elasticsearch.yml,默认端口9200: # Elasticsearch Configuration # # NOTE: Elasticsearch comes with reasonable defaults for most …...
工厂方法模式Factory Method
1.模式定义 定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使得一个类的实例化延迟到子类 2.使用场景 1.当你不知道改使用对象的确切类型的时候 2.当你希望为库或框架提供扩展其内部组件的方法时 主要优点: 1.将具体产品和创建…...
Vue的个人笔记
Vue学习小tips ctrl s ----> 运行 alt b <scrip> 链接 <script src"https://cdn.jsdelivr.net/npm/vue2.7.16/dist/vue.js"></script> 插值表达式 指令...
linux platform架构下I2C接口驱动开发
目录 概述 1 认识I2C协议 1.1 初识I2C 1.2 I2C物理层 1.3 I2C协议分析 1.3.1 Start、Stop、ACK 信号 1.3.2 I2C协议的操作流程 1.3.3 操作I2C注意的问题 2 linux platform驱动开发 2.1 更新设备树 2.1.1 添加驱动节点 2.1.2 编译.dts 2.1.3 更新板卡中的.dtb 2.2 …...
基于机器学习的青藏高原高寒沼泽湿地蒸散发插补研究_王秀英_2022
基于机器学习的青藏高原高寒沼泽湿地蒸散发插补研究_王秀英_2022 摘要关键词 1 材料和方法1.1 研究区概况与数据来源1.2 研究方法 2 结果和分析2.1 蒸散发通量观测数据缺省状况2.2 蒸散发与气象因子的相关性分析2.3 不同气象因子输入组合下各模型算法精度对比2.4 随机森林回归模…...
Failed at the node-sass@4.14.1 postinstall script.
问题描述 安装sass # "node-sass": "^4.9.0" npm i node-sass报错如下 npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! node-sass4.14.1 postinstall: node scripts/build.js npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the node-sass4…...
【鸿蒙系统学习笔记】网络请求
一、介绍 资料来自官网:文档中心 网络管理模块主要提供以下功能: HTTP数据请求:通过HTTP发起一个数据请求。WebSocket连接:使用WebSocket建立服务器与客户端的双向连接。Socket连接:通过Socket进行数据传输。 日常…...
LabVIEW风力机智能叶片控制系统
LabVIEW风力机智能叶片控制系统 介绍了一种风力机智能叶片控制系统的开发。通过利用LabVIEW软件与CDS技术,该系统能够实时监测并调整风力机叶片的角度,优化风能转换效率。此项技术不仅提高了风力发电的稳定性和效率,而且为风力机的智能化管…...
HarmonyOS Stage模型 权限申请
配置声明权限 在module.json5配置文件中声明权限。不论是system_grant还是user_grant类型都需要声明权限,否则应用将无法获得授权。 {"module" : {// ..."requestPermissions":[{"name": "ohos.permission.DISCOVER_BLUETOOTH…...
标题:从预编译到链接:探索C/C++程序的翻译环境全貌
引言 在软件开发的世界里,我们通常会遇到两种不同的环境——翻译环境与运行环境。今天,我们将聚焦于前者,深入剖析C/C程序生命周期中至关重要的“翻译环境”,即从源代码到可执行文件这一过程中涉及的四个关键阶段:预编…...
深入理解单端模拟多路复用器DG406DW-E3 应用于高速数据采集、ATE系统和航空电子设备解决方案
DG406DW-E3是一款16通道单端模拟多路复用器设计用于将16个输入中的一个连接到公共端口由4位二进制地址确定的输出。应用包括高速数据采集、音频信号切换和路由、ATE系统和航空电子设备。高性能低功耗损耗使其成为电池供电和电池供电的理想选择远程仪器应用。采用44V硅栅CMOS工艺…...
Redis篇----第六篇
系列文章目录 文章目录 系列文章目录前言一、Redis 的持久化机制是什么?各自的优缺点?二、Redis 常见性能问题和解决方案:三、redis 过期键的删除策略?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章…...
【LeetCode】509. 斐波那契数(简单)——代码随想录算法训练营Day38
题目链接:509. 斐波那契数 题目描述 斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是: F(0) 0,F(1) 1 F(n) F(n -…...
[OpenGL教程05 ] glAccum() 函数对累积缓存设置
Accumulation Buffer:累积缓存 一、说明 openGL编程之所以困难,是因为它是三维图表示;简简单单加入一个Z轴,却使得几何遮挡、光线过度、运动随影等搞得尤其复杂。它的核心处理环节是像素缓存,本篇的积累缓存就是其一个…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...
Kafka主题运维全指南:从基础配置到故障处理
#作者:张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1:主题删除失败。常见错误2:__consumer_offsets占用太多的磁盘。 主题日常管理 …...
python打卡day49@浙大疏锦行
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 一、通道注意力模块复习 & CBAM实现 import torch import torch.nn as nnclass CBAM(nn.Module):def __init__…...
