You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@flex.apache.org by Harbs <ha...@gmail.com> on 2017/07/13 22:40:22 UTC

Bead Lifecycle (was Re: git commit: [flex-asjs] [refs/heads/develop] - Add FileUploaderWithResponseData)

Now that Yishay and I have spent quite some time with beads, I have some thoughts on the architecture.

Here’s some things I’ve noticed (somewhat randomly):

1. There’s no clear place to add beads to components in AS. It seems like the catch-all place to do so is in addedToParent(), but many components add beads at other places. Many of these are lazy initialization and the like. There’s probably good reasons for all of these, but it’s confusing. Here’s a list of places where addBead() is called in Basic:
start
initHandler
finishSetup
set states
get/set model
get/set view
get measurementBead
setCursor
get accordionCollapseBead
get layout
set strand
createViewport
createLists
displayBackgroundAndBorder
setupForBorder
handleMessageChange
get presentationModel
constructor

Especially for someone who is new to this, it’s very confusing to know where the right place to add a bead is.

2. It’s not immediately obvious that Beads can also be Strands. There are quite a few cases where that’s true. The only ones I’ve noticed were View Beads.

3. It’s hard to follow which beads have which dependencies. There are event listeners added at seemingly random places and events dispatched seemingly randomly as well. It’s hard to follow the flow.

4. It’s hard to know when beads are added and in what order.

5. Even if you know what other beads and events your bead relies on, you need to cross-reference to know what exact events are being dispatched.

6. The use of events is probably overkill for the needs of stands and beads. Strands are effectively a command bus for the beads (there’s many terms for the same concept). Events have significant overhead and indirection. Really what we need is for beads to tell the Strand “hey, I need to know when x happens so I can react and/or change what’s happening” and when beads do things they need to say “hey here’s what I did/ want to do”.

7. Beads have no way of knowing when they can finish setting up. The only way to do so is attach event listeners which is a bit awkward.

I really like the Notification architecture in PureMVC, and I think it’s perfect for Strands and Beads.

Without going into all the nitty gritty details, the classes have some standard info that the “mediator” can use to find who’s interested in what. The classes which need to react to specific notifications (i.e. Mediators) list their interests and they are directly notified when something that interests them happened.

There’s also a clear lifecycle where functions can be called at predetermined times. Notification is done by using a Notification object which has three properties: name, type and body. Subscription to events happens through their names, but Notifications of the same name can modify their behavior by their type. body is an Object and can contain any kind of payload.

I’d like to see a couple of things with Strands and Beads.

1. We should publish popular patterns for Strand/Bead interaction. (I’m talking to myself as much as anyone else.)

2. I’d like to have a clearly documented lifecycle for beads. There are some standard bead types such as Model, Controller, View, Content View. When should each of these be created and how? At critical points in this cycle, things should happen automatically: The strand should pull from each bead which is added what interests it has.

3. At the point when all “necessary” beads are added, the beads should have some method automatically called so they can “finish” their setup if they rely on another bead.

4. All Strands should have a “notify” method that beads can call to let the strand know to let the appropriate beads know about an event. The beads should send a notification with the necessary payload if one is needed. Other beads can modify this payload and/or change the notification type if necessary. The publisher of the notification can examine the notification after it’s sent to know if it needs to do something different.

Bonus points if there’s some kind of “post process” on notifications in case a bead needs to wait until after some other bead did their thing. This can take the form of a “registerPostProcess” call to the bead which is only every called once per registration.

5. I’m likely missing some points in the lifecycle…

This is something that I’d work on if others think this makes any kind of sense. While a lot of this is not very different from how events are working today, it feels to me like it would help give the strand/bead relationships a lot more structure.

Thoughts?
Harbs

