Skip to content

Events redo#149

Merged
brian-brazil merged 4 commits intodevfrom
events-redo
Sep 13, 2018
Merged

Events redo#149
brian-brazil merged 4 commits intodevfrom
events-redo

Conversation

@brian-brazil
Copy link
Copy Markdown
Contributor

This switches event delivery to be largely synchronous, and also in-order. Only one event is executed at a time.

Async is kept for the scoreboard itself, to avoid deadlocks, and when talking to systems like Twitter/XML/WS who may stall.

This is simpler, more predictable, and also happens to halve the length of the unittests.

@frank-weinberg

This ensures that events will be delivered in a more
predictable order which mitigates race conditions, and
avoids thread/memory leaks in ScoreBoardEventProviderManager.

Leave DefaultScoreBoardModel as-is for now.
This is a wrapper which serves events asynchronously via a thread.
This is used for places that are talking to the outside world
so that they don't inadvertantly hold up the entire system if
an external dependency is slow.
Make event delivery within DefaultScoreBoardModel async,
to avoid deadlocks.
@frank-weinberg
Copy link
Copy Markdown
Contributor

Did you actually encounter deadlocks in DefaultScoreBoardModel or are you just being cautious?

@brian-brazil
Copy link
Copy Markdown
Contributor Author

I encountered deadlocks immediately in actual usage (but not in unittests).

Twitter/XML/WS is me being cautious. Twitter/XML I don't know enough about how they work, WS can run out of kernel TCP buffer space.

@frank-weinberg
Copy link
Copy Markdown
Contributor

Without knowing the specific cause of the deadlocks, I'm somewhat worried that DefaultTeamModel or DefaultClockModel could also be vulnerable to them. Both classes also have functions that are called from the frontend and trigger events which are in turn sent back to the frontend. (And having two threads do this with an unlucky ordering of locks sounds like a candidate for the source of the deadlocks.)

@brian-brazil
Copy link
Copy Markdown
Contributor Author

Neither DefaultClockModel nor DefaultTeamModel have a listener. DefaultTeamModel just passes events up to the DefaultScoreBoardModel, as it's the clearing house for events.

I believe the deadlocks are due to the various ad-hoc locking patterns in use, and running all the events async as I'm doing in DefaultScoreBoardModel should prevent any issues.

Copy link
Copy Markdown
Contributor

@frank-weinberg frank-weinberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside from the concerns regarding deadlocks, I have no objections to the change. And while those concerns are sufficient for me to not merge the PR, I don't object, if you want to do it yourself.

@brian-brazil brian-brazil merged commit 6ece88b into dev Sep 13, 2018
@brian-brazil
Copy link
Copy Markdown
Contributor Author

Thanks! I don't think there's any more risk than what we have today, in fact I'd expect it to be a bit less. We'll see at British Champs this weekend anyway.

@brian-brazil brian-brazil deleted the events-redo branch September 13, 2018 13:15
frank-weinberg added a commit to frank-weinberg/scoreboard that referenced this pull request Sep 16, 2018
In order to avoid potential for deadlocks, cover all the core logic in
Default*Model with a single lock. This could make reaction times a bit
slower, if multiple clients send state updates at the same time but as
long as all updates are handled quickly, this should be negligible. (We
should, however, not start to compute complex stats under the lock.)

The only remaining calls from code under the lock to code (potentially)
under different locks are to the baseLock in Ruleset.java, which in turn
does not reach other locks, and through the event interface. Since all
event listeners not covered by the coreLock are async and thus the
actual handling of the event will not be done while holding the
coreLock, we can conclude that this change and rollerderby#149 together do not
introduce any potential deadlocks.
brian-brazil pushed a commit that referenced this pull request Sep 18, 2018
In order to avoid potential for deadlocks, cover all the core logic in
Default*Model with a single lock. This could make reaction times a bit
slower, if multiple clients send state updates at the same time but as
long as all updates are handled quickly, this should be negligible. (We
should, however, not start to compute complex stats under the lock.)

The only remaining calls from code under the lock to code (potentially)
under different locks are to the baseLock in Ruleset.java, which in turn
does not reach other locks, and through the event interface. Since all
event listeners not covered by the coreLock are async and thus the
actual handling of the event will not be done while holding the
coreLock, we can conclude that this change and #149 together do not
introduce any potential deadlocks.
official-sounding pushed a commit to official-sounding/scoreboard that referenced this pull request May 9, 2019
In order to avoid potential for deadlocks, cover all the core logic in
Default*Model with a single lock. This could make reaction times a bit
slower, if multiple clients send state updates at the same time but as
long as all updates are handled quickly, this should be negligible. (We
should, however, not start to compute complex stats under the lock.)

The only remaining calls from code under the lock to code (potentially)
under different locks are to the baseLock in Ruleset.java, which in turn
does not reach other locks, and through the event interface. Since all
event listeners not covered by the coreLock are async and thus the
actual handling of the event will not be done while holding the
coreLock, we can conclude that this change and rollerderby#149 together do not
introduce any potential deadlocks.
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

Successfully merging this pull request may close these issues.

2 participants