Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add determines whether the subscriber parameter is interface instance #669

Closed
yijianmin opened this issue Sep 16, 2020 · 4 comments
Closed

Comments

@yijianmin
Copy link

yijianmin commented Sep 16, 2020

Use IEnumerable to publish to RabbitMQ, and then the consumer uses IEnumerable to receive and report the above exception.

The release is successful, but the consumer does not consume it. The cap.received table is recorded as Failed, and Retries is directly displayed as 3. After more than 4 minutes, consumption starts, and then the cap.received table record is changed to Succeeded.

Finally, replace IEnumerable with List. There is no such problem, no delay and no exception. What is the reason?

DotNetCore.CAP.Internal.SubscriberExecutionFailedException: Object must implement IConvertible.
System.InvalidCastException: Object must implement IConvertible.
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at DotNetCore.CAP.Internal.SubscribeInvoker.InvokeAsync(ConsumerContext context, CancellationToken cancellationToken)
at DotNetCore.CAP.Internal.SubscribeDispatcher.InvokeConsumerMethodAsync(MediumMessage message, ConsumerExecutorDescriptor descriptor, CancellationToken cancellationToken)
@yang-xiaodong
Copy link
Member

This is a basic knowledge, the data needs to be carried by the object instance not interface

var obj = JsonConvert.DeserializeObject("[\"2020-01-01\"]", typeof(IEnumerable<DateTime>));
Console.WriteLine(obj.GetType()); // Output : System.Collections.Generic.List`1[System.DateTime]

@yang-xiaodong
Copy link
Member

I think this is an item that can be improved. Do this by passing to check if the instance and interface match

@yang-xiaodong yang-xiaodong changed the title DotNetCore.CAP.Internal.SubscriberExecutionFailedException: Object must implement IConvertible. Add determines whether the subscriber parameter is interface instance Sep 16, 2020
@yang-xiaodong
Copy link
Member

Fixed in v3.1.1

maikebing pushed a commit to maikebing/CAP that referenced this issue Nov 19, 2020
@jirisykora83
Copy link

Facing exact same issue with last version. Frist 3 times in row (almost instantly) got DotNetCore.CAP.Internal.SubscriberExecutionFailedException: Object must implement IConvertible and then after some time (by default 4min) message was successfully process (without changing anything even without restarting etc..).

DotNetCore.CAP.Internal.SubscriberExecutionFailedException: Object must implement IConvertible.
 ---> System.InvalidCastException: Object must implement IConvertible.
   at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) in System.Private.CoreLib.dll:token 0x6000b96+0x0
   at DotNetCore.CAP.Internal.SubscribeInvoker.InvokeAsync(ConsumerContext context, CancellationToken cancellationToken) in DotNetCore.CAP.dll:token 0x60001d1+0x25f
   at DotNetCore.CAP.Internal.SubscribeDispatcher.InvokeConsumerMethodAsync(MediumMessage message, ConsumerExecutorDescriptor descriptor, CancellationToken cancellationToken) in DotNetCore.CAP.dll:token 0x60001ca+0xb9
   --- End of inner exception stack trace ---
   at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) in System.Private.CoreLib.dll:token 0x6000b96+0x0
   at DotNetCore.CAP.Internal.SubscribeInvoker.InvokeAsync(ConsumerContext context, CancellationToken cancellationToken) in DotNetCore.CAP.dll:token 0x60001d1+0x25f
   at DotNetCore.CAP.Internal.SubscribeDispatcher.InvokeConsumerMethodAsync(MediumMessage message, ConsumerExecutorDescriptor descriptor, CancellationToken cancellationToken) in DotNetCore.CAP.dll:token 0x60001ca+0xb9

After some investigation i found that issue is when in my case I have ConsumerServiceSelector which register my handler automatically and method which handle Event have second parameter with CancellationToken

public class TestHandler : BaseAsyncHandler<TestEvent>
{
  public override async Task Handle(FullCacheInvalidateEvent notification,
	  CancellationToken cancellationToken)
  {
	  
  }
  }

Should be to ekvivalent to something like this (i do not try it)

[CapSubscribe("tomethind")
  public override async Task Handle(FullCacheInvalidateEvent notification,
	  CancellationToken cancellationToken)
  {
	
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants