Class AppointmentPushNotificationDispatcher
Hosted service that drains the appointment push-notification queue produced by AppointmentMatrix and sends the notifications via NotificationEventHandler.
Inheritance
Inherited Members
Namespace: SuperOffice.CRM.Notification
Assembly: SoDataBase.BusinessLogic.dll
Syntax
public class AppointmentPushNotificationDispatcher : AsyncQueueProcessor<IAsyncQueue<AppointmentPushNotificationTask>, AppointmentPushNotificationTask>, IDisposable, IHostedService
Remarks
Sending push notifications involves a call to an external service (Central Services) per recipient device, each taking from tens of milliseconds up to several seconds. Previously this was done sequentially on the save/delete request thread; moving it here both decouples it from the originating request and lets the recipients of a single appointment be processed in parallel. Concurrency is deliberately bounded (SuperOffice.CRM.Notification.AppointmentPushNotificationDispatcher.MaxDegreeOfParallelism) to avoid overwhelming / being throttled by the external service.
Each send does database-scoped work (resolving caches, reading device rows). Because several run concurrently, each is dispatched through RunInUserContext(Action, CancellationToken) so it gets its own service-provider scope and re-signed user rather than sharing request/database scoped state - the established pattern for parallel database work in this codebase.Constructors
AppointmentPushNotificationDispatcher(IAsyncQueue<AppointmentPushNotificationTask>, ILogger<AppointmentPushNotificationDispatcher>)
Hosted service that drains the appointment push-notification queue produced by AppointmentMatrix and sends the notifications via NotificationEventHandler.
Declaration
public AppointmentPushNotificationDispatcher(IAsyncQueue<AppointmentPushNotificationTask> queue, ILogger<AppointmentPushNotificationDispatcher> logger)
Parameters
| Type | Name | Description |
|---|---|---|
| IAsyncQueue<AppointmentPushNotificationTask> | queue | |
| ILogger<AppointmentPushNotificationDispatcher> | logger |
Remarks
Sending push notifications involves a call to an external service (Central Services) per recipient device, each taking from tens of milliseconds up to several seconds. Previously this was done sequentially on the save/delete request thread; moving it here both decouples it from the originating request and lets the recipients of a single appointment be processed in parallel. Concurrency is deliberately bounded (SuperOffice.CRM.Notification.AppointmentPushNotificationDispatcher.MaxDegreeOfParallelism) to avoid overwhelming / being throttled by the external service.
Each send does database-scoped work (resolving caches, reading device rows). Because several run concurrently, each is dispatched through RunInUserContext(Action, CancellationToken) so it gets its own service-provider scope and re-signed user rather than sharing request/database scoped state - the established pattern for parallel database work in this codebase.Methods
ProcessItemAsync(IAsyncQueueProcessItemContext<AppointmentPushNotificationTask>, CancellationToken)
Process an item from the queue
Declaration
protected override Task ProcessItemAsync(IAsyncQueueProcessItemContext<AppointmentPushNotificationTask> context, CancellationToken cancellationToken)
Parameters
| Type | Name | Description |
|---|---|---|
| IAsyncQueueProcessItemContext<AppointmentPushNotificationTask> | context | Context of item to be processed |
| CancellationToken | cancellationToken |
Returns
| Type | Description |
|---|---|
| Task |
Overrides
Remarks
Sending push notifications involves a call to an external service (Central Services) per recipient device, each taking from tens of milliseconds up to several seconds. Previously this was done sequentially on the save/delete request thread; moving it here both decouples it from the originating request and lets the recipients of a single appointment be processed in parallel. Concurrency is deliberately bounded (SuperOffice.CRM.Notification.AppointmentPushNotificationDispatcher.MaxDegreeOfParallelism) to avoid overwhelming / being throttled by the external service.
Each send does database-scoped work (resolving caches, reading device rows). Because several run concurrently, each is dispatched through RunInUserContext(Action, CancellationToken) so it gets its own service-provider scope and re-signed user rather than sharing request/database scoped state - the established pattern for parallel database work in this codebase.SendNotificationAsync(AppointmentPushNotificationRecipient, bool, CancellationToken)
Sends a single push notification. Virtual so tests can substitute the external call.
Declaration
protected virtual Task SendNotificationAsync(AppointmentPushNotificationRecipient recipient, bool sendMessageToOurself, CancellationToken cancellationToken)
Parameters
| Type | Name | Description |
|---|---|---|
| AppointmentPushNotificationRecipient | recipient | |
| bool | sendMessageToOurself | |
| CancellationToken | cancellationToken |
Returns
| Type | Description |
|---|---|
| Task |
Remarks
Sending push notifications involves a call to an external service (Central Services) per recipient device, each taking from tens of milliseconds up to several seconds. Previously this was done sequentially on the save/delete request thread; moving it here both decouples it from the originating request and lets the recipients of a single appointment be processed in parallel. Concurrency is deliberately bounded (SuperOffice.CRM.Notification.AppointmentPushNotificationDispatcher.MaxDegreeOfParallelism) to avoid overwhelming / being throttled by the external service.
Each send does database-scoped work (resolving caches, reading device rows). Because several run concurrently, each is dispatched through RunInUserContext(Action, CancellationToken) so it gets its own service-provider scope and re-signed user rather than sharing request/database scoped state - the established pattern for parallel database work in this codebase.