/// <summary> /// 执行远程事件超时 /// </summary> /// <param name="queueId"></param> /// <param name="key"></param> /// <param name="callback"></param> public static void Timeout(Guid queueId, EventKey key, EventCallback callback) { TimeoutManager.End(key); //首先释放资源,删除为了收取信息而建立的临时队列 CleanupRemoteEventResult(key.EventName, key.EventId); //记录异常状态 DataContext.NewScope(() => { var queue = EventQueue.Find(queueId); if (queue.IsEmpty()) { return; } var entry = queue.GetEntry(key.EventId); if (entry.IsEmpty() || entry.IsLocal) { return; } entry.Status = EventStatus.TimedOut; EventQueue.Update(queue); }, true); //抛出执行失败的异常 throw new RemoteEventFailedException(Strings.ExecuteRemoteEventTimeout); }
/// <summary> /// 完成远程事件 /// </summary> /// <param name="event"></param> private static void CompleteRemoteEvent(Guid queueId, DTObject @event, EventKey key) { if (!TimeoutManager.End(key)) { return; //如果结束失败,证明已超时了 } //首先释放资源,删除为了收取信息而建立的临时队列 CleanupRemoteEventResult(key.EventName, key.EventId); //再处理结果 var success = @event.GetValue <bool>("success"); var message = @event.GetValue <string>("message"); if (!success) { //如果没有执行成功,那么抛出异常 throw new RemoteEventFailedException(message); } var args = @event.GetObject("args"); DataContext.NewScope(() => { var queue = EventQueue.Find(queueId); if (queue.IsEmpty()) { //短期内事件队列不存在只有一个原因,那就是由于回逆而被删除了 //长期内事件不存在,那是因为为防止数据过多导致性能下降,已完成的过期队列会被删除,这种情况下不可能被继续调用,不会执行到这里来 throw new DomainEventException(string.Format(Strings.QueueNotExistWithCallbackTip, queue.Id)); } var entry = queue.GetEntry(key.EventId); if (entry.IsEmpty()) { throw new DomainEventException(string.Format(Strings.EventEntryNotExistWithCallbackTip, queue.Id, entry.EventId)); } if (entry.IsLocal) //本地事件是不能继续触发的,这明显是个致命错误 { throw new DomainEventException(string.Format(Strings.ContinueNotWithLocal, entry.EventName)); } if (entry.Status == EventStatus.TimedOut) //已经超时了,抛出异常 { throw new RemoteEventFailedException(Strings.ExecuteRemoteEventTimeout); } //远程事件执行完毕后,用它所在的源事件接受结果 var source = entry.GetSourceEvent(); source.ApplyResult(entry.EventName, args); entry.Status = EventStatus.Raised; EventQueue.Update(queue); }, true); }
private static void RaiseRemoteEvent(EventEntry entry, dynamic identity, DTObject args) { entry.Status = EventStatus.Raising; //先订阅触发事件的返回结果的事件 SubscribeRemoteEventResult(entry.EventName, entry.EventId); //再发布“触发事件”的事件 var raiseEventName = EventUtil.GetRaise(entry.EventName); EventPortal.Publish(raiseEventName, entry.GetRemotable(identity, args)); //触发远程事件就是发布一个“触发事件”的事件 ,订阅者会收到消息后会执行触发操作 TimeoutManager.Start(new EventKey(entry.EventId, entry.EventName)); }