PostUpdate Trigger
- PostUpdate Triggers run after a Protrak Type Instance is updated.
- They enable business logic execution based on updated instance values; they only execute after the instance is committed to the database.
- PostUpdate Trigger operate outside the database transaction boundary, meaning they can’t prevent an instance update.
- There may be a slight delay in execution of PostUpdate Trigger due to the asynchronous nature and queue processing time.
Coding guidelines
-
PostUpdate Trigger program is a class that must implement the interface
IPostUpdateTriggerProgramAsyncpublic interface IPostUpdateTriggerProgramAsync
{
Task<ProgramResult> RunAsync(Guid instanceId);
}NOTE: Implement IPostUpdateTriggerProgramAsync with the RunAsync method to enable asynchronous, scalable trigger logic. Most internal service methods are now async, and their synchronous versions are deprecated and will be removed. Use
RunAsyncto ensure compatibility with these changes.
- Protrak runtime passes InstanceID guid of the instance being updated.
- In case of failure in execution of the trigger even after the standard number of retries, the message is sent to dead letter queue and can be re-inserted in queue only by a system administrator. Hence it is very important to write robust code.
Instance "Lock"
- While the execution of
PostUpdatetrigger program is in progress for a given instance, the instance will be "locked" for modifications from any other client application or user.- The user will be unable to modify the given instance from client applications. All action options will be disabled from all layouts.
- If an attempt is made to update the instance from a custom program, an error will appear: "Update already in progress. Please try again later."
- The instance lock will be released once the
PostUpdatetrigger program completes, regardless of success or failure. - Currently, there is no UI indication that the
PostUpdatetrigger is still running, so please consider this scenario carefully before implementing aPostUpdatetrigger program.
Typical use cases for PostUpdate Trigger
- When a value is modified on a parent instance, update corresponding values in child instances.
For example, if the
DrawingRevisionDateis updated on a drawing, ensure the date is synchronized across all related elements. - Use to send notifications to third party systems or email notifications.
Anti-patterns or when not to use PostUpdate Trigger
- Do not add business validations in PostUpdate Trigger. Use PreUpdate for validations.
- Avoid recursive updates by controlling UpdateInstance calls in PostUpdate.
- Optimize trigger conditions to avoid running PostUpdate when not needed.
Example Program
public async Task<ProgramResult> RunAsync(Guid instanceId)
{
var drawingAttributes = new[] { Attribute_DrawingRevisionDate };
var updatedChecklistInstance = await InstanceService.GetInstanceAsync(instanceId, drawingAttributes);
var drawingRevisionDateAttribute = updatedChecklistInstance.Attributes
.FirstOrDefault(a => a.Name == Attribute_DrawingRevisionDate);
if (drawingRevisionDateAttribute?.DateValue != null)
{
// Retrieve all related element instances
// If element's DrawingRevisionDate is different, update it
}
return new ProgramResult { IsSuccess = true, Errors = null };
}
Note:
The Run method (from IPostUpdateTriggerProgram) should only be used if the trigger logic is fully synchronous, does not involve any service/API calls, and consists only lightweight in-memory operations.