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

ShouldContainSaga on InMemorySagaRepository always waits for the full timeout if the InstanceState overload for string/int has been used. #1201

Closed
wastaz opened this issue Sep 28, 2018 · 3 comments

Comments

@wastaz
Copy link
Contributor

wastaz commented Sep 28, 2018

Is this a bug report?

Yes.

Can you also reproduce the problem with the lastest version?

Yes.

Steps to Reproduce

Create a saga like this.

public class SagaState : SagaStateMachineInstance {
    // This can also be string, the bug is still there
    // The bug goes away if this is of the type State
    public int CurrentState { get; set }
   
    // .... other Saga State
}

Create a state machine.

public class MyStateMachine : MassTransitStateMachine<SagaState>
{
    public State MyState { get; private set; }
    // Maybe more states here
   
    public Event<MyEvent> MyEvent { get; private set; }

    public MyStateMachine() 
    {
        InstanceState(x => x.CurrentState, MyState);
        // Bug is also here if you switch to the InstanceState(x => x.CurrentState) when CurrentState is a string.
        // Bug goes away if using the overload InstanceState(x => x.CurrentState) when CurrentState is of the type State.

       // Perform other basic saga setup here.

       Initially(When(MyEvent).TransitionTo(MyState));
    }
}

With these very basic things in place, if we make a test using MassTransit.TestFramework that uses the ShouldContainSaga method on an InMemorySagaRepository...

await repo.ShouldContainSaga(x => x.Id == id && Equals(x.CurrentState, saga.MyState), TimeSpan.FromMinutes(1));

This will always wait 1 minutes. After one minute it might pass, but it will always wait the full timeout time causing incredibly slow tests.
Switching the type of the CurrentState property to State instead of int or string will cause the exact same code to perform as expected (very fast).

Of course, switching the type of the CurrentState property to State may lead to other problems if using some persistance options since that type is harder for some persistance options to serialize/deserialize (mongodb for example does not like that, but that can of course be fixed with a classmap). But switching this type is a workaround that seems to work properly.

@phatboyg
Copy link
Member

So the issue is the state isn't actually Equal, the instance state accessor should be used to convert the int/string to the State type for the comparison.

@phatboyg
Copy link
Member

I'll add some ShouldContainSagaInState overloads that do the work under the hood.

@phatboyg
Copy link
Member

phatboyg commented Oct 1, 2018

You should be using this to make it work:

await repo.ShouldContainSaga(x => x.Id == id && saga.MyState.Equals(saga.GetState(x)), TimeSpan.FromMinutes(1));

This will properly return the state from the instance (x) as a State instead of the built-in type of int or string.

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

No branches or pull requests

2 participants