当前位置: 首页 > news >正文

基于Kotlin中Flow扩展重试方法

在这里插入图片描述
最近项目中统一采用Kotlin的Flow来重构了网络请求相关代码。
目前的场景是,接口在请求的时候需要一个accessToken值,因为此值会过期或者不存在,需要刷新,因此最终方案是在使用Flow请求的时候先获取accessToken值然后再进行接口请求,而获取accessToken值的方法已经封装成了一个Flow并且做了缓存,因此最后需要使用flatMapConcat操作符来连接真正需要的接口请求,如果获取的accessToken无效,又需要回头重新执行,逻辑如下:

  1. 判断本地是否存在accessToken并且是否过期,不存在或者已过期则请求accessToken
  2. 请求对应的接口
  3. 如果返回结果中accessToken无效,则重试

Flow提供了retryretryWhen两种扩展方法来做重试操作:

retry源码

public fun <T> Flow<T>.retry(retries: Long = Long.MAX_VALUE,predicate: suspend (cause: Throwable) -> Boolean = { true }
): Flow<T> {require(retries > 0) { "Expected positive amount of retries, but had $retries" }return retryWhen { cause, attempt -> attempt < retries && predicate(cause) }
}

retryWhen源码

public fun <T> Flow<T>.retryWhen(predicate: suspend FlowCollector<T>.(cause: Throwable, attempt: Long) -> Boolean): Flow<T> =flow {var attempt = 0Lvar shallRetry: Booleando {shallRetry = falseval cause = catchImpl(this)if (cause != null) {if (predicate(cause, attempt)) {shallRetry = trueattempt++} else {throw cause}}} while (shallRetry)}

但是,retryretryWhen只能通过异常来判断,如果是通过返回结果来判断,就需要借助外部变量来处理了,因此基于源码扩展了方法retry,可以接收请求结果,从而通过请求结果来判断是否需要重试。

fun <T> Flow<T>.retry(retries: Long = Long.MAX_VALUE, predicate: suspend (result: T) -> Boolean = { true }
): Flow<T> {require(retries > 0) { "Expected positive amount of retries, but had $retries" }return flow {var attempt = 0Lvar shallRetry: Booleando {shallRetry = falsetry {collect {if (attempt < retries && predicate(it)) {shallRetry = trueattempt++} else {this.emit(it)}}} catch (e: Throwable) {throw e}} while (shallRetry)}
}

最后的请求示例代码如下:

MainScope().launch {getToken().flatMapConcat {if (it is Result.Success) {sendMobileCode()} else {emptyFlow()}}.retry(1) {return@retry (it is Result.Failure) && (it.code == ErrorStatus.ACCESS_TOKEN_ERROR)}.flowOn(Dispatchers.IO).onStart {callback?.onStart()}.catch {callback?.onError(it)}.onCompletion {callback?.onComplete(it)}.collectLatest { result ->}}

感谢大家的支持,如有错误请指正,如需转载请标明原文出处!

相关文章:

基于Kotlin中Flow扩展重试方法

最近项目中统一采用Kotlin的Flow来重构了网络请求相关代码。 目前的场景是&#xff0c;接口在请求的时候需要一个accessToken值&#xff0c;因为此值会过期或者不存在&#xff0c;需要刷新&#xff0c;因此最终方案是在使用Flow请求的时候先获取accessToken值然后再进行接口请求…...

好好说话:深度学习扫盲

大创项目是和目标检测算法YOLO相关的&#xff0c;浅浅了解了一些有关深度学习的知识。在这里根据本人的理解做一些梳理。 深度学习是什么&#xff1f; 之前经常听到AI&#xff0c;机器学习&#xff0c;深度学习这三个概念&#xff0c;但是对于三者的区别一直很模糊。 AI&…...

【状态空间方程】对于状态空间方程矩阵D≠0时的状态反馈与滑模控制

又到新的一年啦&#xff0c;2025新年快乐~。前几个月都没更新&#xff0c;主要还是因为不能把项目上的私密工作写进去&#xff0c;所以暂时没啥可写的。最近在山里实习&#xff0c;突然想起年前遗留了个问题一直没解决&#xff0c;没想到这两天在deepseek的加持下很快解决了&am…...

腾讯大数据基于 StarRocks 的向量检索探索

作者&#xff1a;赵裕隆&#xff0c;腾讯大数据研发工程师 本文整理自腾讯大数据工程师在 StarRocks 年度峰会上的分享&#xff0c;深入探讨了向量检索技术的原理与应用。此功能已应用到腾讯内部多个场景&#xff0c;引入 StarRocks 后&#xff0c;业务不仅不需要维护多套数据库…...

Linux系统调用

文章目录 系统调用和POSIX标准系统调用表程序直接访问系统调用新增系统调用 在linux中&#xff0c;内核空间和用户空间之间增加了一个中间层——系统调用层&#xff0c;如下图&#xff1a; 系统内调用层主要作用&#xff1a; 为用户空间程序提供一层硬件抽象接口。保证系统稳定…...

如何在Servlet容器中使用HttpServletResponse?

HttpServletResponse 是 Java Servlet API 中的一个接口&#xff0c;它代表了服务器对客户端的响应。通过 HttpServletResponse 对象&#xff0c;可以设置响应的状态码、发送数据到客户端&#xff08;如 HTML 页面、文件等&#xff09;、添加响应头信息等。下面是如何在 Servle…...

SpringCloud - Seata 分布式事务

