-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Fix internal policy of event.Bus events publishing #8110
Conversation
Can one of the admins verify this patch? |
1 similar comment
Can one of the admins verify this patch? |
ci-test |
Hi @voievodin! Nice to see you again. Can you sign your commits to satisfy eclipse ip check? |
ci-test build report: |
} | ||
|
||
// SubAny does the same as Sub func, but for multiple event types. | ||
func (bus *Bus) SubAny(consumer Consumer, types ...string) { | ||
bus.Lock() | ||
defer bus.Unlock() | ||
for _, t := range types { | ||
bus.consumers[t] = append(bus.consumers[t], consumer) | ||
bus.consumers[t] = append(bus.copyConsumers(t), consumer) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the whole function is covered by a lock do we really need to copy consumers before appending the new one?
@@ -81,19 +82,20 @@ func (bus *Bus) Pub(e E) { | |||
func (bus *Bus) Sub(consumer Consumer, eType string) { | |||
bus.Lock() | |||
defer bus.Unlock() | |||
bus.consumers[eType] = append(bus.consumers[eType], consumer) | |||
bus.consumers[eType] = append(bus.copyConsumers(eType), consumer) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the whole function is covered by a lock do we really need to copy consumers before appending the new one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically it will work without copying, as a new element will be added to the underlining array while concurrently reading(publishing) go routines will be working with slices referencing the same array but different elements.
The reason i changed this code was to achieve the same copy-on-write pattern concept throughout all bus state modification functions. For example Bus.rm
copies values because otherwise it would change the original values of underlining array, including those being concurrently referenced by reading routines, which may produce unexpected results. Fail-safe traversing, simplicity are the main reasons.
If we take a look at EventService
java implementation it carries ConcurrentMap
of CopyOnWriteArraySets
, so each write produces a new instance of underlining array, which is the same approach in terms of modification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought that it always creates a new array, but now I see that there are cases when the slice is just resliced.
Thank you for the explanation.
Can one of the admins verify this patch? |
I'm not sure i can pass CLA check as i have no access to my previous email. |
@voievodin just register your new gmail through Eclipse ECA here is the link https://accounts.eclipse.org/user/login?destination=user/eca |
@benoitf How does it work for the users not from the Eclipse organization? |
@voievodin yes it's for all external contributors |
@benoitf thank you, i will register and pass the validation =) |
Signed-off-by: Yevhenii Voievodin <targetjump@gmail.com>
Signed-off-by: Yevhenii Voievodin <targetjump@gmail.com>
@garagatyi, @akorneta all checks passed, feel free to merge when necessary |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ci-build
@voievodin thx |
Hi there ✋
This pull request fixed the behaviour of events publishing in Golang based event bus.
The current version of
Bus.Pub
func:The main problem here is modification of bus state within the read lock in case consumer is instance of
TmpConsumer
and call toisDone
returns true. One of the commits introduces a test-case that breaks the behaviour of this function and ends up throwing one of the following errors:To solve the problem copy-on-write approach was used. So basically each time there is a new subscription or consumer removal the original array of consumers is replaced with a new one. It allows concurrently publishing go-routines to complete without any errors. This approach is similar to the one used by EventService.