> 
> On Jul 13, 2017, at 7:34 PM, Alex Harui <ah...@adobe.com.INVALID> wrote:
> 
> Yes, that's how I think of it.  You are right that getting one bead in a
> multi bead set to listen to other beads is tricky.  UIBase defines a
> particular order of model first, then view, then controller.  But
> otherwise, you either have to dictate your own order or find another event
> to listen to that will give a bead another chance to search the strand for
> other beads to listen to.  There is a "beadsAdded" event that can be used.
> 
> Maybe as more folks implement multi-bead sets we'll see patterns emerge
> and make it is simpler and faster.
> 
> My 2 cents,
> -Alex
> 
> On 7/13/17, 3:54 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
> 
>> Generally speaking it feels like sometimes I need to insure the order of
>> invocation. Since beads communicate with one another through events it’s
>> difficult to achieve. Regarding the upload response data I understand
>> your suggestion as follows (edges contain event names):
>> 
>> <Strand>--uploadRequested--<controllerForWithResponse (sends
>> request)>---complete---<ModelWithResponse (after controller wrote to
>> model>---modelChanged--<UserClassListening>
>> 
>> And for the case where the user isn’t interested in the response, just in
>> the status:
>> 
>> <Strand>---uploadRequested--<controllerForWithoutResponse>---complete---<M
>> odelWithoutResponse>--modelChanged--<UserClassListening>
>> 
>> Is that right?
>> 
>> 
>> From: Alex Harui<ma...@adobe.com.INVALID>
>> Sent: Wednesday, July 12, 2017 9:58 AM
>> To: dev@flex.apache.org<ma...@flex.apache.org>
>> Subject: Re: git commit: [flex-asjs] [refs/heads/develop] - Add
>> FileUploaderWithResponseData
>> 
>> I think I still don't understand.
>> 
>> It is ok for beads to require other beads.  If a ResponseData bead
>> requires a model with a slot for responseData and a controller that knows
>> to record that data, that's how you are supposed to "re-compose"
>> components.  There doesn't have to be one model or controller per
>> component.  The strand is a gathering place for small pieces to work
>> together.
>> 
>> I'm not sure what work CheckPermissions needs to do, but is totally fine
>> to split its work amongst a set of beads.
>> 
>> HTH,
>> -Alex
>> 
>> On 7/11/17, 11:21 PM, "yishayw" <yi...@hotmail.com> wrote:
>> 
>>> Ideally we wouldn't have to record data that's never read. This may be an
>>> extreme case, but some users will want to know the response on an upload,
>>> while some will just want to make sure the status is ok. I'd rather not
>>> anticipate too many use cases when writing the strand and the model
>>> because
>>> I might end up with code that's never used. If the bead was responsible
>>> for
>>> both recording the response and exposing it to the user, we wouldn't have
>>> to
>>> do that.
>>> 
>>> Perhaps a better example is permissions. I already have an Upload bead.
>>> Now
>>> I want an alert to pop up if the user is not permitted to upload. I'd
>>> like
>>> to be able to add a 'CheckPemissionsOnUpload' bead. Right now I don't see
>>> how to do that, instead I would probably have to replace 'UploadBead'
>>> with
>>> 'UploadButCheckPermissionsBead'. This takes us away from composition and
>>> forces inheritance.
>>> 
>>> Maybe we don't need to modify class definitions. I think it's enough to
>>> modify the bead instance. In JS we could simply replace the function, and
>>> in
>>> flash we could maybe replace the whole original bead with a
>>> flash.utils.Proxy. But this will make things a bit complicated to read
>>> and
>>> maintain.
>>> 
>>> 
>>> 
>>> 
>>> 
>>> --
>>> View this message in context:
>>> https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fapache-fl
>>> e
>>> x-development.2333347.n4.nabble.com%2FRe-git-commit-flex-asjs-refs-heads-
>>> d
>>> evelop-Add-FileUploaderWithResponseData-tp63051p63139.html&data=02%7C01%7
>>> C
>>> %7Cbd5414b3ced9495c188908d4c8f0f59b%7Cfa7b1b5a7b34438794aed2c178decee1%7C
>>> 0
>>> %7C0%7C636354384624691027&sdata=BGn1g0wbTZr7ikn3uuhcIGDGPEmSVWTwIF%2BlaF6
>>> d
>>> v8w%3D&reserved=0
>>> Sent from the Apache Flex Development mailing list archive at Nabble.com.
>> 
> 


Re: Bead Lifecycle (was Re: git commit: [flex-asjs] [refs/heads/develop] - Add FileUploaderWithResponseData)

Posted by piotrz <pi...@gmail.com>.
Harbs,

I agree with everything what you just said. I've used PureMVC a lot and
indeed it has really strong communication channel between each parts of
framework which is worth to apply if it possible. 

Apart of that I think your experience should be put at least as an comments
to page about PAYG which Greg started. 

Thank you with sharing with us all of that!
Piotr



-----
Apache Flex PMC
piotrzarzycki21@gmail.com
--
View this message in context: http://apache-flex-development.2333347.n4.nabble.com/Re-git-commit-flex-asjs-refs-heads-develop-Add-FileUploaderWithResponseData-tp63051p63251.html
Sent from the Apache Flex Development mailing list archive at Nabble.com.

Re: Bead Lifecycle (was Re: git commit: [flex-asjs] [refs/heads/develop] - Add FileUploaderWithResponseData)

Posted by Harbs <ha...@gmail.com>.
It’s not an 8 step lifecycle. The only extra step is the registerBead step.

The rest is dealing with the peculiarities of different scenarios.

FWIW, none of this will be enforced, so there’s nothing to stop anyone from using beads exactly as they are used today.

Once I finish my experiment, let’s discuss some more…

> On Jul 14, 2017, at 7:13 PM, Alex Harui <ah...@adobe.com.INVALID> wrote:
> 
> For sure, it probably isn't efficient to try to think this out on the
> mailing list.  So, if this is important to you, find the time to code it
> up and see how it turns out.
> 
> My first impression of an 8-step lifecycle is not positive.  Sounds like a
> lot of steps.  The lifecycle I described upthread, which seems to be fine
> for the vast majority of beads that don't talk with other beads, was only
> 4 steps.  Maybe there can be a different lifecycle for beads that need to
> find each other.
> 
> Also, I don't think there is any way to make MXML and AS behavior the same
> without placing a lot of constraints on how AS is written, which I don't
> think is a good idea.
> 
> I still expect Lazy or Just-in-time Instantiation to be the most
> performant and lazy instantiation will cause beads to be added at any
> time.  Creating all beads in the Constructor is likely to miss important
> scenarios like using CSS to determine which bead to use.
> Or allow language/locale specific beads that are determined at runtime by
> user selection from a dropdown.  Or data parsing beads that are determined
> based on the kind of data returned from a network request.
> 
> Maybe it will help if you can describe some scenarios where beads need to
> find each other and those beads are not the model or view beads since we
> always make them seem like they are put on first because they are created
> on-demand.
> 
> Maybe the answer is as simple as: a bead that requires another bead simply
> throws an error if it can't find the bead on the strand.  That will clue
> in the developer to add beads in the right order.  We've recently learned
> how to write such error messages in ways that they don't end up in
> production code.
> 
> And/or, there might be scenarios where the prerequisite bead is specified
> in the ValuesManager, and some new utility function called
> getBeadByTypeAndInstantiateItIfYouCan'tFindIt will create it and added to
> the strand and return a pointer to it.
> 
> And in some cases, a bead can look for its partner and if it isn't there,
> just do nothing.  Then when the partner comes in it finds the first bead
> and says, "hey I'm here".
> 
> IMO, beads are just another scenario of asynchronous programming.  If you
> make two network requests without waiting for the first one to return, you
> can't guarantee the order in which they return.  I think I saw in regular
> Flex someone try to load two modules and they might return in different
> order and if they had to find each other, they had to create a similar
> protocol.  Maybe there can be a base class for beads that need to find
> each other that has some built-in code that manages this protocol.
> 
> Just thinking out loud,
> -Alex
> 
> On 7/14/17, 12:46 AM, "Harbs" <ha...@gmail.com> wrote:
> 
>> Thinking about this some more:
>> 
>> Order can be important, but that’s something that should be enforced by
>> the strand. Where to add beads might change from strand to strand, but
>> there should be some clear “point” where that happens (before
>> beadsAdded). There needs to be a way to say "add a bead with the rest of
>> them” and “add a bead now”. MXML and AS behavior should be the same.
>> 
>> Here’s what I’m thinking:
>> 
>> 1. Strands should have a registerBead() method which takes a bead
>> instance and adds it to a list, but does not yet add it.
>> 
>> 2. addBead() should work exactly as it does today, but should be reserved
>> for lazy instantiation, or early instantiation.
>> 
>> 3. Strands should have a protected addBeads() method which takes no
>> arguments, but adds all beads which were registered using registerBead().
>> Subclasses could override this method if necessary, but I don’t imagine
>> this being usually necessary. One case where this would be important is
>> when the order of beads is significant. For this to work, getBeadByType()
>> would have to be modified to optionally get registered beads instead of
>> added beads. The responsibility of order would rest on the Strand.
>> 
>> 4. When addBeads() adds all the registered beads, it would send a
>> beadsAdded notification to beads which care.
>> 
>> 5. addBeads() would probably only ever be called once, but if there’s a
>> valid reason to do so, maybe it can be called more than once and
>> beadsAdded notification would be sent out again.
>> 
>> 6. If there are cases where it’s necessary, pre/post beadsAdded
>> notification could possibly be sent as well.
>> 
>> 7. For beads when lazy instantiation does not make sense (i.e. most of
>> the time), registerBead should be called for all beads in the constructor
>> of the strand.
>> 
>> 8. Beads declared in MXML, they should be instantiated with
>> registerBead() rather than addBead(). That would allow code in set
>> strand() to assume the strand is already properly set up, because the
>> strand would only call addBeads() when it makes sense.
>> 
>> This would be a common lifecycle of all beads regardless of type. It
>> should be easier to grok and give predictable behavior.
>> 
>> The notification vs events question is a separate point to ponder.
>> 
>> Thoughts?
>> 
>>> On Jul 14, 2017, at 3:38 AM, Harbs <ha...@gmail.com> wrote:
>>> 
>>> 1. I think so, or at most, only slightly. We’d probably save some code
>>> by not adding lots of functions for events and the like. I feel like the
>>> event system in general is bloated more than it needs to be.
>>> 2. I think there’s probably some and some. There’s probably going to be
>>> some lazy beads, and that’s ok. The way I see it is that there are two
>>> kinds of beads. There’s required ones which are not lazy and then
>>> there’s possibly-required, lazy ones. Lazy ones by definition will not
>>> need to listen for every notification. As long as there’s structure for
>>> the required ones, it’s good.
>>> 3. I think it’s okay to require certain classes of beads to be loaded
>>> in a certain order (i.e. controllers and views), as long as it doesn’t
>>> lead to pitfall bugs, but there’s probably others where requiring the
>>> order makes things difficult.
>>> 
>>> Totally agree about the compiler bit.
>>> 
>>> I generally think better by doing rather than writing.
>>> 
>>> What I might do when I have some spare time is to do some experiments
>>> on a branch and see what happens. I have no problem if my experiments
>>> turn out to be pointless. Either way, it should be educational. I think
>>> it would give a concrete point of reference.
>>> 
>>> Harbs
>>> 
>>>> On Jul 14, 2017, at 2:48 AM, Alex Harui <ah...@adobe.com.INVALID>
>>>> wrote:
>>>> 
>>>> These are good points.  I'm glad I sent my PAYG email earlier today.
>>>> I'm
>>>> not sure I understood points #3 (dependencies) and #5
>>>> (cross-referencing)
>>>> so apologies if my thoughts below didn't take them into account.
>>>> 
>>>> I'd say that some of these ideas simply need to be tried and measured
>>>> against the PAYG metrics I proposed.  For example:
>>>> 1) Can we implement a second, lighterweight notification system without
>>>> increasing download size?  Besides mediators I think there is another
>>>> mechanism called AS3Signals.
>>>> 2) Can we have more consistency in when beads get instantiated or will
>>>> that cause too many beads to be instantiated "just-in-case"?  It may
>>>> just
>>>> be that "just-in-time" or "lazy" instantiation of beads is going to
>>>> make
>>>> it hard to know when a bead will be added to the strand, but I think
>>>> "just-in-time" instantiation is always going to provide best
>>>> performance.
>>>> Too much consistency sometimes results in too much just-in-case code.
>>>> 3) Is it better to require certain beads to be placed on the strand
>>>> before
>>>> other beads?  Does doing so make the code smaller or faster?  Will it
>>>> be
>>>> more painful for developers to get the order right?  It might be best
>>>> just
>>>> to find the best patterns for waiting for your partner beads.  One
>>>> thing
>>>> to consider is that we have more control over when beads get added in
>>>> MXML, but we probably shouldn't have control over when beads get added
>>>> in
>>>> AS.  I don't think the compiler can or should detect when the
>>>> application
>>>> developer is going to add a bead and tell them not to do it.
>>>> 
>>>> There are probably at least two different "lifecycles".  Any individual
>>>> bead's lifecycle should be pretty simple: Instantiation, Initial
>>>> Properties, Add To Strand, Listen for Events/Notifications/Property
>>>> Changes.  Depending on how we decide #3 above, some beads may have a
>>>> "wait
>>>> for my partner bead" phase.
>>>> A UI Component has a lifecycle of: Instantiation, Initial Properties,
>>>> Add
>>>> To Parent, Add Beads.  But model beads may be instantiated and added on
>>>> demand in Initial Properties.  In "Add Beads" the model is added first
>>>> if
>>>> not already added, then the view, then everything else.  In theory, the
>>>> "beadsAdded" event can be used by beads to know when significant
>>>> changes
>>>> to the set of beads has occurred and that can be used to finish
>>>> setting up
>>>> if you are waiting for partner beads, but otherwise, I think you can
>>>> count
>>>> on model being instantiated on-demand and finish up in your strand
>>>> setter.
>>>> 
>>>> The idea I liked the least was the notion that the Strand was some
>>>> intermediary and beads talk to the Strand, tell the Strand what their
>>>> interest are and things like that.  In my view the strand is just a bus
>>>> like you mentioned and isn't involved in any communications.  The beads
>>>> simply use the bus to find each other and find the most PAYG way of
>>>> communicating. 
>>>> 
>>>> Have you found common/popular patterns?  I don't really know because
>>>> I've
>>>> been spending most of my time in the compiler.  If you have, then yes,
>>>> please document them.
>>>> 
>>>> My 2 cents,
>>>> -Alex
>>>> 
>>>> On 7/13/17, 3:40 PM, "Harbs" <ha...@gmail.com> wrote:
>>>> 
>>>>> Now that Yishay and I have spent quite some time with beads, I have
>>>>> some
>>>>> thoughts on the architecture.
>>>>> 
>>>>> Here’s some things I’ve noticed (somewhat randomly):
>>>>> 
>>>>> 1. There’s no clear place to add beads to components in AS. It seems
>>>>> like
>>>>> the catch-all place to do so is in addedToParent(), but many
>>>>> components
>>>>> add beads at other places. Many of these are lazy initialization and
>>>>> the
>>>>> like. There’s probably good reasons for all of these, but it’s
>>>>> confusing.
>>>>> Here’s a list of places where addBead() is called in Basic:
>>>>> start
>>>>> initHandler
>>>>> finishSetup
>>>>> set states
>>>>> get/set model
>>>>> get/set view
>>>>> get measurementBead
>>>>> setCursor
>>>>> get accordionCollapseBead
>>>>> get layout
>>>>> set strand
>>>>> createViewport
>>>>> createLists
>>>>> displayBackgroundAndBorder
>>>>> setupForBorder
>>>>> handleMessageChange
>>>>> get presentationModel
>>>>> constructor
>>>>> 
>>>>> Especially for someone who is new to this, it’s very confusing to know
>>>>> where the right place to add a bead is.
>>>>> 
>>>>> 2. It’s not immediately obvious that Beads can also be Strands. There
>>>>> are
>>>>> quite a few cases where that’s true. The only ones I’ve noticed were
>>>>> View
>>>>> Beads.
>>>>> 
>>>>> 3. It’s hard to follow which beads have which dependencies. There are
>>>>> event listeners added at seemingly random places and events dispatched
>>>>> seemingly randomly as well. It’s hard to follow the flow.
>>>>> 
>>>>> 4. It’s hard to know when beads are added and in what order.
>>>>> 
>>>>> 5. Even if you know what other beads and events your bead relies on,
>>>>> you
>>>>> need to cross-reference to know what exact events are being
>>>>> dispatched.
>>>>> 
>>>>> 6. The use of events is probably overkill for the needs of stands and
>>>>> beads. Strands are effectively a command bus for the beads (there’s
>>>>> many
>>>>> terms for the same concept). Events have significant overhead and
>>>>> indirection. Really what we need is for beads to tell the Strand
>>>>> “hey, I
>>>>> need to know when x happens so I can react and/or change what’s
>>>>> happening” and when beads do things they need to say “hey here’s what
>>>>> I
>>>>> did/ want to do”.
>>>>> 
>>>>> 7. Beads have no way of knowing when they can finish setting up. The
>>>>> only
>>>>> way to do so is attach event listeners which is a bit awkward.
>>>>> 
>>>>> I really like the Notification architecture in PureMVC, and I think
>>>>> it’s
>>>>> perfect for Strands and Beads.
>>>>> 
>>>>> Without going into all the nitty gritty details, the classes have some
>>>>> standard info that the “mediator” can use to find who’s interested in
>>>>> what. The classes which need to react to specific notifications (i.e.
>>>>> Mediators) list their interests and they are directly notified when
>>>>> something that interests them happened.
>>>>> 
>>>>> There’s also a clear lifecycle where functions can be called at
>>>>> predetermined times. Notification is done by using a Notification
>>>>> object
>>>>> which has three properties: name, type and body. Subscription to
>>>>> events
>>>>> happens through their names, but Notifications of the same name can
>>>>> modify their behavior by their type. body is an Object and can contain
>>>>> any kind of payload.
>>>>> 
>>>>> I’d like to see a couple of things with Strands and Beads.
>>>>> 
>>>>> 1. We should publish popular patterns for Strand/Bead interaction.
>>>>> (I’m
>>>>> talking to myself as much as anyone else.)
>>>>> 
>>>>> 2. I’d like to have a clearly documented lifecycle for beads. There
>>>>> are
>>>>> some standard bead types such as Model, Controller, View, Content
>>>>> View.
>>>>> When should each of these be created and how? At critical points in
>>>>> this
>>>>> cycle, things should happen automatically: The strand should pull from
>>>>> each bead which is added what interests it has.
>>>>> 
>>>>> 3. At the point when all “necessary” beads are added, the beads should
>>>>> have some method automatically called so they can “finish” their
>>>>> setup if
>>>>> they rely on another bead.
>>>>> 
>>>>> 4. All Strands should have a “notify” method that beads can call to
>>>>> let
>>>>> the strand know to let the appropriate beads know about an event. The
>>>>> beads should send a notification with the necessary payload if one is
>>>>> needed. Other beads can modify this payload and/or change the
>>>>> notification type if necessary. The publisher of the notification can
>>>>> examine the notification after it’s sent to know if it needs to do
>>>>> something different.
>>>>> 
>>>>> Bonus points if there’s some kind of “post process” on notifications
>>>>> in
>>>>> case a bead needs to wait until after some other bead did their thing.
>>>>> This can take the form of a “registerPostProcess” call to the bead
>>>>> which
>>>>> is only every called once per registration.
>>>>> 
>>>>> 5. I’m likely missing some points in the lifecycle…
>>>>> 
>>>>> This is something that I’d work on if others think this makes any
>>>>> kind of
>>>>> sense. While a lot of this is not very different from how events are
>>>>> working today, it feels to me like it would help give the strand/bead
>>>>> relationships a lot more structure.
>>>>> 
>>>>> Thoughts?
>>>>> Harbs
>>>>> 
>>>>>> 
>>>>>> On Jul 13, 2017, at 7:34 PM, Alex Harui <ah...@adobe.com.INVALID>
>>>>>> wrote:
>>>>>> 
>>>>>> Yes, that's how I think of it.  You are right that getting one bead
>>>>>> in a
>>>>>> multi bead set to listen to other beads is tricky.  UIBase defines a
>>>>>> particular order of model first, then view, then controller.  But
>>>>>> otherwise, you either have to dictate your own order or find another
>>>>>> event
>>>>>> to listen to that will give a bead another chance to search the
>>>>>> strand
>>>>>> for
>>>>>> other beads to listen to.  There is a "beadsAdded" event that can be
>>>>>> used.
>>>>>> 
>>>>>> Maybe as more folks implement multi-bead sets we'll see patterns
>>>>>> emerge
>>>>>> and make it is simpler and faster.
>>>>>> 
>>>>>> My 2 cents,
>>>>>> -Alex
>>>>>> 
>>>>>> On 7/13/17, 3:54 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>>>>>> 
>>>>>>> Generally speaking it feels like sometimes I need to insure the
>>>>>>> order
>>>>>>> of
>>>>>>> invocation. Since beads communicate with one another through events
>>>>>>> it’s
>>>>>>> difficult to achieve. Regarding the upload response data I
>>>>>>> understand
>>>>>>> your suggestion as follows (edges contain event names):
>>>>>>> 
>>>>>>> <Strand>--uploadRequested--<controllerForWithResponse (sends
>>>>>>> request)>---complete---<ModelWithResponse (after controller wrote to
>>>>>>> model>---modelChanged--<UserClassListening>
>>>>>>> 
>>>>>>> And for the case where the user isn’t interested in the response,
>>>>>>> just
>>>>>>> in
>>>>>>> the status:
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> <Strand>---uploadRequested--<controllerForWithoutResponse>---complete
>>>>>>> ---
>>>>>>> <M
>>>>>>> odelWithoutResponse>--modelChanged--<UserClassListening>
>>>>>>> 
>>>>>>> Is that right?
>>>>>>> 
>>>>>>> 
>>>>>>> From: Alex Harui<ma...@adobe.com.INVALID>
>>>>>>> Sent: Wednesday, July 12, 2017 9:58 AM
>>>>>>> To: dev@flex.apache.org<ma...@flex.apache.org>
>>>>>>> Subject: Re: git commit: [flex-asjs] [refs/heads/develop] - Add
>>>>>>> FileUploaderWithResponseData
>>>>>>> 
>>>>>>> I think I still don't understand.
>>>>>>> 
>>>>>>> It is ok for beads to require other beads.  If a ResponseData bead
>>>>>>> requires a model with a slot for responseData and a controller that
>>>>>>> knows
>>>>>>> to record that data, that's how you are supposed to "re-compose"
>>>>>>> components.  There doesn't have to be one model or controller per
>>>>>>> component.  The strand is a gathering place for small pieces to work
>>>>>>> together.
>>>>>>> 
>>>>>>> I'm not sure what work CheckPermissions needs to do, but is totally
>>>>>>> fine
>>>>>>> to split its work amongst a set of beads.
>>>>>>> 
>>>>>>> HTH,
>>>>>>> -Alex
>>>>>>> 
>>>>>>> On 7/11/17, 11:21 PM, "yishayw" <yi...@hotmail.com> wrote:
>>>>>>> 
>>>>>>>> Ideally we wouldn't have to record data that's never read. This may
>>>>>>>> be an
>>>>>>>> extreme case, but some users will want to know the response on an
>>>>>>>> upload,
>>>>>>>> while some will just want to make sure the status is ok. I'd rather
>>>>>>>> not
>>>>>>>> anticipate too many use cases when writing the strand and the model
>>>>>>>> because
>>>>>>>> I might end up with code that's never used. If the bead was
>>>>>>>> responsible
>>>>>>>> for
>>>>>>>> both recording the response and exposing it to the user, we
>>>>>>>> wouldn't
>>>>>>>> have
>>>>>>>> to
>>>>>>>> do that.
>>>>>>>> 
>>>>>>>> Perhaps a better example is permissions. I already have an Upload
>>>>>>>> bead.
>>>>>>>> Now
>>>>>>>> I want an alert to pop up if the user is not permitted to upload.
>>>>>>>> I'd
>>>>>>>> like
>>>>>>>> to be able to add a 'CheckPemissionsOnUpload' bead. Right now I
>>>>>>>> don't
>>>>>>>> see
>>>>>>>> how to do that, instead I would probably have to replace
>>>>>>>> 'UploadBead'
>>>>>>>> with
>>>>>>>> 'UploadButCheckPermissionsBead'. This takes us away from
>>>>>>>> composition
>>>>>>>> and
>>>>>>>> forces inheritance.
>>>>>>>> 
>>>>>>>> Maybe we don't need to modify class definitions. I think it's
>>>>>>>> enough
>>>>>>>> to
>>>>>>>> modify the bead instance. In JS we could simply replace the
>>>>>>>> function,
>>>>>>>> and
>>>>>>>> in
>>>>>>>> flash we could maybe replace the whole original bead with a
>>>>>>>> flash.utils.Proxy. But this will make things a bit complicated to
>>>>>>>> read
>>>>>>>> and
>>>>>>>> maintain.
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> --
>>>>>>>> View this message in context:
>>>>>>>> 
>>>>>>>> 
>>>>>>>> https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fapac
>>>>>>>> he-
>>>>>>>> fl
>>>>>>>> e
>>>>>>>> 
>>>>>>>> 
>>>>>>>> x-development.2333347.n4.nabble.com%2FRe-git-commit-flex-asjs-refs-h
>>>>>>>> ead
>>>>>>>> s-
>>>>>>>> d
>>>>>>>> 
>>>>>>>> 
>>>>>>>> evelop-Add-FileUploaderWithResponseData-tp63051p63139.html&data=02%7
>>>>>>>> C01
>>>>>>>> %7
>>>>>>>> C
>>>>>>>> 
>>>>>>>> 
>>>>>>>> %7Cbd5414b3ced9495c188908d4c8f0f59b%7Cfa7b1b5a7b34438794aed2c178dece
>>>>>>>> e1%
>>>>>>>> 7C
>>>>>>>> 0
>>>>>>>> 
>>>>>>>> 
>>>>>>>> %7C0%7C636354384624691027&sdata=BGn1g0wbTZr7ikn3uuhcIGDGPEmSVWTwIF%2
>>>>>>>> Bla
>>>>>>>> F6
>>>>>>>> d
>>>>>>>> v8w%3D&reserved=0
>>>>>>>> Sent from the Apache Flex Development mailing list archive at
>>>>>>>> Nabble.com.
>>>>>>> 
>>>>>> 
>>>>> 
>>>> 
>>> 
>> 
> 


Re: Bead Lifecycle (was Re: git commit: [flex-asjs] [refs/heads/develop] - Add FileUploaderWithResponseData)

Posted by Alex Harui <ah...@adobe.com.INVALID>.
For sure, it probably isn't efficient to try to think this out on the
mailing list.  So, if this is important to you, find the time to code it
up and see how it turns out.

My first impression of an 8-step lifecycle is not positive.  Sounds like a
lot of steps.  The lifecycle I described upthread, which seems to be fine
for the vast majority of beads that don't talk with other beads, was only
4 steps.  Maybe there can be a different lifecycle for beads that need to
find each other.

Also, I don't think there is any way to make MXML and AS behavior the same
without placing a lot of constraints on how AS is written, which I don't
think is a good idea.

I still expect Lazy or Just-in-time Instantiation to be the most
performant and lazy instantiation will cause beads to be added at any
time.  Creating all beads in the Constructor is likely to miss important
scenarios like using CSS to determine which bead to use.
Or allow language/locale specific beads that are determined at runtime by
user selection from a dropdown.  Or data parsing beads that are determined
based on the kind of data returned from a network request.

Maybe it will help if you can describe some scenarios where beads need to
find each other and those beads are not the model or view beads since we
always make them seem like they are put on first because they are created
on-demand.

Maybe the answer is as simple as: a bead that requires another bead simply
throws an error if it can't find the bead on the strand.  That will clue
in the developer to add beads in the right order.  We've recently learned
how to write such error messages in ways that they don't end up in
production code.

And/or, there might be scenarios where the prerequisite bead is specified
in the ValuesManager, and some new utility function called
getBeadByTypeAndInstantiateItIfYouCan'tFindIt will create it and added to
the strand and return a pointer to it.

And in some cases, a bead can look for its partner and if it isn't there,
just do nothing.  Then when the partner comes in it finds the first bead
and says, "hey I'm here".

IMO, beads are just another scenario of asynchronous programming.  If you
make two network requests without waiting for the first one to return, you
can't guarantee the order in which they return.  I think I saw in regular
Flex someone try to load two modules and they might return in different
order and if they had to find each other, they had to create a similar
protocol.  Maybe there can be a base class for beads that need to find
each other that has some built-in code that manages this protocol.

Just thinking out loud,
-Alex

On 7/14/17, 12:46 AM, "Harbs" <ha...@gmail.com> wrote:

>Thinking about this some more:
>
>Order can be important, but that’s something that should be enforced by
>the strand. Where to add beads might change from strand to strand, but
>there should be some clear “point” where that happens (before
>beadsAdded). There needs to be a way to say "add a bead with the rest of
>them” and “add a bead now”. MXML and AS behavior should be the same.
>
>Here’s what I’m thinking:
>
>1. Strands should have a registerBead() method which takes a bead
>instance and adds it to a list, but does not yet add it.
>
>2. addBead() should work exactly as it does today, but should be reserved
>for lazy instantiation, or early instantiation.
>
>3. Strands should have a protected addBeads() method which takes no
>arguments, but adds all beads which were registered using registerBead().
>Subclasses could override this method if necessary, but I don’t imagine
>this being usually necessary. One case where this would be important is
>when the order of beads is significant. For this to work, getBeadByType()
>would have to be modified to optionally get registered beads instead of
>added beads. The responsibility of order would rest on the Strand.
>
>4. When addBeads() adds all the registered beads, it would send a
>beadsAdded notification to beads which care.
>
>5. addBeads() would probably only ever be called once, but if there’s a
>valid reason to do so, maybe it can be called more than once and
>beadsAdded notification would be sent out again.
>
>6. If there are cases where it’s necessary, pre/post beadsAdded
>notification could possibly be sent as well.
>
>7. For beads when lazy instantiation does not make sense (i.e. most of
>the time), registerBead should be called for all beads in the constructor
>of the strand.
>
>8. Beads declared in MXML, they should be instantiated with
>registerBead() rather than addBead(). That would allow code in set
>strand() to assume the strand is already properly set up, because the
>strand would only call addBeads() when it makes sense.
>
>This would be a common lifecycle of all beads regardless of type. It
>should be easier to grok and give predictable behavior.
>
>The notification vs events question is a separate point to ponder.
>
>Thoughts?
>
>> On Jul 14, 2017, at 3:38 AM, Harbs <ha...@gmail.com> wrote:
>> 
>> 1. I think so, or at most, only slightly. We’d probably save some code
>>by not adding lots of functions for events and the like. I feel like the
>>event system in general is bloated more than it needs to be.
>> 2. I think there’s probably some and some. There’s probably going to be
>>some lazy beads, and that’s ok. The way I see it is that there are two
>>kinds of beads. There’s required ones which are not lazy and then
>>there’s possibly-required, lazy ones. Lazy ones by definition will not
>>need to listen for every notification. As long as there’s structure for
>>the required ones, it’s good.
>> 3. I think it’s okay to require certain classes of beads to be loaded
>>in a certain order (i.e. controllers and views), as long as it doesn’t
>>lead to pitfall bugs, but there’s probably others where requiring the
>>order makes things difficult.
>> 
>> Totally agree about the compiler bit.
>> 
>> I generally think better by doing rather than writing.
>> 
>> What I might do when I have some spare time is to do some experiments
>>on a branch and see what happens. I have no problem if my experiments
>>turn out to be pointless. Either way, it should be educational. I think
>>it would give a concrete point of reference.
>> 
>> Harbs
>> 
>>> On Jul 14, 2017, at 2:48 AM, Alex Harui <ah...@adobe.com.INVALID>
>>>wrote:
>>> 
>>> These are good points.  I'm glad I sent my PAYG email earlier today.
>>>I'm
>>> not sure I understood points #3 (dependencies) and #5
>>>(cross-referencing)
>>> so apologies if my thoughts below didn't take them into account.
>>> 
>>> I'd say that some of these ideas simply need to be tried and measured
>>> against the PAYG metrics I proposed.  For example:
>>> 1) Can we implement a second, lighterweight notification system without
>>> increasing download size?  Besides mediators I think there is another
>>> mechanism called AS3Signals.
>>> 2) Can we have more consistency in when beads get instantiated or will
>>> that cause too many beads to be instantiated "just-in-case"?  It may
>>>just
>>> be that "just-in-time" or "lazy" instantiation of beads is going to
>>>make
>>> it hard to know when a bead will be added to the strand, but I think
>>> "just-in-time" instantiation is always going to provide best
>>>performance.
>>> Too much consistency sometimes results in too much just-in-case code.
>>> 3) Is it better to require certain beads to be placed on the strand
>>>before
>>> other beads?  Does doing so make the code smaller or faster?  Will it
>>>be
>>> more painful for developers to get the order right?  It might be best
>>>just
>>> to find the best patterns for waiting for your partner beads.  One
>>>thing
>>> to consider is that we have more control over when beads get added in
>>> MXML, but we probably shouldn't have control over when beads get added
>>>in
>>> AS.  I don't think the compiler can or should detect when the
>>>application
>>> developer is going to add a bead and tell them not to do it.
>>> 
>>> There are probably at least two different "lifecycles".  Any individual
>>> bead's lifecycle should be pretty simple: Instantiation, Initial
>>> Properties, Add To Strand, Listen for Events/Notifications/Property
>>> Changes.  Depending on how we decide #3 above, some beads may have a
>>>"wait
>>> for my partner bead" phase.
>>> A UI Component has a lifecycle of: Instantiation, Initial Properties,
>>>Add
>>> To Parent, Add Beads.  But model beads may be instantiated and added on
>>> demand in Initial Properties.  In "Add Beads" the model is added first
>>>if
>>> not already added, then the view, then everything else.  In theory, the
>>> "beadsAdded" event can be used by beads to know when significant
>>>changes
>>> to the set of beads has occurred and that can be used to finish
>>>setting up
>>> if you are waiting for partner beads, but otherwise, I think you can
>>>count
>>> on model being instantiated on-demand and finish up in your strand
>>>setter.
>>> 
>>> The idea I liked the least was the notion that the Strand was some
>>> intermediary and beads talk to the Strand, tell the Strand what their
>>> interest are and things like that.  In my view the strand is just a bus
>>> like you mentioned and isn't involved in any communications.  The beads
>>> simply use the bus to find each other and find the most PAYG way of
>>> communicating. 
>>> 
>>> Have you found common/popular patterns?  I don't really know because
>>>I've
>>> been spending most of my time in the compiler.  If you have, then yes,
>>> please document them.
>>> 
>>> My 2 cents,
>>> -Alex
>>> 
>>> On 7/13/17, 3:40 PM, "Harbs" <ha...@gmail.com> wrote:
>>> 
>>>> Now that Yishay and I have spent quite some time with beads, I have
>>>>some
>>>> thoughts on the architecture.
>>>> 
>>>> Here’s some things I’ve noticed (somewhat randomly):
>>>> 
>>>> 1. There’s no clear place to add beads to components in AS. It seems
>>>>like
>>>> the catch-all place to do so is in addedToParent(), but many
>>>>components
>>>> add beads at other places. Many of these are lazy initialization and
>>>>the
>>>> like. There’s probably good reasons for all of these, but it’s
>>>>confusing.
>>>> Here’s a list of places where addBead() is called in Basic:
>>>> start
>>>> initHandler
>>>> finishSetup
>>>> set states
>>>> get/set model
>>>> get/set view
>>>> get measurementBead
>>>> setCursor
>>>> get accordionCollapseBead
>>>> get layout
>>>> set strand
>>>> createViewport
>>>> createLists
>>>> displayBackgroundAndBorder
>>>> setupForBorder
>>>> handleMessageChange
>>>> get presentationModel
>>>> constructor
>>>> 
>>>> Especially for someone who is new to this, it’s very confusing to know
>>>> where the right place to add a bead is.
>>>> 
>>>> 2. It’s not immediately obvious that Beads can also be Strands. There
>>>>are
>>>> quite a few cases where that’s true. The only ones I’ve noticed were
>>>>View
>>>> Beads.
>>>> 
>>>> 3. It’s hard to follow which beads have which dependencies. There are
>>>> event listeners added at seemingly random places and events dispatched
>>>> seemingly randomly as well. It’s hard to follow the flow.
>>>> 
>>>> 4. It’s hard to know when beads are added and in what order.
>>>> 
>>>> 5. Even if you know what other beads and events your bead relies on,
>>>>you
>>>> need to cross-reference to know what exact events are being
>>>>dispatched.
>>>> 
>>>> 6. The use of events is probably overkill for the needs of stands and
>>>> beads. Strands are effectively a command bus for the beads (there’s
>>>>many
>>>> terms for the same concept). Events have significant overhead and
>>>> indirection. Really what we need is for beads to tell the Strand
>>>>“hey, I
>>>> need to know when x happens so I can react and/or change what’s
>>>> happening” and when beads do things they need to say “hey here’s what
>>>>I
>>>> did/ want to do”.
>>>> 
>>>> 7. Beads have no way of knowing when they can finish setting up. The
>>>>only
>>>> way to do so is attach event listeners which is a bit awkward.
>>>> 
>>>> I really like the Notification architecture in PureMVC, and I think
>>>>it’s
>>>> perfect for Strands and Beads.
>>>> 
>>>> Without going into all the nitty gritty details, the classes have some
>>>> standard info that the “mediator” can use to find who’s interested in
>>>> what. The classes which need to react to specific notifications (i.e.
>>>> Mediators) list their interests and they are directly notified when
>>>> something that interests them happened.
>>>> 
>>>> There’s also a clear lifecycle where functions can be called at
>>>> predetermined times. Notification is done by using a Notification
>>>>object
>>>> which has three properties: name, type and body. Subscription to
>>>>events
>>>> happens through their names, but Notifications of the same name can
>>>> modify their behavior by their type. body is an Object and can contain
>>>> any kind of payload.
>>>> 
>>>> I’d like to see a couple of things with Strands and Beads.
>>>> 
>>>> 1. We should publish popular patterns for Strand/Bead interaction.
>>>>(I’m
>>>> talking to myself as much as anyone else.)
>>>> 
>>>> 2. I’d like to have a clearly documented lifecycle for beads. There
>>>>are
>>>> some standard bead types such as Model, Controller, View, Content
>>>>View.
>>>> When should each of these be created and how? At critical points in
>>>>this
>>>> cycle, things should happen automatically: The strand should pull from
>>>> each bead which is added what interests it has.
>>>> 
>>>> 3. At the point when all “necessary” beads are added, the beads should
>>>> have some method automatically called so they can “finish” their
>>>>setup if
>>>> they rely on another bead.
>>>> 
>>>> 4. All Strands should have a “notify” method that beads can call to
>>>>let
>>>> the strand know to let the appropriate beads know about an event. The
>>>> beads should send a notification with the necessary payload if one is
>>>> needed. Other beads can modify this payload and/or change the
>>>> notification type if necessary. The publisher of the notification can
>>>> examine the notification after it’s sent to know if it needs to do
>>>> something different.
>>>> 
>>>> Bonus points if there’s some kind of “post process” on notifications
>>>>in
>>>> case a bead needs to wait until after some other bead did their thing.
>>>> This can take the form of a “registerPostProcess” call to the bead
>>>>which
>>>> is only every called once per registration.
>>>> 
>>>> 5. I’m likely missing some points in the lifecycle…
>>>> 
>>>> This is something that I’d work on if others think this makes any
>>>>kind of
>>>> sense. While a lot of this is not very different from how events are
>>>> working today, it feels to me like it would help give the strand/bead
>>>> relationships a lot more structure.
>>>> 
>>>> Thoughts?
>>>> Harbs
>>>> 
>>>>> 
>>>>> On Jul 13, 2017, at 7:34 PM, Alex Harui <ah...@adobe.com.INVALID>
>>>>> wrote:
>>>>> 
>>>>> Yes, that's how I think of it.  You are right that getting one bead
>>>>>in a
>>>>> multi bead set to listen to other beads is tricky.  UIBase defines a
>>>>> particular order of model first, then view, then controller.  But
>>>>> otherwise, you either have to dictate your own order or find another
>>>>> event
>>>>> to listen to that will give a bead another chance to search the
>>>>>strand
>>>>> for
>>>>> other beads to listen to.  There is a "beadsAdded" event that can be
>>>>> used.
>>>>> 
>>>>> Maybe as more folks implement multi-bead sets we'll see patterns
>>>>>emerge
>>>>> and make it is simpler and faster.
>>>>> 
>>>>> My 2 cents,
>>>>> -Alex
>>>>> 
>>>>> On 7/13/17, 3:54 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>>>>> 
>>>>>> Generally speaking it feels like sometimes I need to insure the
>>>>>>order
>>>>>> of
>>>>>> invocation. Since beads communicate with one another through events
>>>>>> it’s
>>>>>> difficult to achieve. Regarding the upload response data I
>>>>>>understand
>>>>>> your suggestion as follows (edges contain event names):
>>>>>> 
>>>>>> <Strand>--uploadRequested--<controllerForWithResponse (sends
>>>>>> request)>---complete---<ModelWithResponse (after controller wrote to
>>>>>> model>---modelChanged--<UserClassListening>
>>>>>> 
>>>>>> And for the case where the user isn’t interested in the response,
>>>>>>just
>>>>>> in
>>>>>> the status:
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>><Strand>---uploadRequested--<controllerForWithoutResponse>---complete
>>>>>>---
>>>>>> <M
>>>>>> odelWithoutResponse>--modelChanged--<UserClassListening>
>>>>>> 
>>>>>> Is that right?
>>>>>> 
>>>>>> 
>>>>>> From: Alex Harui<ma...@adobe.com.INVALID>
>>>>>> Sent: Wednesday, July 12, 2017 9:58 AM
>>>>>> To: dev@flex.apache.org<ma...@flex.apache.org>
>>>>>> Subject: Re: git commit: [flex-asjs] [refs/heads/develop] - Add
>>>>>> FileUploaderWithResponseData
>>>>>> 
>>>>>> I think I still don't understand.
>>>>>> 
>>>>>> It is ok for beads to require other beads.  If a ResponseData bead
>>>>>> requires a model with a slot for responseData and a controller that
>>>>>> knows
>>>>>> to record that data, that's how you are supposed to "re-compose"
>>>>>> components.  There doesn't have to be one model or controller per
>>>>>> component.  The strand is a gathering place for small pieces to work
>>>>>> together.
>>>>>> 
>>>>>> I'm not sure what work CheckPermissions needs to do, but is totally
>>>>>> fine
>>>>>> to split its work amongst a set of beads.
>>>>>> 
>>>>>> HTH,
>>>>>> -Alex
>>>>>> 
>>>>>> On 7/11/17, 11:21 PM, "yishayw" <yi...@hotmail.com> wrote:
>>>>>> 
>>>>>>> Ideally we wouldn't have to record data that's never read. This may
>>>>>>> be an
>>>>>>> extreme case, but some users will want to know the response on an
>>>>>>> upload,
>>>>>>> while some will just want to make sure the status is ok. I'd rather
>>>>>>> not
>>>>>>> anticipate too many use cases when writing the strand and the model
>>>>>>> because
>>>>>>> I might end up with code that's never used. If the bead was
>>>>>>> responsible
>>>>>>> for
>>>>>>> both recording the response and exposing it to the user, we
>>>>>>>wouldn't
>>>>>>> have
>>>>>>> to
>>>>>>> do that.
>>>>>>> 
>>>>>>> Perhaps a better example is permissions. I already have an Upload
>>>>>>> bead.
>>>>>>> Now
>>>>>>> I want an alert to pop up if the user is not permitted to upload.
>>>>>>>I'd
>>>>>>> like
>>>>>>> to be able to add a 'CheckPemissionsOnUpload' bead. Right now I
>>>>>>>don't
>>>>>>> see
>>>>>>> how to do that, instead I would probably have to replace
>>>>>>>'UploadBead'
>>>>>>> with
>>>>>>> 'UploadButCheckPermissionsBead'. This takes us away from
>>>>>>>composition
>>>>>>> and
>>>>>>> forces inheritance.
>>>>>>> 
>>>>>>> Maybe we don't need to modify class definitions. I think it's
>>>>>>>enough
>>>>>>> to
>>>>>>> modify the bead instance. In JS we could simply replace the
>>>>>>>function,
>>>>>>> and
>>>>>>> in
>>>>>>> flash we could maybe replace the whole original bead with a
>>>>>>> flash.utils.Proxy. But this will make things a bit complicated to
>>>>>>>read
>>>>>>> and
>>>>>>> maintain.
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> --
>>>>>>> View this message in context:
>>>>>>> 
>>>>>>> 
>>>>>>>https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fapac
>>>>>>>he-
>>>>>>> fl
>>>>>>> e
>>>>>>> 
>>>>>>> 
>>>>>>>x-development.2333347.n4.nabble.com%2FRe-git-commit-flex-asjs-refs-h
>>>>>>>ead
>>>>>>> s-
>>>>>>> d
>>>>>>> 
>>>>>>> 
>>>>>>>evelop-Add-FileUploaderWithResponseData-tp63051p63139.html&data=02%7
>>>>>>>C01
>>>>>>> %7
>>>>>>> C
>>>>>>> 
>>>>>>> 
>>>>>>>%7Cbd5414b3ced9495c188908d4c8f0f59b%7Cfa7b1b5a7b34438794aed2c178dece
>>>>>>>e1%
>>>>>>> 7C
>>>>>>> 0
>>>>>>> 
>>>>>>> 
>>>>>>>%7C0%7C636354384624691027&sdata=BGn1g0wbTZr7ikn3uuhcIGDGPEmSVWTwIF%2
>>>>>>>Bla
>>>>>>> F6
>>>>>>> d
>>>>>>> v8w%3D&reserved=0
>>>>>>> Sent from the Apache Flex Development mailing list archive at
>>>>>>> Nabble.com.
>>>>>> 
>>>>> 
>>>> 
>>> 
>> 
>


Re: Bead Lifecycle (was Re: git commit: [flex-asjs] [refs/heads/develop] - Add FileUploaderWithResponseData)

Posted by Harbs <ha...@gmail.com>.
Thinking about this some more:

Order can be important, but that’s something that should be enforced by the strand. Where to add beads might change from strand to strand, but there should be some clear “point” where that happens (before beadsAdded). There needs to be a way to say "add a bead with the rest of them” and “add a bead now”. MXML and AS behavior should be the same.

Here’s what I’m thinking:

1. Strands should have a registerBead() method which takes a bead instance and adds it to a list, but does not yet add it.

2. addBead() should work exactly as it does today, but should be reserved for lazy instantiation, or early instantiation.

3. Strands should have a protected addBeads() method which takes no arguments, but adds all beads which were registered using registerBead(). Subclasses could override this method if necessary, but I don’t imagine this being usually necessary. One case where this would be important is when the order of beads is significant. For this to work, getBeadByType() would have to be modified to optionally get registered beads instead of added beads. The responsibility of order would rest on the Strand.

4. When addBeads() adds all the registered beads, it would send a beadsAdded notification to beads which care.

5. addBeads() would probably only ever be called once, but if there’s a valid reason to do so, maybe it can be called more than once and beadsAdded notification would be sent out again.

6. If there are cases where it’s necessary, pre/post beadsAdded notification could possibly be sent as well.

7. For beads when lazy instantiation does not make sense (i.e. most of the time), registerBead should be called for all beads in the constructor of the strand.

8. Beads declared in MXML, they should be instantiated with registerBead() rather than addBead(). That would allow code in set strand() to assume the strand is already properly set up, because the strand would only call addBeads() when it makes sense.

This would be a common lifecycle of all beads regardless of type. It should be easier to grok and give predictable behavior.

The notification vs events question is a separate point to ponder.

Thoughts?

> On Jul 14, 2017, at 3:38 AM, Harbs <ha...@gmail.com> wrote:
> 
> 1. I think so, or at most, only slightly. We’d probably save some code by not adding lots of functions for events and the like. I feel like the event system in general is bloated more than it needs to be.
> 2. I think there’s probably some and some. There’s probably going to be some lazy beads, and that’s ok. The way I see it is that there are two kinds of beads. There’s required ones which are not lazy and then there’s possibly-required, lazy ones. Lazy ones by definition will not need to listen for every notification. As long as there’s structure for the required ones, it’s good.
> 3. I think it’s okay to require certain classes of beads to be loaded in a certain order (i.e. controllers and views), as long as it doesn’t lead to pitfall bugs, but there’s probably others where requiring the order makes things difficult.
> 
> Totally agree about the compiler bit.
> 
> I generally think better by doing rather than writing.
> 
> What I might do when I have some spare time is to do some experiments on a branch and see what happens. I have no problem if my experiments turn out to be pointless. Either way, it should be educational. I think it would give a concrete point of reference.
> 
> Harbs
> 
>> On Jul 14, 2017, at 2:48 AM, Alex Harui <ah...@adobe.com.INVALID> wrote:
>> 
>> These are good points.  I'm glad I sent my PAYG email earlier today.  I'm
>> not sure I understood points #3 (dependencies) and #5 (cross-referencing)
>> so apologies if my thoughts below didn't take them into account.
>> 
>> I'd say that some of these ideas simply need to be tried and measured
>> against the PAYG metrics I proposed.  For example:
>> 1) Can we implement a second, lighterweight notification system without
>> increasing download size?  Besides mediators I think there is another
>> mechanism called AS3Signals.
>> 2) Can we have more consistency in when beads get instantiated or will
>> that cause too many beads to be instantiated "just-in-case"?  It may just
>> be that "just-in-time" or "lazy" instantiation of beads is going to make
>> it hard to know when a bead will be added to the strand, but I think
>> "just-in-time" instantiation is always going to provide best performance.
>> Too much consistency sometimes results in too much just-in-case code.
>> 3) Is it better to require certain beads to be placed on the strand before
>> other beads?  Does doing so make the code smaller or faster?  Will it be
>> more painful for developers to get the order right?  It might be best just
>> to find the best patterns for waiting for your partner beads.  One thing
>> to consider is that we have more control over when beads get added in
>> MXML, but we probably shouldn't have control over when beads get added in
>> AS.  I don't think the compiler can or should detect when the application
>> developer is going to add a bead and tell them not to do it.
>> 
>> There are probably at least two different "lifecycles".  Any individual
>> bead's lifecycle should be pretty simple: Instantiation, Initial
>> Properties, Add To Strand, Listen for Events/Notifications/Property
>> Changes.  Depending on how we decide #3 above, some beads may have a "wait
>> for my partner bead" phase.
>> A UI Component has a lifecycle of: Instantiation, Initial Properties, Add
>> To Parent, Add Beads.  But model beads may be instantiated and added on
>> demand in Initial Properties.  In "Add Beads" the model is added first if
>> not already added, then the view, then everything else.  In theory, the
>> "beadsAdded" event can be used by beads to know when significant changes
>> to the set of beads has occurred and that can be used to finish setting up
>> if you are waiting for partner beads, but otherwise, I think you can count
>> on model being instantiated on-demand and finish up in your strand setter.
>> 
>> The idea I liked the least was the notion that the Strand was some
>> intermediary and beads talk to the Strand, tell the Strand what their
>> interest are and things like that.  In my view the strand is just a bus
>> like you mentioned and isn't involved in any communications.  The beads
>> simply use the bus to find each other and find the most PAYG way of
>> communicating.  
>> 
>> Have you found common/popular patterns?  I don't really know because I've
>> been spending most of my time in the compiler.  If you have, then yes,
>> please document them.
>> 
>> My 2 cents,
>> -Alex
>> 
>> On 7/13/17, 3:40 PM, "Harbs" <ha...@gmail.com> wrote:
>> 
>>> Now that Yishay and I have spent quite some time with beads, I have some
>>> thoughts on the architecture.
>>> 
>>> Here’s some things I’ve noticed (somewhat randomly):
>>> 
>>> 1. There’s no clear place to add beads to components in AS. It seems like
>>> the catch-all place to do so is in addedToParent(), but many components
>>> add beads at other places. Many of these are lazy initialization and the
>>> like. There’s probably good reasons for all of these, but it’s confusing.
>>> Here’s a list of places where addBead() is called in Basic:
>>> start
>>> initHandler
>>> finishSetup
>>> set states
>>> get/set model
>>> get/set view
>>> get measurementBead
>>> setCursor
>>> get accordionCollapseBead
>>> get layout
>>> set strand
>>> createViewport
>>> createLists
>>> displayBackgroundAndBorder
>>> setupForBorder
>>> handleMessageChange
>>> get presentationModel
>>> constructor
>>> 
>>> Especially for someone who is new to this, it’s very confusing to know
>>> where the right place to add a bead is.
>>> 
>>> 2. It’s not immediately obvious that Beads can also be Strands. There are
>>> quite a few cases where that’s true. The only ones I’ve noticed were View
>>> Beads.
>>> 
>>> 3. It’s hard to follow which beads have which dependencies. There are
>>> event listeners added at seemingly random places and events dispatched
>>> seemingly randomly as well. It’s hard to follow the flow.
>>> 
>>> 4. It’s hard to know when beads are added and in what order.
>>> 
>>> 5. Even if you know what other beads and events your bead relies on, you
>>> need to cross-reference to know what exact events are being dispatched.
>>> 
>>> 6. The use of events is probably overkill for the needs of stands and
>>> beads. Strands are effectively a command bus for the beads (there’s many
>>> terms for the same concept). Events have significant overhead and
>>> indirection. Really what we need is for beads to tell the Strand “hey, I
>>> need to know when x happens so I can react and/or change what’s
>>> happening” and when beads do things they need to say “hey here’s what I
>>> did/ want to do”.
>>> 
>>> 7. Beads have no way of knowing when they can finish setting up. The only
>>> way to do so is attach event listeners which is a bit awkward.
>>> 
>>> I really like the Notification architecture in PureMVC, and I think it’s
>>> perfect for Strands and Beads.
>>> 
>>> Without going into all the nitty gritty details, the classes have some
>>> standard info that the “mediator” can use to find who’s interested in
>>> what. The classes which need to react to specific notifications (i.e.
>>> Mediators) list their interests and they are directly notified when
>>> something that interests them happened.
>>> 
>>> There’s also a clear lifecycle where functions can be called at
>>> predetermined times. Notification is done by using a Notification object
>>> which has three properties: name, type and body. Subscription to events
>>> happens through their names, but Notifications of the same name can
>>> modify their behavior by their type. body is an Object and can contain
>>> any kind of payload.
>>> 
>>> I’d like to see a couple of things with Strands and Beads.
>>> 
>>> 1. We should publish popular patterns for Strand/Bead interaction. (I’m
>>> talking to myself as much as anyone else.)
>>> 
>>> 2. I’d like to have a clearly documented lifecycle for beads. There are
>>> some standard bead types such as Model, Controller, View, Content View.
>>> When should each of these be created and how? At critical points in this
>>> cycle, things should happen automatically: The strand should pull from
>>> each bead which is added what interests it has.
>>> 
>>> 3. At the point when all “necessary” beads are added, the beads should
>>> have some method automatically called so they can “finish” their setup if
>>> they rely on another bead.
>>> 
>>> 4. All Strands should have a “notify” method that beads can call to let
>>> the strand know to let the appropriate beads know about an event. The
>>> beads should send a notification with the necessary payload if one is
>>> needed. Other beads can modify this payload and/or change the
>>> notification type if necessary. The publisher of the notification can
>>> examine the notification after it’s sent to know if it needs to do
>>> something different.
>>> 
>>> Bonus points if there’s some kind of “post process” on notifications in
>>> case a bead needs to wait until after some other bead did their thing.
>>> This can take the form of a “registerPostProcess” call to the bead which
>>> is only every called once per registration.
>>> 
>>> 5. I’m likely missing some points in the lifecycle…
>>> 
>>> This is something that I’d work on if others think this makes any kind of
>>> sense. While a lot of this is not very different from how events are
>>> working today, it feels to me like it would help give the strand/bead
>>> relationships a lot more structure.
>>> 
>>> Thoughts?
>>> Harbs
>>> 
>>>> 
>>>> On Jul 13, 2017, at 7:34 PM, Alex Harui <ah...@adobe.com.INVALID>
>>>> wrote:
>>>> 
>>>> Yes, that's how I think of it.  You are right that getting one bead in a
>>>> multi bead set to listen to other beads is tricky.  UIBase defines a
>>>> particular order of model first, then view, then controller.  But
>>>> otherwise, you either have to dictate your own order or find another
>>>> event
>>>> to listen to that will give a bead another chance to search the strand
>>>> for
>>>> other beads to listen to.  There is a "beadsAdded" event that can be
>>>> used.
>>>> 
>>>> Maybe as more folks implement multi-bead sets we'll see patterns emerge
>>>> and make it is simpler and faster.
>>>> 
>>>> My 2 cents,
>>>> -Alex
>>>> 
>>>> On 7/13/17, 3:54 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>>>> 
>>>>> Generally speaking it feels like sometimes I need to insure the order
>>>>> of
>>>>> invocation. Since beads communicate with one another through events
>>>>> it’s
>>>>> difficult to achieve. Regarding the upload response data I understand
>>>>> your suggestion as follows (edges contain event names):
>>>>> 
>>>>> <Strand>--uploadRequested--<controllerForWithResponse (sends
>>>>> request)>---complete---<ModelWithResponse (after controller wrote to
>>>>> model>---modelChanged--<UserClassListening>
>>>>> 
>>>>> And for the case where the user isn’t interested in the response, just
>>>>> in
>>>>> the status:
>>>>> 
>>>>> 
>>>>> <Strand>---uploadRequested--<controllerForWithoutResponse>---complete---
>>>>> <M
>>>>> odelWithoutResponse>--modelChanged--<UserClassListening>
>>>>> 
>>>>> Is that right?
>>>>> 
>>>>> 
>>>>> From: Alex Harui<ma...@adobe.com.INVALID>
>>>>> Sent: Wednesday, July 12, 2017 9:58 AM
>>>>> To: dev@flex.apache.org<ma...@flex.apache.org>
>>>>> Subject: Re: git commit: [flex-asjs] [refs/heads/develop] - Add
>>>>> FileUploaderWithResponseData
>>>>> 
>>>>> I think I still don't understand.
>>>>> 
>>>>> It is ok for beads to require other beads.  If a ResponseData bead
>>>>> requires a model with a slot for responseData and a controller that
>>>>> knows
>>>>> to record that data, that's how you are supposed to "re-compose"
>>>>> components.  There doesn't have to be one model or controller per
>>>>> component.  The strand is a gathering place for small pieces to work
>>>>> together.
>>>>> 
>>>>> I'm not sure what work CheckPermissions needs to do, but is totally
>>>>> fine
>>>>> to split its work amongst a set of beads.
>>>>> 
>>>>> HTH,
>>>>> -Alex
>>>>> 
>>>>> On 7/11/17, 11:21 PM, "yishayw" <yi...@hotmail.com> wrote:
>>>>> 
>>>>>> Ideally we wouldn't have to record data that's never read. This may
>>>>>> be an
>>>>>> extreme case, but some users will want to know the response on an
>>>>>> upload,
>>>>>> while some will just want to make sure the status is ok. I'd rather
>>>>>> not
>>>>>> anticipate too many use cases when writing the strand and the model
>>>>>> because
>>>>>> I might end up with code that's never used. If the bead was
>>>>>> responsible
>>>>>> for
>>>>>> both recording the response and exposing it to the user, we wouldn't
>>>>>> have
>>>>>> to
>>>>>> do that.
>>>>>> 
>>>>>> Perhaps a better example is permissions. I already have an Upload
>>>>>> bead.
>>>>>> Now
>>>>>> I want an alert to pop up if the user is not permitted to upload. I'd
>>>>>> like
>>>>>> to be able to add a 'CheckPemissionsOnUpload' bead. Right now I don't
>>>>>> see
>>>>>> how to do that, instead I would probably have to replace 'UploadBead'
>>>>>> with
>>>>>> 'UploadButCheckPermissionsBead'. This takes us away from composition
>>>>>> and
>>>>>> forces inheritance.
>>>>>> 
>>>>>> Maybe we don't need to modify class definitions. I think it's enough
>>>>>> to
>>>>>> modify the bead instance. In JS we could simply replace the function,
>>>>>> and
>>>>>> in
>>>>>> flash we could maybe replace the whole original bead with a
>>>>>> flash.utils.Proxy. But this will make things a bit complicated to read
>>>>>> and
>>>>>> maintain.
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> --
>>>>>> View this message in context:
>>>>>> 
>>>>>> https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fapache-
>>>>>> fl
>>>>>> e
>>>>>> 
>>>>>> x-development.2333347.n4.nabble.com%2FRe-git-commit-flex-asjs-refs-head
>>>>>> s-
>>>>>> d
>>>>>> 
>>>>>> evelop-Add-FileUploaderWithResponseData-tp63051p63139.html&data=02%7C01
>>>>>> %7
>>>>>> C
>>>>>> 
>>>>>> %7Cbd5414b3ced9495c188908d4c8f0f59b%7Cfa7b1b5a7b34438794aed2c178decee1%
>>>>>> 7C
>>>>>> 0
>>>>>> 
>>>>>> %7C0%7C636354384624691027&sdata=BGn1g0wbTZr7ikn3uuhcIGDGPEmSVWTwIF%2Bla
>>>>>> F6
>>>>>> d
>>>>>> v8w%3D&reserved=0
>>>>>> Sent from the Apache Flex Development mailing list archive at
>>>>>> Nabble.com.
>>>>> 
>>>> 
>>> 
>> 
> 


Re: Bead Lifecycle (was Re: git commit: [flex-asjs] [refs/heads/develop] - Add FileUploaderWithResponseData)

Posted by Harbs <ha...@gmail.com>.
1. I think so, or at most, only slightly. We’d probably save some code by not adding lots of functions for events and the like. I feel like the event system in general is bloated more than it needs to be.
2. I think there’s probably some and some. There’s probably going to be some lazy beads, and that’s ok. The way I see it is that there are two kinds of beads. There’s required ones which are not lazy and then there’s possibly-required, lazy ones. Lazy ones by definition will not need to listen for every notification. As long as there’s structure for the required ones, it’s good.
3. I think it’s okay to require certain classes of beads to be loaded in a certain order (i.e. controllers and views), as long as it doesn’t lead to pitfall bugs, but there’s probably others where requiring the order makes things difficult.

Totally agree about the compiler bit.

I generally think better by doing rather than writing.

What I might do when I have some spare time is to do some experiments on a branch and see what happens. I have no problem if my experiments turn out to be pointless. Either way, it should be educational. I think it would give a concrete point of reference.

Harbs

> On Jul 14, 2017, at 2:48 AM, Alex Harui <ah...@adobe.com.INVALID> wrote:
> 
> These are good points.  I'm glad I sent my PAYG email earlier today.  I'm
> not sure I understood points #3 (dependencies) and #5 (cross-referencing)
> so apologies if my thoughts below didn't take them into account.
> 
> I'd say that some of these ideas simply need to be tried and measured
> against the PAYG metrics I proposed.  For example:
> 1) Can we implement a second, lighterweight notification system without
> increasing download size?  Besides mediators I think there is another
> mechanism called AS3Signals.
> 2) Can we have more consistency in when beads get instantiated or will
> that cause too many beads to be instantiated "just-in-case"?  It may just
> be that "just-in-time" or "lazy" instantiation of beads is going to make
> it hard to know when a bead will be added to the strand, but I think
> "just-in-time" instantiation is always going to provide best performance.
> Too much consistency sometimes results in too much just-in-case code.
> 3) Is it better to require certain beads to be placed on the strand before
> other beads?  Does doing so make the code smaller or faster?  Will it be
> more painful for developers to get the order right?  It might be best just
> to find the best patterns for waiting for your partner beads.  One thing
> to consider is that we have more control over when beads get added in
> MXML, but we probably shouldn't have control over when beads get added in
> AS.  I don't think the compiler can or should detect when the application
> developer is going to add a bead and tell them not to do it.
> 
> There are probably at least two different "lifecycles".  Any individual
> bead's lifecycle should be pretty simple: Instantiation, Initial
> Properties, Add To Strand, Listen for Events/Notifications/Property
> Changes.  Depending on how we decide #3 above, some beads may have a "wait
> for my partner bead" phase.
> A UI Component has a lifecycle of: Instantiation, Initial Properties, Add
> To Parent, Add Beads.  But model beads may be instantiated and added on
> demand in Initial Properties.  In "Add Beads" the model is added first if
> not already added, then the view, then everything else.  In theory, the
> "beadsAdded" event can be used by beads to know when significant changes
> to the set of beads has occurred and that can be used to finish setting up
> if you are waiting for partner beads, but otherwise, I think you can count
> on model being instantiated on-demand and finish up in your strand setter.
> 
> The idea I liked the least was the notion that the Strand was some
> intermediary and beads talk to the Strand, tell the Strand what their
> interest are and things like that.  In my view the strand is just a bus
> like you mentioned and isn't involved in any communications.  The beads
> simply use the bus to find each other and find the most PAYG way of
> communicating.  
> 
> Have you found common/popular patterns?  I don't really know because I've
> been spending most of my time in the compiler.  If you have, then yes,
> please document them.
> 
> My 2 cents,
> -Alex
> 
> On 7/13/17, 3:40 PM, "Harbs" <ha...@gmail.com> wrote:
> 
>> Now that Yishay and I have spent quite some time with beads, I have some
>> thoughts on the architecture.
>> 
>> Here’s some things I’ve noticed (somewhat randomly):
>> 
>> 1. There’s no clear place to add beads to components in AS. It seems like
>> the catch-all place to do so is in addedToParent(), but many components
>> add beads at other places. Many of these are lazy initialization and the
>> like. There’s probably good reasons for all of these, but it’s confusing.
>> Here’s a list of places where addBead() is called in Basic:
>> start
>> initHandler
>> finishSetup
>> set states
>> get/set model
>> get/set view
>> get measurementBead
>> setCursor
>> get accordionCollapseBead
>> get layout
>> set strand
>> createViewport
>> createLists
>> displayBackgroundAndBorder
>> setupForBorder
>> handleMessageChange
>> get presentationModel
>> constructor
>> 
>> Especially for someone who is new to this, it’s very confusing to know
>> where the right place to add a bead is.
>> 
>> 2. It’s not immediately obvious that Beads can also be Strands. There are
>> quite a few cases where that’s true. The only ones I’ve noticed were View
>> Beads.
>> 
>> 3. It’s hard to follow which beads have which dependencies. There are
>> event listeners added at seemingly random places and events dispatched
>> seemingly randomly as well. It’s hard to follow the flow.
>> 
>> 4. It’s hard to know when beads are added and in what order.
>> 
>> 5. Even if you know what other beads and events your bead relies on, you
>> need to cross-reference to know what exact events are being dispatched.
>> 
>> 6. The use of events is probably overkill for the needs of stands and
>> beads. Strands are effectively a command bus for the beads (there’s many
>> terms for the same concept). Events have significant overhead and
>> indirection. Really what we need is for beads to tell the Strand “hey, I
>> need to know when x happens so I can react and/or change what’s
>> happening” and when beads do things they need to say “hey here’s what I
>> did/ want to do”.
>> 
>> 7. Beads have no way of knowing when they can finish setting up. The only
>> way to do so is attach event listeners which is a bit awkward.
>> 
>> I really like the Notification architecture in PureMVC, and I think it’s
>> perfect for Strands and Beads.
>> 
>> Without going into all the nitty gritty details, the classes have some
>> standard info that the “mediator” can use to find who’s interested in
>> what. The classes which need to react to specific notifications (i.e.
>> Mediators) list their interests and they are directly notified when
>> something that interests them happened.
>> 
>> There’s also a clear lifecycle where functions can be called at
>> predetermined times. Notification is done by using a Notification object
>> which has three properties: name, type and body. Subscription to events
>> happens through their names, but Notifications of the same name can
>> modify their behavior by their type. body is an Object and can contain
>> any kind of payload.
>> 
>> I’d like to see a couple of things with Strands and Beads.
>> 
>> 1. We should publish popular patterns for Strand/Bead interaction. (I’m
>> talking to myself as much as anyone else.)
>> 
>> 2. I’d like to have a clearly documented lifecycle for beads. There are
>> some standard bead types such as Model, Controller, View, Content View.
>> When should each of these be created and how? At critical points in this
>> cycle, things should happen automatically: The strand should pull from
>> each bead which is added what interests it has.
>> 
>> 3. At the point when all “necessary” beads are added, the beads should
>> have some method automatically called so they can “finish” their setup if
>> they rely on another bead.
>> 
>> 4. All Strands should have a “notify” method that beads can call to let
>> the strand know to let the appropriate beads know about an event. The
>> beads should send a notification with the necessary payload if one is
>> needed. Other beads can modify this payload and/or change the
>> notification type if necessary. The publisher of the notification can
>> examine the notification after it’s sent to know if it needs to do
>> something different.
>> 
>> Bonus points if there’s some kind of “post process” on notifications in
>> case a bead needs to wait until after some other bead did their thing.
>> This can take the form of a “registerPostProcess” call to the bead which
>> is only every called once per registration.
>> 
>> 5. I’m likely missing some points in the lifecycle…
>> 
>> This is something that I’d work on if others think this makes any kind of
>> sense. While a lot of this is not very different from how events are
>> working today, it feels to me like it would help give the strand/bead
>> relationships a lot more structure.
>> 
>> Thoughts?
>> Harbs
>> 
>>> 
>>> On Jul 13, 2017, at 7:34 PM, Alex Harui <ah...@adobe.com.INVALID>
>>> wrote:
>>> 
>>> Yes, that's how I think of it.  You are right that getting one bead in a
>>> multi bead set to listen to other beads is tricky.  UIBase defines a
>>> particular order of model first, then view, then controller.  But
>>> otherwise, you either have to dictate your own order or find another
>>> event
>>> to listen to that will give a bead another chance to search the strand
>>> for
>>> other beads to listen to.  There is a "beadsAdded" event that can be
>>> used.
>>> 
>>> Maybe as more folks implement multi-bead sets we'll see patterns emerge
>>> and make it is simpler and faster.
>>> 
>>> My 2 cents,
>>> -Alex
>>> 
>>> On 7/13/17, 3:54 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>>> 
>>>> Generally speaking it feels like sometimes I need to insure the order
>>>> of
>>>> invocation. Since beads communicate with one another through events
>>>> it’s
>>>> difficult to achieve. Regarding the upload response data I understand
>>>> your suggestion as follows (edges contain event names):
>>>> 
>>>> <Strand>--uploadRequested--<controllerForWithResponse (sends
>>>> request)>---complete---<ModelWithResponse (after controller wrote to
>>>> model>---modelChanged--<UserClassListening>
>>>> 
>>>> And for the case where the user isn’t interested in the response, just
>>>> in
>>>> the status:
>>>> 
>>>> 
>>>> <Strand>---uploadRequested--<controllerForWithoutResponse>---complete---
>>>> <M
>>>> odelWithoutResponse>--modelChanged--<UserClassListening>
>>>> 
>>>> Is that right?
>>>> 
>>>> 
>>>> From: Alex Harui<ma...@adobe.com.INVALID>
>>>> Sent: Wednesday, July 12, 2017 9:58 AM
>>>> To: dev@flex.apache.org<ma...@flex.apache.org>
>>>> Subject: Re: git commit: [flex-asjs] [refs/heads/develop] - Add
>>>> FileUploaderWithResponseData
>>>> 
>>>> I think I still don't understand.
>>>> 
>>>> It is ok for beads to require other beads.  If a ResponseData bead
>>>> requires a model with a slot for responseData and a controller that
>>>> knows
>>>> to record that data, that's how you are supposed to "re-compose"
>>>> components.  There doesn't have to be one model or controller per
>>>> component.  The strand is a gathering place for small pieces to work
>>>> together.
>>>> 
>>>> I'm not sure what work CheckPermissions needs to do, but is totally
>>>> fine
>>>> to split its work amongst a set of beads.
>>>> 
>>>> HTH,
>>>> -Alex
>>>> 
>>>> On 7/11/17, 11:21 PM, "yishayw" <yi...@hotmail.com> wrote:
>>>> 
>>>>> Ideally we wouldn't have to record data that's never read. This may
>>>>> be an
>>>>> extreme case, but some users will want to know the response on an
>>>>> upload,
>>>>> while some will just want to make sure the status is ok. I'd rather
>>>>> not
>>>>> anticipate too many use cases when writing the strand and the model
>>>>> because
>>>>> I might end up with code that's never used. If the bead was
>>>>> responsible
>>>>> for
>>>>> both recording the response and exposing it to the user, we wouldn't
>>>>> have
>>>>> to
>>>>> do that.
>>>>> 
>>>>> Perhaps a better example is permissions. I already have an Upload
>>>>> bead.
>>>>> Now
>>>>> I want an alert to pop up if the user is not permitted to upload. I'd
>>>>> like
>>>>> to be able to add a 'CheckPemissionsOnUpload' bead. Right now I don't
>>>>> see
>>>>> how to do that, instead I would probably have to replace 'UploadBead'
>>>>> with
>>>>> 'UploadButCheckPermissionsBead'. This takes us away from composition
>>>>> and
>>>>> forces inheritance.
>>>>> 
>>>>> Maybe we don't need to modify class definitions. I think it's enough
>>>>> to
>>>>> modify the bead instance. In JS we could simply replace the function,
>>>>> and
>>>>> in
>>>>> flash we could maybe replace the whole original bead with a
>>>>> flash.utils.Proxy. But this will make things a bit complicated to read
>>>>> and
>>>>> maintain.
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> --
>>>>> View this message in context:
>>>>> 
>>>>> https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fapache-
>>>>> fl
>>>>> e
>>>>> 
>>>>> x-development.2333347.n4.nabble.com%2FRe-git-commit-flex-asjs-refs-head
>>>>> s-
>>>>> d
>>>>> 
>>>>> evelop-Add-FileUploaderWithResponseData-tp63051p63139.html&data=02%7C01
>>>>> %7
>>>>> C
>>>>> 
>>>>> %7Cbd5414b3ced9495c188908d4c8f0f59b%7Cfa7b1b5a7b34438794aed2c178decee1%
>>>>> 7C
>>>>> 0
>>>>> 
>>>>> %7C0%7C636354384624691027&sdata=BGn1g0wbTZr7ikn3uuhcIGDGPEmSVWTwIF%2Bla
>>>>> F6
>>>>> d
>>>>> v8w%3D&reserved=0
>>>>> Sent from the Apache Flex Development mailing list archive at
>>>>> Nabble.com.
>>>> 
>>> 
>> 
> 


Re: Bead Lifecycle (was Re: git commit: [flex-asjs] [refs/heads/develop] - Add FileUploaderWithResponseData)

Posted by Alex Harui <ah...@adobe.com.INVALID>.
These are good points.  I'm glad I sent my PAYG email earlier today.  I'm
not sure I understood points #3 (dependencies) and #5 (cross-referencing)
so apologies if my thoughts below didn't take them into account.

I'd say that some of these ideas simply need to be tried and measured
against the PAYG metrics I proposed.  For example:
1) Can we implement a second, lighterweight notification system without
increasing download size?  Besides mediators I think there is another
mechanism called AS3Signals.
2) Can we have more consistency in when beads get instantiated or will
that cause too many beads to be instantiated "just-in-case"?  It may just
be that "just-in-time" or "lazy" instantiation of beads is going to make
it hard to know when a bead will be added to the strand, but I think
"just-in-time" instantiation is always going to provide best performance.
Too much consistency sometimes results in too much just-in-case code.
3) Is it better to require certain beads to be placed on the strand before
other beads?  Does doing so make the code smaller or faster?  Will it be
more painful for developers to get the order right?  It might be best just
to find the best patterns for waiting for your partner beads.  One thing
to consider is that we have more control over when beads get added in
MXML, but we probably shouldn't have control over when beads get added in
AS.  I don't think the compiler can or should detect when the application
developer is going to add a bead and tell them not to do it.

