Repository navigation
[Server] Implement event-driven RolePermissionsValidation caching in MonitoredNode2 - #3583
Conversation
|
|
…ing in MonitoredNode2 Co-authored-by: romanett <7413710+romanett@users.noreply.github.com>
|
@copilot RolePermissions validation is more complex than that for each NamespaceMetaDataState there can be DefaultRolePermissions and also DefaultUserRolePermissions. Those can change also |
…andle namespace-level default permission changes Co-authored-by: romanett <7413710+romanett@users.noreply.github.com>
Good point. I've extended the permission cache invalidation to also cover namespace-level defaults in commit fc6d418. What changed:
|
Proposed changes
ValidateRolePermissionswas called for every monitored item on every node value change — O(clients × writes/sec) permission lookups that include a node metadata fetch per call. Under high-load scenarios this severely limits write throughput.NodeStateChangeMasks.RolePermissions(new flag inNodeState.cs)Added
RolePermissions = 0x20toNodeStateChangeMasks. This flag is set (alongsideNonValue) whenRolePermissionsorUserRolePermissionschange — either via property setter or an OPC UA client write (WriteNonValueAttribute). This gives subscribers a precise signal that permissions have changed without conflating it with other non-value attribute changes.Permission result caching in
MonitoredNode2m_permissionCache: ConcurrentDictionary<uint, ServiceResult>— caches theValidateRolePermissionsresult per monitored item ID.ValidateRolePermissionson a cache miss.NodeStateChangeMasks.RolePermissionsdetected: clears the entire permission cache so all items are re-validated on the next value change.GetOrCreateContext): removes the affected item's permission cache entry alongside the existing context cache invalidation.Namespace-level default permissions support (
IConfigurationNodeManager/ConfigurationNodeManager)Validation also depends on
DefaultRolePermissionsandDefaultUserRolePermissionsfromNamespaceMetadataState. Changes to these namespace-level defaults now also invalidate the permission cache:event EventHandler DefaultPermissionsChangedtoIConfigurationNodeManager.ConfigurationNodeManager.CreateNamespaceMetadataState()subscribes toDefaultRolePermissions.StateChangedandDefaultUserRolePermissions.StateChangedon eachNamespaceMetadataState. When either fires with aValuemask,DefaultPermissionsChangedis raised.MonitoredNode2subscribes tom_server.ConfigurationNodeManager.DefaultPermissionsChangedwhen the first monitored item is added, clears the entire permission cache when it fires, and unsubscribes when the last item is removed.Related Issues
Types of changes
Checklist
Further comments
The
RolePermissionschange mask is a strict subset ofNonValue— both bits are always set together when permissions change, so existing code that checksNonValuecontinues to work unchanged. The caching is conservative: any ambiguous invalidation trigger (identity change, context expiry, node-levelRolePermissionsmask, or namespace-levelDefaultPermissionsChangedevent) causes a full re-validation, so correctness is maintained at the cost of at most one extra validation call per trigger event.Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.