前言 该博客为Sentinel学习笔记&#xff0c;主要目的是为了帮助后期快速复习使用 学习视频&#xff1a;7小快速通关SpringCloud 辅助文档&#xff1a;SpringCloud快速通关 源码地址&#xff1a;cloud-demo 一、简介 官网&#xff1a;https://seata.apache.org/zh-cn/ Seata …...

Ansible批量配置服务器免密登录步骤详解

一、准备工作 192.168.85.138 安装ansible&#xff0c;计划配置到139的免密 192.168.85.139 待配置免密 1. 生成SSH密钥对 在Ansible控制节点生成密钥对&#xff0c;用于后续免密认证&#xff1a; ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa 全部回车默认&#xff0c;无…...

互联网大厂中面试的高频计算机网络问题及详解

前言 哈喽各位小伙伴们,本期小梁给大家带来了互联网大厂中计算机网络部分的高频面试题,本文会以通俗易懂的语言以及图解形式描述,希望能给大家的面试带来一点帮助,祝大家offer拿到手软!!! 话不多说,我们立刻进入本期正题! 一、计算机网络基础部分 1 …...

人工智能时代下ai智能语音机器人如何以假乱真?

智能语音机器人若要达到以假乱真的效果&#xff0c;需要在以下几个关键方面不断提升&#xff1a; 一、语音合成技术 音色模拟 多维度采样 对大量真人语音样本进行多维度采样&#xff0c;包括不同年龄、性别、地域的人的语音。例如&#xff0c;采集不同年龄段男性从低沉到清亮…...

【橘子ES】Aggregations 聚合准备

一、聚合的概念 聚合文档 聚合区别于检索&#xff0c;检索是使用一系列条件把文档从es中搜索回来。但是聚合则是在搜索回来的文档的基础上进一步进行处理。 简单来说聚合就是将数据汇总为指标、统计数据或其他分析。聚合可以解决以下几类问题&#xff1a; 我的网站的平均加载…...

vue3读取webrtc-stream 视频流

一.首先下载webrtc-stream&#xff0c;方便自己本地搭建视频流服务 https://download.csdn.net/download/cyw8998/90373521 解压后&#xff0c;启动命令 webrtc-streamer.exe -H 127.0.0.1:8020 二.vue3代码如下 <template><h1>video</h1><video id&…...

springcloud集成gateway

本篇文章只介绍gateway模块的搭建步骤&#xff0c;并无gateway详细介绍 gateway详解请查看&#xff1a;SpringCloudGateway官方文档详解 前置处理 父模块中已指定版本 不知道如何选择版本看这篇&#xff1a; 手把手教你梳理springcloud与springboot与springcloudalibaba的版本…...

2025常用的SEO工具有哪些?

在互联网时代&#xff0c;如何让自己的网站或内容脱颖而出&#xff0c;成为许多企业和个人站长们最关注的问题。而在这个过程中&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;作为一种有效的提升网站曝光度和吸引流量的手段&#xff0c;已经成为了网站运营的核心之一。对…...

C++类和对象进阶:运算符重载深度详解

C类和对象进阶&#xff1a;运算符重载 前言引入运算符重载定义语法注意事项重载为全局函数重载为成员函数运算符重载的本质 默认赋值运算符重载(默认成员函数)编译器自己生成的赋值运算符重载函数需要自己实现的场景总结默认赋值运算符重载 拷贝构造函数和赋值重载的区分验证 总…...

Mybatisplus——Mybatisplus3.5.2版本使用Page分页插件查询,records有数据但是total显示0

目录 一、问题背景 debug 执行Mybatisplus使用Page分页插件查询时&#xff0c;发现 Page 里面的records有数据但是total显示0。 二、问题产生的原因 未配置MybatisPlus的分页插件拦截器导致的或者因mybatis-plus版本3.4或3.5版本导致原先的分页插件paginationInterceptor无法…...

C#(Winform)通过添加AForge添加并使用系统摄像机

先展示效果 AForge介绍 AForge是一个专门为开发者和研究者基于C#框架设计的, 也是NET平台下的开源计算机视觉和人工智能库 它提供了许多常用的图像处理和视频处理算法、机器学习和神经网络模型&#xff0c;并且具有高效、易用、稳定等特点。 AForge主要包括: 计算机视觉与人…...

AI使用场景简单测试

前言 今天来分享下AI的2个实用场景&#xff0c;我这里是使用的博主&#xff1a;小虚竹&#xff0c;搭建的AI服务&#xff0c;用的ChatGPT 4O模型&#xff0c;主要是试了3个场景&#xff0c;服装设计、直播带货话术、检验报告分析。 一、服装设计 对于最后需要的裁片设计上的尺寸…...

Linux 配置 MySQL 定时自动备份到另一台服务器

Linux 配置 MySQL 定时自动备份到另一台服务器 前言1、配置服务器通信1.1&#xff1a;配置过程 2、编写自动备份sh脚本文件3&#xff1a;设置定时自动执行 前言 此方案可使一台服务器上的 MySQL 中的所有数据库每天 0 点自动转储为 .sql 文件&#xff0c;然后将文件同步到另一…...

PostgreSQL 备库的延迟问题

目录标题 1. 查看主备状态计算方式&#xff1a;实际情况&#xff1a;举个例子&#xff1a; 2. 查看历史状态3. 分析日志文件4. 查看数据库层面的复制状态5. 检查活动事务6. 检查系统资源7. 检查网络状况8. 检查复制槽状态9. 检查未提交的两阶段事务 要排查 PostgreSQL 备库的延…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...