There are probably at least two different "lifecycles".  Any individual
bead's lifecycle should be pretty simple: Instantiation, Initial
Properties, Add To Strand, Listen for Events/Notifications/Property
Changes.  Depending on how we decide #3 above, some beads may have a "wait
for my partner bead" phase.
A UI Component has a lifecycle of: Instantiation, Initial Properties, Add
To Parent, Add Beads.  But model beads may be instantiated and added on
demand in Initial Properties.  In "Add Beads" the model is added first if
not already added, then the view, then everything else.  In theory, the
"beadsAdded" event can be used by beads to know when significant changes
to the set of beads has occurred and that can be used to finish setting up
if you are waiting for partner beads, but otherwise, I think you can count
on model being instantiated on-demand and finish up in your strand setter.

The idea I liked the least was the notion that the Strand was some
intermediary and beads talk to the Strand, tell the Strand what their
interest are and things like that.  In my view the strand is just a bus
like you mentioned and isn't involved in any communications.  The beads
simply use the bus to find each other and find the most PAYG way of
communicating.  

Have you found common/popular patterns?  I don't really know because I've
been spending most of my time in the compiler.  If you have, then yes,
please document them.

My 2 cents,
-Alex

On 7/13/17, 3:40 PM, "Harbs" <ha...@gmail.com> wrote:

