hi
We will try the inbox processers and go from there.
Thanks
Thank you for the advice β weβre going to follow the approach of using dedicated workers for specific events, which should help us process events faster.
However, we still have a concern around message intake. At the moment, we need to consume more messages from the Service Bus in order to populate the Inbox table more quickly, so that there are always enough messages available for inbox processing.
In other words, even if we scale out the workers that process inbox messages, we appear to be limited by how fast messages are pulled from the Service Bus and written into the Inbox table.
Is there a recommended way in ABP v10 to:
Increase or parallelize message consumption from the Service Bus for the Inbox, or
Configure multiple consumers/listeners that safely populate the Inbox table while still preserving idempotency and ordering guarantees?
Any guidance on best practices for scaling the message ingestion into the Inbox (not just inbox processing) would be very helpful.
We need to support horizontal scaling to handle the volume of events being published to the Service Bus. At present, a single service instance processing the inbox can take several hours to complete, regardless of the compute resources allocated. Could you please advise on recommended approaches or architectural patterns to enable parallel or distributed inbox processing in this scenario?
we would like to clarify the runtime behaviour of the Inbox processing in ABP.IO v10 when multiple instances are running.
For example:
If the Inbox contains 10 or more pending items
And 2 (or more) application instances are running with Inbox processing enabled
What is the expected behavior?
Will each instance pick different Inbox items and process them in parallel?
Or does only one instance consume and process Inbox messages while the others remain idle?
If parallel processing is supported, how does ABP prevent two instances from processing the same Inbox item?
Understanding this behaviour is important for us to properly size and scale our deployment.
Thank you.
Have managed to get this working.
In the API project this registration would not trigger the read. This is still the registration on the web project.
services.Configure<AbpSystemTextJsonSerializerOptions>(options => c
{
options.JsonSerializerOptions.Converters.Add(new PaymentRequestProductExtraParameterConfigurationJsonConverter());
});
Adding the JsonConverter in the API project against the JsonOptions instead of AbpSystemTextJsonSerializerOptions resolved the issue and the read now trigger.
Configure<JsonOptions>(options =>
{
options.JsonSerializerOptions.Converters.Add(new PaymentRequestProductExtraParameterConfigurationJsonConverter());
});
This did not resolve my issue, I am still experiencing the same error.
I added the new JsonConverter to my web project.
The API is still throwing the following exception:
Deserialization of interface or abstract types is not supported. Type 'Volo.Payment.IPaymentRequestProductExtraParameterConfiguration'. Path: $.products[0].extraProperties.ZendaPaymentRequestProductExtraParameterConfiguration | LineNumber: 0 | BytePositionInLine: 213
StackTrace:
at System.Text.Json.ThrowHelper.ThrowNotSupportedException(ReadStack& state, Utf8JsonReader& reader, Exception innerException)
at System.Text.Json.ThrowHelper.ThrowNotSupportedException_DeserializeNoConstructor(JsonTypeInfo typeInfo, Utf8JsonReader& reader, ReadStack& state)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.JsonDictionaryConverter`3.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, TDictionary& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.JsonCollectionConverter`2.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, TCollection& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, T& value, JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.ContinueDeserialize(ReadBufferState& bufferState, JsonReaderState& jsonReaderState, ReadStack& readStack, T& value)
at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.DeserializeAsync(Stream utf8Json, CancellationToken cancellationToken)
at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.DeserializeAsObjectAsync(Stream utf8Json, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinder.BindModelAsync(ModelBindingContext bindingContext)
at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object value, Object container)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
I also add the same JsonConverter to the API project where the exception is being thrown.