/// <summary> /// 触发队列事件 /// </summary> /// <param name="queue"></param> private static void Raise(Guid queueId, EventCallback callback) { bool isSucceeded = false; bool isRunning = false; while (!isRunning && !isSucceeded) { DataContext.NewScope(() => { //触发队列事件 var queue = EventQueue.Find(queueId); var entry = queue.GetPreRaise(); if (!entry.IsEmpty()) { var args = entry.GetArgs(); //获取条目的事件参数 EventLog.FlushRaise(queue, entry); if (entry.IsLocal) { var source = entry.GetSourceEvent(); var local = EventFactory.GetLocalEvent(entry, args, true); RaiseLocalEvent(entry, local, source); } else { var identity = queue.GetIdentity(); RaiseRemoteEvent(entry, identity, args); } } EventQueue.Update(queue); isRunning = queue.IsRunning; isSucceeded = queue.IsSucceeded; }, true); } bool completed = false; DomainEvent @event = null; if (isSucceeded) { DataContext.NewScope(() => { var queue = EventQueue.Find(queueId); if (queue.IsSubqueue) { var entry = queue.Source; var argsCode = entry.ArgsCode; var identity = queue.GetIdentity(); var eventName = entry.EventName; var eventId = entry.EventId; callback.Mount(() => //挂载回调事件,这样所有操作执行完毕后,会发布事件被完成的消息 { //发布事件被完成的消息 PublishRaiseSucceeded(identity, eventName, eventId, argsCode); }); } else { //不是被外界调用的,所以整个事件场景已完成 completed = true; @event = queue.Source.GetSourceEvent(); } }, true); EventLog.FlushEnd(queueId); //指示恢复管理器事件队列的操作已经全部完成 } if (completed) { callback.Mount(() => //挂载回调事件 { DomainEvent.OnSucceeded(queueId, @event); }); } }
/// <summary> /// 有两种情况会恢复: /// 1.调用方主动要求恢复(这一般是因为调用方出了错误,要求被调用的领域事件恢复),这时候本地的事件队列就算是成功执行完毕的(非中断),也需要恢复 /// 2.本地机器故障或业务错误,要求恢复 /// </summary> /// <param name="queueId"></param> /// <param name="reason"></param> /// <param name="forceRestore">即使监视器不会中断的,也要回逆,这一般是因为调用方发布的回逆要求</param> /// <returns></returns> public static bool TryRestore(Guid queueId, Exception reason, bool forceRestore) { bool success = false; //是否成功恢复 try { DataContext.NewScope(() => { var @lock = EventLock.Find(queueId, QueryLevel.Single);//这段代码将入口锁住,所以监视器和队列也间接被锁住了 if (@lock.IsEmpty()) { return; //没有锁,那么意味着队列及相关的数据已被恢复了 } var monitor = EventMonitor.Find(queueId); var queue = EventQueue.Find(queueId); if (queue.IsEmpty()) { //队列不存在,要么是队列已被恢复了,要么就是队列还没初始化之前,就被终止了 //删除监视器 if (!monitor.IsEmpty()) { EventMonitor.Delete(monitor); } //删除锁 EventLock.Delete(@lock); success = true; return; } if (!forceRestore && !monitor.Interrupted) { //由于中断的监视器有可能是正在运行中的(正在执行的队列我们会把监视器设置为中断,当队列执行完毕后恢复为非中断),所以这类监视器运行完毕后,就不再中断了 //所以就不需要恢复 success = false; return; } //防止恢复过程中也断电或故障,这里主动设置为中断的 monitor.Interrupted = true; EventMonitor.UpdateAndFlush(monitor); Restore(queueId, reason); //恢复完毕后,删除监视器 EventMonitor.Delete(monitor); //删除锁 EventLock.Delete(@lock); }, true); DomainEvent.OnFailed(queueId, new EventFailedException(reason)); success = true; } catch (EventRestoreException) { //Restore方法已写入日志,就不再写入 DomainEvent.OnError(queueId, new EventErrorException(reason)); throw; } catch (Exception ex) { LogWrapper.Default.Fatal(ex); } return(success); }