>Now that Yishay and I have spent quite some time with beads, I have some
>thoughts on the architecture.
>
>Here’s some things I’ve noticed (somewhat randomly):
>
>1. There’s no clear place to add beads to components in AS. It seems like
>the catch-all place to do so is in addedToParent(), but many components
>add beads at other places. Many of these are lazy initialization and the
>like. There’s probably good reasons for all of these, but it’s confusing.
>Here’s a list of places where addBead() is called in Basic:
>start
>initHandler
>finishSetup
>set states
>get/set model
>get/set view
>get measurementBead
>setCursor
>get accordionCollapseBead
>get layout
>set strand
>createViewport
>createLists
>displayBackgroundAndBorder
>setupForBorder
>handleMessageChange
>get presentationModel
>constructor
>
>Especially for someone who is new to this, it’s very confusing to know
>where the right place to add a bead is.
>
>2. It’s not immediately obvious that Beads can also be Strands. There are
>quite a few cases where that’s true. The only ones I’ve noticed were View
>Beads.
>
>3. It’s hard to follow which beads have which dependencies. There are
>event listeners added at seemingly random places and events dispatched
>seemingly randomly as well. It’s hard to follow the flow.
>
>4. It’s hard to know when beads are added and in what order.
>
>5. Even if you know what other beads and events your bead relies on, you
>need to cross-reference to know what exact events are being dispatched.
>
>6. The use of events is probably overkill for the needs of stands and
>beads. Strands are effectively a command bus for the beads (there’s many
>terms for the same concept). Events have significant overhead and
>indirection. Really what we need is for beads to tell the Strand “hey, I
>need to know when x happens so I can react and/or change what’s
>happening” and when beads do things they need to say “hey here’s what I
>did/ want to do”.
>
>7. Beads have no way of knowing when they can finish setting up. The only
>way to do so is attach event listeners which is a bit awkward.
>
>I really like the Notification architecture in PureMVC, and I think it’s
>perfect for Strands and Beads.
>
>Without going into all the nitty gritty details, the classes have some
>standard info that the “mediator” can use to find who’s interested in
>what. The classes which need to react to specific notifications (i.e.
>Mediators) list their interests and they are directly notified when
>something that interests them happened.
>
>There’s also a clear lifecycle where functions can be called at
>predetermined times. Notification is done by using a Notification object
>which has three properties: name, type and body. Subscription to events
>happens through their names, but Notifications of the same name can
>modify their behavior by their type. body is an Object and can contain
>any kind of payload.
>
>I’d like to see a couple of things with Strands and Beads.
>
>1. We should publish popular patterns for Strand/Bead interaction. (I’m
>talking to myself as much as anyone else.)
>
>2. I’d like to have a clearly documented lifecycle for beads. There are
>some standard bead types such as Model, Controller, View, Content View.
>When should each of these be created and how? At critical points in this
>cycle, things should happen automatically: The strand should pull from
>each bead which is added what interests it has.
>
>3. At the point when all “necessary” beads are added, the beads should
>have some method automatically called so they can “finish” their setup if
>they rely on another bead.
>
>4. All Strands should have a “notify” method that beads can call to let
>the strand know to let the appropriate beads know about an event. The
>beads should send a notification with the necessary payload if one is
>needed. Other beads can modify this payload and/or change the
>notification type if necessary. The publisher of the notification can
>examine the notification after it’s sent to know if it needs to do
>something different.
>
>Bonus points if there’s some kind of “post process” on notifications in
>case a bead needs to wait until after some other bead did their thing.
>This can take the form of a “registerPostProcess” call to the bead which
>is only every called once per registration.
>
>5. I’m likely missing some points in the lifecycle…
>
>This is something that I’d work on if others think this makes any kind of
>sense. While a lot of this is not very different from how events are
>working today, it feels to me like it would help give the strand/bead
>relationships a lot more structure.
>
>Thoughts?
>Harbs
>
>> 
>> On Jul 13, 2017, at 7:34 PM, Alex Harui <ah...@adobe.com.INVALID>
>>wrote:
>> 
>> Yes, that's how I think of it.  You are right that getting one bead in a
>> multi bead set to listen to other beads is tricky.  UIBase defines a
>> particular order of model first, then view, then controller.  But
>> otherwise, you either have to dictate your own order or find another
>>event
>> to listen to that will give a bead another chance to search the strand
>>for
>> other beads to listen to.  There is a "beadsAdded" event that can be
>>used.
>> 
>> Maybe as more folks implement multi-bead sets we'll see patterns emerge
>> and make it is simpler and faster.
>> 
>> My 2 cents,
>> -Alex
>> 
>> On 7/13/17, 3:54 AM, "Yishay Weiss" <yi...@hotmail.com> wrote:
>> 
>>> Generally speaking it feels like sometimes I need to insure the order
>>>of
>>> invocation. Since beads communicate with one another through events
>>>it’s
>>> difficult to achieve. Regarding the upload response data I understand
>>> your suggestion as follows (edges contain event names):
>>> 
>>> <Strand>--uploadRequested--<controllerForWithResponse (sends
>>> request)>---complete---<ModelWithResponse (after controller wrote to
>>> model>---modelChanged--<UserClassListening>
>>> 
>>> And for the case where the user isn’t interested in the response, just
>>>in
>>> the status:
>>> 
>>> 
>>><Strand>---uploadRequested--<controllerForWithoutResponse>---complete---
>>><M
>>> odelWithoutResponse>--modelChanged--<UserClassListening>
>>> 
>>> Is that right?
>>> 
>>> 
>>> From: Alex Harui<ma...@adobe.com.INVALID>
>>> Sent: Wednesday, July 12, 2017 9:58 AM
>>> To: dev@flex.apache.org<ma...@flex.apache.org>
>>> Subject: Re: git commit: [flex-asjs] [refs/heads/develop] - Add
>>> FileUploaderWithResponseData
>>> 
>>> I think I still don't understand.
>>> 
>>> It is ok for beads to require other beads.  If a ResponseData bead
>>> requires a model with a slot for responseData and a controller that
>>>knows
>>> to record that data, that's how you are supposed to "re-compose"
>>> components.  There doesn't have to be one model or controller per
>>> component.  The strand is a gathering place for small pieces to work
>>> together.
>>> 
>>> I'm not sure what work CheckPermissions needs to do, but is totally
>>>fine
>>> to split its work amongst a set of beads.
>>> 
>>> HTH,
>>> -Alex
>>> 
>>> On 7/11/17, 11:21 PM, "yishayw" <yi...@hotmail.com> wrote:
>>> 
>>>> Ideally we wouldn't have to record data that's never read. This may
>>>>be an
>>>> extreme case, but some users will want to know the response on an
>>>>upload,
>>>> while some will just want to make sure the status is ok. I'd rather
>>>>not
>>>> anticipate too many use cases when writing the strand and the model
>>>> because
>>>> I might end up with code that's never used. If the bead was
>>>>responsible
>>>> for
>>>> both recording the response and exposing it to the user, we wouldn't
>>>>have
>>>> to
>>>> do that.
>>>> 
>>>> Perhaps a better example is permissions. I already have an Upload
>>>>bead.
>>>> Now
>>>> I want an alert to pop up if the user is not permitted to upload. I'd
>>>> like
>>>> to be able to add a 'CheckPemissionsOnUpload' bead. Right now I don't
>>>>see
>>>> how to do that, instead I would probably have to replace 'UploadBead'
>>>> with
>>>> 'UploadButCheckPermissionsBead'. This takes us away from composition
>>>>and
>>>> forces inheritance.
>>>> 
>>>> Maybe we don't need to modify class definitions. I think it's enough
>>>>to
>>>> modify the bead instance. In JS we could simply replace the function,
>>>>and
>>>> in
>>>> flash we could maybe replace the whole original bead with a
>>>> flash.utils.Proxy. But this will make things a bit complicated to read
>>>> and
>>>> maintain.
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> --
>>>> View this message in context:
>>>> 
>>>>https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fapache-
>>>>fl
>>>> e
>>>> 
>>>>x-development.2333347.n4.nabble.com%2FRe-git-commit-flex-asjs-refs-head
>>>>s-
>>>> d
>>>> 
>>>>evelop-Add-FileUploaderWithResponseData-tp63051p63139.html&data=02%7C01
>>>>%7
>>>> C
>>>> 
>>>>%7Cbd5414b3ced9495c188908d4c8f0f59b%7Cfa7b1b5a7b34438794aed2c178decee1%
>>>>7C
>>>> 0
>>>> 
>>>>%7C0%7C636354384624691027&sdata=BGn1g0wbTZr7ikn3uuhcIGDGPEmSVWTwIF%2Bla
>>>>F6
>>>> d
>>>> v8w%3D&reserved=0
>>>> Sent from the Apache Flex Development mailing list archive at
>>>>Nabble.com.
>>> 
>> 
>