/// <summary> /// 重试处理 /// 应该由Retryer线程调用 /// </summary> /// <param name="arn">重试节点</param> /// <returns></returns> public bool RetryProcess(RetryNode arn) { ISrcUrl isu = arn.SrcUrl; AqiParam ap = arn.Param; byte[] data = null; try { if (isu is ISrcUrlParam) { ISrcUrlParam isup = isu as ISrcUrlParam; data = isup.GetData(ap); } else { data = isu.GetData(); } } catch (Exception ex) { AqiManage.Remind.Log_Error("数据重试失败,再入重试队列", new string[] { this.name, arn.Name, isu.Name }); this.ar.PutAgain(arn, ex); return(false); } this.SaveProcess(data, isu, ap); arn.Reset(); return(true); }
public void HaltsAfterFailure() { var n = new InMemoryVariable <int>(0); var child = new ReturnXNode(NodeStatus.FAILURE); var node = new RetryNode(child, n); var status = node.Tick(); Assert.That(status, Is.EqualTo(NodeStatus.FAILURE)); Assert.That(child.Halts, Is.EqualTo(1)); }
public void HaltsAfterSuccess() { var n = new InMemoryVariable <int>(0); var child = new ReturnXNode(NodeStatus.SUCCESS); var node = new RetryNode(child, n); var status = node.Tick(); Assert.That(status, Is.EqualTo(NodeStatus.SUCCESS)); Assert.That(child.Halts, Is.EqualTo(1)); }
public void ReturnsSuccessImmediately() { var n = new InMemoryVariable <int>(0); var child = new ReturnXNode(NodeStatus.SUCCESS); var node = new RetryNode(child, n); var status = node.Tick(); Assert.That(status, Is.EqualTo(NodeStatus.SUCCESS)); Assert.That(child.Ticks, Is.EqualTo(1)); }
/// <summary> /// 循环线程 /// </summary> private void threadRun() { while (true) { //取队列(无数据会堵塞) string name = Pop(); RetryNode arn = GetHistory(name); this.am[arn.RunnerName].RetryProcess(arn); Thread.Sleep(500); } }
public void DoesNotHaltAfterRunning(int n) { var child = new ReturnXNode(NodeStatus.RUNNING); var node = new RetryNode(child, new InMemoryVariable <int>(n)); for (int i = 0; i < n; i++) { var status = node.Tick(); Assert.That(status, Is.EqualTo(NodeStatus.RUNNING)); } Assert.That(child.Ticks, Is.EqualTo(n)); Assert.That(child.Halts, Is.EqualTo(0)); }
/// <summary> /// 入重试队列 /// 定时器线程 /// </summary> /// <param name="arName"></param> /// <param name="isu"></param> /// <param name="ap"></param> /// <param name="ex"></param> public void PutNew(string arName, ISrcUrl isu, AqiParam ap, Exception ex) { //封装为重试节点 RetryNode arn = new RetryNode(arName, isu, ap); arn.NodeEvent += new RetryNode.NodeEventHandler(this.node_RunEvent); //更新计数 arn.Update(ex); //添加历史记录 arn = this.AddHistory(arn); //入队列 this.Push(arn.Name); AqiManage.Remind.Log_Info("已添加到重试队列", new string[] { this.name, arn.RunnerName, arn.Name }); }
public void ReturnsFailureAfterNFailures(int n) { var child = new ReturnXNode(NodeStatus.FAILURE); var node = new RetryNode(child, new InMemoryVariable <int>(n)); for (int i = 0; i < n; i++) { Assert.That(node.Tick(), Is.EqualTo(NodeStatus.RUNNING)); } Assert.That(node.Tick(), Is.EqualTo(NodeStatus.FAILURE)); // ticked once at the beginning and once more for every tick that returned failure until n Assert.That(child.Ticks, Is.EqualTo(n + 1)); }
/// <summary> /// 添加历史 /// </summary> /// <param name="arn"></param> public RetryNode AddHistory(RetryNode arn) { RetryNode node = null; this.historyLock.EnterUpgradeableReadLock(); try { if (this.history.ContainsKey(arn.Name)) { node = this.history[arn.Name]; if (node.IsValid()) { AqiManage.Remind.Log_Debug("上次时区数据已经丢失,此时区又出现错误", new string[] { this.name, arn.RunnerName }); node.Concat(arn); } else { this.historyLock.EnterWriteLock(); try { this.history[arn.Name] = arn; } finally { this.historyLock.ExitWriteLock(); } } } else { this.historyLock.EnterWriteLock(); try { this.history.Add(arn.Name, arn); } finally { this.historyLock.ExitWriteLock(); } } node = this.history[arn.Name]; } finally { this.historyLock.ExitUpgradeableReadLock(); } return(node); }
/// <summary> /// 得到历史 /// </summary> /// <param name="name"></param> /// <returns></returns> public RetryNode GetHistory(string name) { RetryNode node = null; this.historyLock.EnterReadLock(); try { if (this.history.ContainsKey(name)) { node = this.history[name]; } } finally { this.historyLock.ExitReadLock(); } return(node); }
/// <summary> /// 再次入重试队列 /// 循环线程 /// </summary> /// <param name="arn"></param> /// <param name="ex"></param> public void PutAgain(RetryNode arn, Exception ex) { //更新计数 arn.Update(ex); //检查有效性 if (!arn.IsValid()) { //读取配置 if (AqiManage.Setting.Get <bool>("AqiRetryer.AlwayRetry")) { //继续重试 AqiManage.Remind.Log_Debug("重试已经无效,仍然尝试重试", new string[] { this.name, arn.RunnerName }); } else { //停止重试 AqiManage.Remind.Log_Error("重试已经无效,暂停", new string[] { this.name, arn.RunnerName }); return; } } //入队列:继续重试 this.Push(arn.Name); AqiManage.Remind.Log_Info("已添加到重试队列", new string[] { this.name, arn.RunnerName, arn.Name }); }