/// <summary> /// 合并 /// 仅定时线程调用 /// </summary> /// <param name="node"></param> public void Concat(AqiRetryNode node) { thisLock.EnterWriteLock(); try { this.isu = node.isu; this.ap = node.ap; this.starttime = DateTime.Now; this.endtime = DateTime.Now; this.count = 1; //将NAME_DATA计数保留,其他清空 int i = 0; if (this.counts.ContainsKey(NAME_DATA)) { i = this.counts[NAME_DATA]; } this.counts.Clear(); this.counts.Add(NAME_DATA, i); this.counts = this.counts.Concat(node.counts).ToDictionary(x => x.Key, y => y.Value); AddNameCount(NAME_DATA); } finally { thisLock.ExitWriteLock(); } }
/// <summary> /// 添加历史 /// </summary> /// <param name="arn"></param> public AqiRetryNode AddHistory(AqiRetryNode arn) { AqiRetryNode n = null; bool bHasHistory = false; historyLock.EnterUpgradeableReadLock(); try { bHasHistory = history.ContainsKey(arn.NAME); if (bHasHistory) { n = history[arn.NAME]; if (n.IsValid()) { Console.WriteLine("上次时区数据已经丢失,此时区又出现错误"); //历史有效,合并数据 n.Concat(arn); } else { //历史无效,替换数据 historyLock.EnterWriteLock(); try { history[arn.NAME] = arn; } finally { historyLock.ExitWriteLock(); } } } else { historyLock.EnterWriteLock(); try { history.Add(arn.NAME, arn); } finally { historyLock.ExitWriteLock(); } } n = history[arn.NAME]; } finally { //退出升级锁。 historyLock.ExitUpgradeableReadLock(); } return n; }
/// <summary> /// 更新计数 /// </summary> /// <param name="arn"></param> /// <param name="ex"></param> /// <returns></returns> private bool updateNode(AqiRetryNode arn, Exception ex) { //初始化统计计数 if (ex is WebException) { //可忽略错误 WebException we = ex as WebException; if (we.Status == WebExceptionStatus.Timeout) { //统计超时次数 arn.AddNameCount(AqiRetryNode.NAME_TIMEOUT); } else { //统计网络错误次数 arn.AddNameCount(AqiRetryNode.NAME_WEB); } } else { //不可忽略错误 arn.AddNameCount(AqiRetryNode.NAME_OTHER); Console.WriteLine("不可忽略错误,数据源接口可能变更"); Console.WriteLine(ex.Message); return false; } return true; }
/// <summary> /// 重试处理 /// </summary> /// <param name="arn"></param> private bool retryProcess(AqiRetryNode arn) { ISrcUrl isu = arn.SRCURL; AqiParam ap = arn.PARAM; byte[] data = null; try { if (ap != null) { data = isu.getDate(ap); } else { data = isu.getDate(); } } catch (Exception ex) { //再 入重试队列 PutAgain(arn, ex); return false; } am.AqiRun.saveProcess(isu, ap, data); //重置 arn.Reset(); return true; }
/// <summary> /// 入重试队列 /// 定时器线程 /// </summary> /// <param name="isu"></param> /// <param name="ap"></param> /// <param name="ex"></param> public void PutNew(ISrcUrl isu, AqiParam ap, Exception ex) { //封装为重试节点 AqiRetryNode arn = new AqiRetryNode(isu, ap); //更新计数 if (!updateNode(arn, ex)) { return; } //添加历史记录 arn = AddHistory(arn); //入队列 Push(arn.NAME); }
/// <summary> /// 再次入重试队列 /// 循环线程 /// </summary> /// <param name="arn"></param> /// <param name="ex"></param> public void PutAgain(AqiRetryNode arn, Exception ex) { //更新计数 if (!updateNode(arn, ex)) { return; } //检查有效性 if (!arn.IsValid()) { //读取配置 if (AqiManage.Setting.Get<bool>("AqiRetryer.AlwayRetry")) { //继续重试 Console.WriteLine("重试已经无效,仍然尝试重试"); } else { //停止重试 Console.WriteLine("重试已经无效,暂停"); return; } } //入队列:继续重试 Push(arn.NAME); Console.WriteLine("再入重试队列"); }