/// <summary> ///ReactiveQueue /// </summary> /// <param name="item"></param> void rqueue_DequeueHandler(List <FileArgs> items) { try { //用于处理重复消息 (当更新文件内容时,会产生多个消息) var knownKeys = new HashSet <string>(); //依次处理消息 foreach (var item in items) { //判断消息是否有价值 if (!FileListenHelper.IsMessageValuable(item.FileSystemEventArgs)) { continue; } if (knownKeys.Add(item.FileSystemEventArgs.Name)) { ltm.Handle(item.MonitorServer, item.FileSystemEventArgs); mtm.Handle(item.MonitorServer, item.FileSystemEventArgs); } } } catch (Exception ex) { logger.Error(MessageUtil.GetExceptionMsg(ex, "")); } }
/// <summary> /// 识别消息,插入到数据库 /// </summary> public void Handle(monitorServer ms, FileSystemEventArgs item) { if (item.ChangeType == WatcherChangeTypes.Changed) { //判断消息是否有价值 if (!FileListenHelper.IsMessageValuable(item)) { return; } //封装log对象 并压入队列 InsertLog(ms, item); } }
/// <summary> /// 放弃此 处理 /// </summary> private void FileCheck(monitorServer ms, FileListenResolver flr) { try { #region 维护文件列表数据 try { //判断数据库中对应monitorServer是否为空,如果为空 则不进行比较,直接插入 FileListenService fls = new FileListenService(); if (fls.IsDBCleared(ms.id)) { FileListenHelper.BackupFSWithoutCheck(ms, flr); } else { /** * 数据库数据正确性及完整性维护逻辑 20140706 xiecongwen * 进行比较 此处将不使用自制消息,即数据完整性交由数据库实现 * 为了提高效率:特将比较逻辑移到内存,即从数据库中取一部分数据 * 与文件系统进行比较 看是否存在 * * 两边数据相同:1.文件系统没有的,数据库要删除;文件系统有的,数据库要添加 * * 难点:查找文件是否在数据库中存在 原因:数据量大,且聚集为id * 从根目录开始: 1.目录下文件2.子目录 依次递归 */ } } catch (Exception ex) { logger.Error(MessageUtil.GetExceptionMsg(ex, "")); } #endregion } catch (Exception ex) { logger.Error(MessageUtil.GetExceptionMsg(ex, "")); } }
/// <summary> /// 检验是否有的顶层文件夹被忽略 /// </summary> private void CheckTopFolder() { try { foreach (var ms in new DBService.MonitorServerService().GetMonitorServerListWithAttached()) { //check DirectoryInfo targetDirInfo = new DirectoryInfo(ms.monitorLocalPath); if (targetDirInfo.Exists) { if (targetDirInfo.LastWriteTime.Date < DateTime.Now.Date) { //如果没有传送监控,则发邮件提醒 //new System.Threading.Thread(() => //{ //send mail FileListenHelper.SendMail(targetDirInfo.FullName + " 異常な配信" + " LastWriteTime:" + targetDirInfo.LastWriteTime.ToString(), "異常な配信"); //}).Start(); } } else { //如果没有传送监控,则发邮件提醒 //new System.Threading.Thread(() => //{ //send mail FileListenHelper.SendMail(ms.monitorLocalPath + " 異常な配信" + " LastWriteTime:", "異常な配信"); //}).Start(); } } } catch (Exception ex) { Common.LogManager.WriteLog(Common.LogFile.Error, MessageUtil.GetExceptionMsg(ex, "")); } }
/// <summary> /// 具体业务逻辑 /// </summary> private void DO(CallBack action) { Signal.IsSystemStoping = false; try { Common.LogManager.WriteLog(LogFile.Bussiness, "Listen start"); //判断是否有监视JOB端(即MAC机) foreach (var ms in new DBService.MonitorServerService().GetMonitorServerListWithAttached()) { Common.LogManager.WriteLog(LogFile.Bussiness, ms.id + " attend to Listening"); #region 建立监视 try { DirectoryInfo targetDirInfo = new DirectoryInfo(ms.monitorLocalPath); #region 判断目标盘符是否有足够空间,并提示用户 if (!FileListenHelper.CheckDisk(targetDirInfo)) { new System.Threading.Thread(() => { //send mail FileListenHelper.SendMail(targetDirInfo, ms); }).Start(); } #endregion //将当前已有文件系统信息同步到数据库,然后建立监控 /* * 由于时间原因,暂时认为此程序先开启,然后再开启BudFileListen 20140704 * * 当前逻辑是判断数据库中对应monitorserver是否为空 如果为空则扫描整个文件系统 * 并插入到数据库中 20140705 */ FileListenResolver flr = new FileListenResolver(ms); FileCheck(ms, flr); #region 设置监视器 FileSystemWatcher fsw = new FileSystemWatcher() { //只监听文件创建、删除、文件大小变化,忽略目录变化 NotifyFilter = NotifyFilters.Size | NotifyFilters.FileName, //Filter="*", Path = ms.monitorLocalPath, IncludeSubdirectories = true }; //设置事件 flr.SetEvent(fsw); fsw.EnableRaisingEvents = true; fswlist.Add(fsw); #endregion } catch (ArgumentException aex) { Common.LogManager.WriteLog(LogFile.Bussiness, ms.id + " error:" + aex.Message); //回调错误处理函数 if (action(aex)) { //用户选择退出时,当前线程直接退出,并新建一个线程去清理资源 ThreadPool.QueueUserWorkItem((x) => { Thread.Sleep(1000); ShutDown(); }); break; } continue; } catch (Exception ex) { logger.Error(ex.Message); action(ex); break; } //日志 通知 此monitorserver已经建立监听 Common.LogManager.WriteLog(LogFile.Bussiness, ms.id + " Listening"); #endregion } //开启定时同步线程 new System.Threading.Thread(() => SyncFileSystemAndDB()).Start(); } catch (Exception ex) { logger.Error(MessageUtil.GetExceptionMsg(ex, "")); action(ex); } finally { //所有server 都处理了 Common.LogManager.WriteLog(LogFile.Bussiness, "All servers have been processed"); } }