Write the default plugin handler
- Last UpdatedApr 08, 2026
- 3 minute read
This scenario guides you through the steps required to write the High Performance Data Export Framework (HPDEF) plugin code for the default handler. For data export targets to handle incoming data that does not have a table-specific plugin, you must, at a minimum, create a default plugin handler for each target. Follow the steps below to create a default handler that the system invokes whenever a record is changed in a table for which data export is enabled, but where a table-specific handler is not specified.
To identify the code associated with each step, see the code comments in the Example code section.
To write the default plugin handler
In this example, the default handler code is written to a file called DefaultHandler.cs.
- In the created project used to implement the default plugin handler code, open or create the class file.
- Set the class to implement the IRecordHandler interface.
- Create the IsInterestedIn() method where the system writes the logic that determines which records should be considered for export:
- Use the old and new versions of the record to determine whether the changes are of interest to the handler.
- Return true if the handler is interested in the record; otherwise, return false.
- Create the ExportRecord() method where the system writes the record processing logic:
- If required, use the old and new versions of the record to perform any custom processing on the record.
Example code
using System;
using OASySDNA.Common.Logging;
using OASySDNA.RealTime.Data.Common.HighPerformanceSetDBWrapper.Interfaces;
namespace OASySDNA.RealTime.DataExport.ExamplePlugin
{
/// <summary>
/// Defaulthandler : If a custom plugin does not exist, then this default Handler for that
/// Data Export target is called. This default Handler will probably do nothing.
/// </summary>
public sealed class DefaultHandler : IRecordHandler
{
public String Name { get; } = "Default Record Handler";
public String TableName { get; }
public readonly Int32 RecordNumberThreshold = 500000;
private IDNALog DNALog { get; }
public DefaultHandler(String tableName) : this(tableName, DNALogAdapter.Instance) { }
internal DefaultHandler(String tableName, IDNALog dnaLog)
{
TableName = tableName;
DNALog = dnaLog;
}
/// <summary>
/// Do default processing if required.
/// In most cases, this method will do nothing.
/// </summary>
/// <param name="message">The DataExport message for the record.</param>
public void ExportRecord(DataExportMessage message)
{
var recordNumber = message.RecordNumber;
var newRecord = message.NewRecord;
var oldRecord = message.OldRecord;
var recordChangeTime = message.RecordChangeTime;
if(recordChangeTime.high != 0 || recordChangeTime.low != 0)
{
DNALog.Verbose(quot;Default handler invoked with RecordChangeTime {recordChangeTime.high}.{recordChangeTime.low} on {newRecord.TableName} for record number {recordNumber}");
}
switch (newRecord.TableName)
{
case "analog":
case "status":
case "rate":
case "multistate":
case "rtstring":
DNALog.Always(quot;Default handler invoked on supported table {newRecord.TableName} for record number {recordNumber}");
break;
default:
DNALog.Always(quot;Default handler invoked on unsupported table {newRecord.TableName} for record number {recordNumber}");
break;
}
}
/// <summary>
/// Decides if this record number from a RealTime database (RTDB) table should be considered for export.
/// This decision is made at the earliest spot in the upstream process to avoid
/// un-interesting records being passed through different stages.
/// </summary>
/// <param name="message">The DataExport message for the record.</param>
/// <returns> True if interested, thus allowing the record to be passed to this handler.</returns>
public Boolean IsInterestedIn(DataExportMessage message)
{
// Change this condition to a group of RTDB table slot numbers that data export is interested in.
return (message.RecordNumber < RecordNumberThreshold);
}
}
}