【Orleans开胃菜系列1】不要被表象迷惑
Orleans之开胃小菜
SafeExecute安全执行
翻看Orleans源码时,发现一句SafeExecute,就以为是什么没接触过的很深的东西。那么SafeExecute到底是什么玩意呢?
Utils.SafeExecute(() => { if (typeMapRefreshTimer != null) { typeMapRefreshTimer.Dispose(); typeMapRefreshTimer = null; } }, logger, "Client.typeMapRefreshTimer.Dispose");
接下来追踪代码如下,原来主要逻辑就是加try,catch不引发异常。
public static void SafeExecute(Action action, ILogger logger, Func<string> callerGetter) { try { action(); } catch (Exception exc) { try { if (logger != null) { string caller = null; if (callerGetter != null) { try { caller = callerGetter(); }catch (Exception) { } } foreach (var e in exc.FlattenAggregate()) { logger.Warn(ErrorCode.Runtime_Error_100325, $"Ignoring {e.GetType().FullName} exception thrown from an action called by {caller ?? String.Empty}.", exc); } } } catch (Exception) { // now really, really ignore. } } }
ExecuteWithRetries重试机制
还有例如以下代码,顾名思义就是支持重试执行
await ExecuteWithRetries( async () => this.GrainTypeResolver = await transport.GetGrainTypeResolver(this.InternalGrainFactory), retryFilter);
跟踪源码如下:
综合考虑最晚执行时间,成功执行次数,失败执行次数等因素,延迟回调.
利用do..while,Task,Func等知识来完成延时重试,并不算太复杂。
public static Task ExecuteWithRetries( Func<int, Task> action, int maxNumErrorTries, Func<Exception, int, bool> retryExceptionFilter, TimeSpan maxExecutionTime, IBackoffProvider onErrorBackOff) { Func<int, Task<bool>> function = async (int i) => { await action(i); return true; }; return ExecuteWithRetriesHelper<bool>( function, 0, 0, maxNumErrorTries, maxExecutionTime, DateTime.UtcNow, null, retryExceptionFilter, null, onErrorBackOff); } private static async Task<T> ExecuteWithRetriesHelper<T>( Func<int, Task<T>> function, int callCounter, int maxNumSuccessTries, int maxNumErrorTries, TimeSpan maxExecutionTime, DateTime startExecutionTime, Func<T, int, bool> retryValueFilter = null, Func<Exception, int, bool> retryExceptionFilter = null, IBackoffProvider onSuccessBackOff = null, IBackoffProvider onErrorBackOff = null) { T result = default(T); ExceptionDispatchInfo lastExceptionInfo = null; bool retry; do { retry = false; if (maxExecutionTime != Constants.INFINITE_TIMESPAN && maxExecutionTime != default(TimeSpan)) { DateTime now = DateTime.UtcNow; if (now - startExecutionTime > maxExecutionTime) { if (lastExceptionInfo == null) { throw new TimeoutException( $"ExecuteWithRetries has exceeded its max execution time of {maxExecutionTime}. Now is {LogFormatter.PrintDate(now)}, started at {LogFormatter.PrintDate(startExecutionTime)}, passed {now - startExecutionTime}"); } lastExceptionInfo.Throw(); } } int counter = callCounter; try { callCounter++; result = await function(counter); lastExceptionInfo = null; if (callCounter < maxNumSuccessTries || maxNumSuccessTries == INFINITE_RETRIES) // -1 for infinite retries { if (retryValueFilter != null) retry = retryValueFilter(result, counter); } if (retry) { TimeSpan? delay = onSuccessBackOff?.Next(counter); if (delay.HasValue) { await Task.Delay(delay.Value); } } } catch (Exception exc) { retry = false; if (callCounter < maxNumErrorTries || maxNumErrorTries == INFINITE_RETRIES) { if (retryExceptionFilter != null) retry = retryExceptionFilter(exc, counter); } if (!retry) { throw; } lastExceptionInfo = ExceptionDispatchInfo.Capture(exc); TimeSpan? delay = onErrorBackOff?.Next(counter); if (delay.HasValue) { await Task.Delay(delay.Value); } } } while (retry); return result; } }
耐心求索
很多基础性的实现并不完全依赖高深隐秘的技术,多思考,多实践。只要思路正确,慢慢修养,星星之火总能燎原。
众所周知,.net的应用层每隔几年总会变化,像aspx现在是完全放弃了的。.netcore现在日益火热,但不见的得持久恒定。在有限的时间内,为了不让知识贬值,除了快速学习新知识外,更要注意基础知识的沉淀。就像上面的两个例子,无论方法名,基础思想在那放着,不会太变质。
但这些是远远不够的。变化的永远是上层。沉淀到基础层次,如进程线程之类的,就比较稳定了。除了这些代码层次的,更重要的是思想的沉淀,如《人月神话》《失控》《领域驱动涉及》,敏捷开发等方法论,依然很有用,更加基础的冯诺依曼计算器体系结构更是奠基者。
理论才是跨各种语言平台的。只记得一些方法命名空间而根基不扎实的,是无根之木。
未来的日子,勉励自己继续扩充理论知识。
分类:
微软分布式框架Orleans
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述