felangel/bloc

docs: clearly document semantics for different transformers off the same bloc

Open

#3,248 opened on Feb 28, 2022

View on GitHub
 (3 comments) (0 reactions) (0 assignees)Dart (3,419 forks)batch import
documentationgood first issue

Repository metrics

Stars
 (12,452 stars)
PR merge metrics
 (Avg merge 2d 22h) (5 merged PRs in 30d)

Description

It's potentially a confusing API design to have the ability to specify a concurrency transformer per event handler - initially I felt that it would be better to have one event transformer per bloc. But I note that e.g. https://github.com/VGVentures/bloc_concurrency_demos/blob/85fd3948b4e77b537f82a59a8e1d4e5fdf417262/lib/registration/bloc/registration_bloc_new.dart does make use of multiple different types of event transformer for handlers off the same bloc.

It's not clear (to me) what the semantics are.

https://pub.dev/documentation/bloc_concurrency/latest/bloc_concurrency/sequential.html states:

Note: there is no event handler overlap and every event is guaranteed to be handled in the order it was received.

I'm not sure that's the case though - if you have several event handlers on the same bloc, looking at the implementation, it's not at all obvious that setting sequential on one would prevent a different event handler from starting concurrently. If a bloc has 2 event handlers, and they both set sequential it's still not clear to me that they mutually exclude each other (because I think the async map is happening after the filtration on the stream, so I think you're essentially splitting the stream in 2 parts first, before applying any exclusion semantics; that said, I'm really quite new to dart/flutter/bloc so I could be very wrong on all of this).

If it were me, I would shift the transformer to be at the bloc level, and not the event handler level, as I think the semantics are much clearer and easier to understand that way. If there really are compelling reasons to have it per handler, then I think the docs should be really explicit about the fact that having one event handler which does its own type-based dispatch is potentially quite different semantics to having two event handlers and getting the bloc to do the type-based dispatch even if those two event handlers are using the same transformer, because of the interaction between (a) splitting the stream per type; (b) applying handlers as a mapping over the (sub) stream(s).

(Again, if it were me, I would have the default transformer be sequential, not concurrent. But I'm sure you've reasons for the choices you've made.)

Contributor guide