Base solution for your next web application
Open Closed

Can we trigger EventBus on the server and catch abp.event.on #11469


User avatar
0
kfrancis created

We have been trying to use notifications but we're getting SQL timeouts because I gather we're abusing notifications so we'd like to use EventBus but it doesn't look like events triggered on the server can be observed client side, is that correct?

We essentially have a background job that is gathering information from a very slow API and we'd like to continue to notify the user when actions are still occurring, but not using IAppNotifier (as it causes the DB timeout issues).

We are thinking about using a SignalR hub that can handle IAsyncEventHandler<SuperCoolEvents> and then send a message to the user by user id which then does the abp.event.trigger with the same data.

If it does work, it'd be nice to see this in the system generally - though it sounds like this would only work if SignalR is enabled, not sure how you'd do it otherwise.


4 Answer(s)
  • User Avatar
    0
    kfrancis created

    If you look here, you're translating a server "event" into a client-side using an IIFE- but obviously, that won't work in the context of a background job:

    script.AppendLine("(function(){");
                script.AppendLine("    abp.event.trigger('abp.dynamicScriptsInitialized');");
                script.Append("})();");
    
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @kfrancis

    What you are trying to do is definitely a sample usage of notifications. Do you have any error log messages about DB timeout issues ?

    Thanks,

  • User Avatar
    0
    kfrancis created

    Here you go:

    URL: (POST) /api/services/app/Notification/SetNotificationAsRead
    Hostname: WN0LDWK0002LC
    Status Code: 500
    Type: System.ComponentModel.Win32Exception
    Message: The wait operation timed out.
    Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while saving the entity changes. See the inner exception for details.
     ---> Microsoft.Data.SqlClient.SqlException (0x80131904): Execution Timeout Expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.
     ---> System.ComponentModel.Win32Exception (258): The wait operation timed out.
       at Task<DbDataReader> Microsoft.Data.SqlClient.SqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)+(Task<SqlDataReader> result) => { }
       at void System.Threading.Tasks.ContinuationResultTaskFromResultTask<TAntecedentResult, TResult>.InnerInvoke()
       at async Task<RelationalDataReader> Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken) x 2
       at async Task Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
    ClientConnectionId:b2d68fed-75a2-4bbf-bd45-59f0926d7ecc
    Error Number:-2,State:0,Class:11
    ClientConnectionId before routing:0de1682f-2deb-4900-b43c-041492f0523b
    Routing Destination:b42514b928c6.HS1.tr2061.canadacentral1-a.worker.database.windows.net,11011
       --- End of inner exception stack trace ---
       at async Task Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
       at async Task Microsoft.EntityFrameworkCore.SqlServer.Update.Internal.SqlServerModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
       at async Task<int> Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable<ModificationCommandBatch> commandBatches, IRelationalConnection connection, CancellationToken cancellationToken) x 3
       at async Task<int> Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList<IUpdateEntry> entriesToSave, CancellationToken cancellationToken) x 2
       at async Task<TResult> Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync<TState, TResult>(TState state, Func<DbContext, TState, CancellationToken, Task<TResult>> operation, Func<DbContext, TState, CancellationToken, Task<ExecutionResult<TResult>>> verifySucceeded, CancellationToken cancellationToken)
       at async Task<int> Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken) x 2
       at async Task<int> Abp.EntityFrameworkCore.AbpDbContext.SaveChangesAsync(CancellationToken cancellationToken)
       at async Task<int> Abp.Zero.EntityFrameworkCore.AbpZeroCommonDbContext<TRole, TUser, TSelf>.SaveChangesAsync(CancellationToken cancellationToken)
       at async Task Abp.EntityFrameworkCore.Uow.EfCoreUnitOfWork.SaveChangesAsync()
       at async Task Abp.Notifications.NotificationStore.UpdateUserNotificationStateAsync(int? tenantId, Guid userNotificationId, UserNotificationState state)+(?) => { }
       at async Task Abp.Domain.Uow.UnitOfWorkManagerExtensions.WithUnitOfWorkAsync(IUnitOfWorkManager manager, Func<Task> action, UnitOfWorkOptions options)
       at async Task Abp.Notifications.NotificationStore.UpdateUserNotificationStateAsync(int? tenantId, Guid userNotificationId, UserNotificationState state)
       at async Task<SetNotificationAsReadOutput> PatientManagement.Notifications.NotificationAppService.SetNotificationAsRead(EntityDto<Guid> input) in C:/Users/vtoll/source/repos/PatientManagement/src/PatientManagement.Application/Notifications/NotificationAppService.cs:line 378
       at object lambda_method22956(Closure, object)
       at async ValueTask<IActionResult> Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor+AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments)
       at async Task Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()+Logged(?)
       at async Task Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()+Awaited(?)
       at void Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
       at Task Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
       at async Task Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()+Awaited(?)
       at async Task Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeNextExceptionFilterAsync()+Awaited(?)
    

    Also, on our Azure instance - it's created a new index.

    The thing is, while we have been using notifications - it's not the kind of notification that a user would want to see in the notifications area, it's more just temporary based on retrieving from a slow API that they are doing that is taking a very long time. There's no need to show it in the "inbox" as it doesn't matter once it's completed.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @kfrancis

    This problem might not be related to notifications. You can definitely use the event system for this but I just wanted to check the cause of the problem.

    1. Could you share the ABP NuGet package version you are using ?
    2. Could you share if you are using Redis cache or not ?

    Thanks,