UniCacheXML Service
Windows Service that generates XML cache files from UniData/AFTEC on a cron schedule. Provides offline data snapshots consumed by ProApps desktop applications.
Overview
PSI.UniCacheXml.Service (registered as PSIMonitorService) is a .NET Framework 4.8 Windows Service running on PS-WS3. It connects to the AFTEC ERP database on a configurable cron schedule and serializes query results into XML files on the network. ProApps and other consumers read these XML caches instead of hitting UniData directly for common lookup data.
Beyond cache generation, the service also handles email notifications, timesheet processing, and on-demand job requests.
Schedule.xml (cron triggers)
│
▼
PSIMonitorService ──► UniData (MRP-PROD)
│ │
│ ▼
│ Query results
│ │
▼ ▼
XML cache files ◄── Serialize to XML
│
▼
ProApps / consumers read cached XML
| Feature | Description |
|---|---|
| Server | PS-WS3 |
| Service Name | PSIMonitorService |
| Framework | .NET Framework 4.8 (WinExe) |
| Service Account | Local System (automatic start) |
| Version | 1.0.0.6 |
| Scheduling | NCrontab cron expressions in Schedule.xml |
| Logging | log4net → SQL database + email alerts |
Source: C:\git\PSI.All\PSI.Shared\trunk\PSI.Windows.Services\PSI.Monitor.Service (in the PSI.All monorepo)
Cache Files Generated
The service generates 40+ XML cache files at varying frequencies. These are the primary data source for ProApps lookup fields, dropdowns, and list views.
Every 5 Minutes
| File | Data |
|---|---|
| RedBookList.xml | Active Redbook/RFC records |
| ServiceTicketList.xml | Service tickets |
| EngChgList.xml | Engineering change notices |
Every 15 Minutes
| File | Data |
|---|---|
| VendorList.xml | Vendor master list |
Every 30 Minutes
| File | Data |
|---|---|
| Contact1287List.xml | Contact records |
| EmployeePublic1287List.xml | Employee directory |
| ShipToList.xml | Ship-to addresses |
| Account1287List.xml | Customer accounts |
| SPN1287List.xml | SPN records |
| EmailXrefList.xml | Email cross-references |
| QuoteHeadList.xml | Quote headers |
| NCNChangeList.xml | Non-conformance changes |
| InvoiceList.xml | Invoices |
Hourly
| File | Data |
|---|---|
| JobMaster1287List.xml | Job master records |
| Project1287List.xml | Project records |
| TMFList.xml | TMF data |
| Customer1287List.xml | Customer master |
| FOBList.xml | FOB terms |
| IndustryClassList.xml | Industry classifications |
| DispatchFocusCache.xml | Dispatch priority focus |
Every 4 Hours
| File | Data |
|---|---|
| FreightList.xml | Freight records |
Daily (Midnight)
| File | Data |
|---|---|
| CountryList.xml | Country codes |
| EntityTypeList.xml | Entity types |
| StateList.xml | State/province codes |
| CWOXREFList.xml | Cost center / work order cross-ref |
| COCEList.xml | Cost centers |
| MarketSourceList.xml | Market sources |
| PriceCat1287List.xml | Price categories |
| PTIPositionList.xml | PTI positions |
| IndustrySectorList.xml | Industry sectors |
| CustomerAcctTypeList.xml | Customer account types |
| PartTypeList.xml | Part types |
| ProcessTypeList.xml | Process types |
| MachineTypeList.xml | Machine types |
| SPNPositionList.xml | SPN positions |
| SPNStatusList.xml | SPN statuses |
| MachineProcessTypeList.xml | Machine process types |
| SPNReasonList.xml | SPN reasons |
| CompetitorList.xml | Competitors |
| ProjectSalesOrdersList.xml | Project sales orders |
| ProjectStatusList.xml | Project statuses |
| SPNQuoteList.xml | SPN quotes |
Multiple Times Daily
| File | Schedule |
|---|---|
| WO Cache Files | 5:30 AM, 9:30 AM, 12:30 PM, 2:30 PM, 4:30 PM, 5:30 PM |
Additional Functions
Beyond XML cache generation, the service handles several other tasks:
Email Notifications
- Reads pending notifications from UniData
- Resolves Active Directory usernames to email addresses
- Sends HTML emails with To/CC/BCC and file attachments via SMTP
- Updates notification status in database after sending
Timesheet Processing
- Check for Emailed Time Sheets — monitors for emailed timesheet submissions
- Send Missing Time Sheet Email — sends reminders on weekdays at 7:30 AM and 7:30 PM
Job Requests
External systems can trigger on-demand tasks by dropping .rqst files into the job requests directory:
- File format: Line 1 =
Title="<schedule_title>", Line 2 = requestor - Processing: Up to 5 requests in parallel (
MaxDegreeOfParallelism = 5) - Lifecycle: Service updates the file with status/result, then moves it to
History/
Custom UD Commands
The UD Command task type allows executing arbitrary UniData SQL queries and exporting results to XML — useful for ad-hoc data extracts.
Scheduling
Cron Format
Tasks are defined in Schedule.xml using standard 5-field NCrontab cron expressions:
minute hour day-of-month month day-of-week
Example: 30 5,9,12,14,16,17 * * * = 5:30 AM, 9:30 AM, 12:30 PM, 2:30 PM, 4:30 PM, 5:30 PM daily.
Hot Reload
A FileSystemWatcher monitors Schedule.xml. Editing the file reinitializes all timers without restarting the service.
Immediate Execution
Tasks can be flagged with Immediately="true" in the schedule XML to run once on service startup.
Backup Window
Tasks automatically skip the 3:25 AM – 4:00 AM window to avoid conflicts with nightly AFTEC database backups. This window is hardcoded in the service.
Architecture
WCF Service Clients
The service uses three lazy-initialized WCF clients:
| Client | Service | Purpose |
|---|---|---|
| WOClient | WOService | Work order cache operations |
| TimeSheetClient | TimeSheetService | Timesheet email processing |
| DataClient | DataService | General data queries and XML export |
These services inherit from BaseService and use FileBasedCache.Serialize() and BaseController.GetRawData() for data retrieval and XML serialization.
Database Connection
- Database: UniData on MRP-PROD (AFTEC ERP)
- Session:
UDSessionControllerwith credentials fromEnvironmentConstants - Cache paths: Configured via
EnvironmentConstants.CacheFileReadPath/CacheFileWritePath
Thread Safety
ConcurrentDictionarytracks currently running tasks- Same task cannot run concurrently (skipped if already running)
- Each scheduled task runs on its own
System.Timers.Timer
Logging & Error Handling
log4net Configuration
| Appender | Level | Target |
|---|---|---|
| AdoNetAppender | DEBUG+ | SQL database (thread, level, logger, message, exception, user, PC) |
| SMTPAppender | ERROR, FATAL | Email alert to ops team |
Fatal Error Recovery
- Top-level exception handler exits with code 1
- OS service recovery restarts the service automatically
- On startup, clears any stale “Running” status flags from previous crash
Configuration Files
| File | Purpose |
|---|---|
Schedule.xml | Production cron schedule (hot-reloadable) |
Schedule.Debug.xml | Development schedule |
Config/App.Debug.config | Debug environment settings |
Config/App.Beta.config | Beta environment settings |
Config/App.Release.config | Production environment settings |
Config/App.Sandbox.config | Sandbox environment settings |
Dependencies
| Dependency | Purpose |
|---|---|
| NCrontab 3.3.3 | Cron expression parsing |
| log4net | Structured logging |
| PSI.UniSessionManager | UniData session management |
| PSI.Common.Models | Shared data models |
| PSI.Common | Shared utilities |
| PSI.Task.Model | Task tracking models |
Related Pages
- Data Brain — AFTEC ERP and data architecture
- PSI.All Architecture — Monorepo structure
- ProApps — Desktop apps that consume the XML cache files
- UniData API — REST API alternative to XML caching
- U2 Toolkit Migration — UniData connectivity evolution
Last updated: March 2026