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

when I use SetState in a callback in a before_<event> => deadlock #87

Open
lzecca78 opened this issue Jul 19, 2022 · 4 comments
Open

when I use SetState in a callback in a before_<event> => deadlock #87

lzecca78 opened this issue Jul 19, 2022 · 4 comments

Comments

@lzecca78
Copy link

I am writing an fsm that needs the follow:

an Event named creating can goes to 3 different states (ok, unreachable, creating) depending on some checks. In order to realize this, I wrote a callback function like this one:

func (p *ClusterState) beforeCreating(e *fsm.Event) {
	p.Logger.Infof("Triggered event %v, trying to reach status %s", e.Event, e.Dst)

	if p.Unreachable {
		timeLimit := p.CreatedAt.Add(time.Minute * 30)
		if timeLimit.Before(p.Clock.Now()) {
			e.FSM.SetState("CREATING") // it hangs here
		}
	}
}

Probably there is a better way to do that, or i am missing something.
Can anyone help me with that?
Thanks in advance!

@lzecca78 lzecca78 changed the title when I use SetState in a callback in a before_<event> the process hangs when I use SetState in a callback in a before_<event> => deadlock Jul 19, 2022
@lzecca78
Copy link
Author

The same happens if I try to trigger an FSM.Event instead of SetState

@itsprdp
Copy link

itsprdp commented Jul 19, 2022

This is a known issue and @annismckenzie has put together a nice PR #82 which is yet to be merged.

Hackish solution that might work for you:

func (p *ClusterState) unreachableLogic() {
  timeLimit := p.CreatedAt.Add(time.Minute * 30)
  if timeLimit.Before(p.Clock.Now()) {
    e.FSM.SetState("CREATING") // it hangs here
  }

}

func (p *ClusterState) beforeCreating(e *fsm.Event) {
  p.Logger.Infof("Triggered event %v, trying to reach status %s", e.Event, e.Dst)

  if p.Unreachable {
    go p.unreachableLogic()
  }
}

@lzecca78
Copy link
Author

thanks for your help @itsprdp, I ended up with a solution that uses heavily the Metadata and GetMetadata feature and then a big switch case for a call to a transition to the desired state. Is of course sub-optimal, but unless the branch will not be merged, it is working. After the fix, I will revisit it. Thanks again for your help, really appreciated it!

@annismckenzie
Copy link
Contributor

#88 was merged today and you may want to revisit this. 🙃

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

3 participants