These are chat archives for jdubray/sam

6th
Feb 2018
Leszek Żarna
@leszarna_twitter
Feb 06 2018 19:32
Hello,
first I would like to thank you for SAM pattern and all the clues in articles about programming you have gave to community. I’ve read some papers about TLA+ from Dr Lamport and it helped me to understand SAM idea more. Also reference to State Machine helps to understand State (Control State). Thank you.
in the article https://dzone.com/articles/the-three-approximations-you-should-never-use-when there is sentence I would like to discuss:
"One of the key advantages of SAM is that you no longer need ancillary state machines to manage side effects. Actions can call APIs and propose the results to the model, there is no particular reason to enter the model and mutate a property such as “fetching,” just to keep track of the API call lifecycle."
Is that just example or just more general statement and approach with ancillary model is also equally valid ?
I have some examples in my mind when using helper that has properties like executing/feching: Bool, value: T, error: Error is natural for me and I cannot find easy solution making this only on the Action side
For example when we have long list view that calls API data and displays it. API queries have page, page_size parameters so data is paged.
Leszek Żarna
@leszarna_twitter
Feb 06 2018 19:38
When there are events from ListView/TableView UI component data is required from data source. So I send load(page: N) or load(row: R) to my model and model has such ancillary tracker for api calls for every page
Jean-Jacques Dubray
@jdubray
Feb 06 2018 19:39
@leszarna_twitter thank you. It's equally valid, but IMHO it introduces too much boilerplate. I tried it and felt it didn't add much value.
Leszek Żarna
@leszarna_twitter
Feb 06 2018 19:39
I try to think about doing this on the Action side but one problem I get is that List elements would trigger the same api call many times
because there are many request events about some row that translate to api call for page of data
so I would have to track actions if there is some api call already started etc
not sure how solution for this could look like. If you know some examples of it I would be very happy to see them.
Jean-Jacques Dubray
@jdubray
Feb 06 2018 19:41
@leszarna_twitter I am not sure why you could not make this call in the action?
I try to think about doing this on the Action side but one problem I get is that List elements would trigger the same api call many times
because there are many request events about some row that translate to api call for page of data
I would need to know more about this.
Leszek Żarna
@leszarna_twitter
Feb 06 2018 19:43
I can but I feel I need to track/account about those calls, what makes me feel that I need to track calls, if they are occuring with fetching property and what is result data or error (“network is offline”) for example. So in summary if I remove this helper from my Model I have to use this state machine on the Action side
Jean-Jacques Dubray
@jdubray
Feb 06 2018 19:44
I guess if you have to check if you need to make a call, I would definitely use NAP and some ancillary state machine to manage it.
There is nothing wrong with it, it's just overkill to have to do it for every single API call.
I am biased, but I'd say that the beauty of the structure of the pattern, binary state machines are implicity handled by the decoupling action/acceptor, when more complex state machines are required, it's handled properly via nap.
devin ivy
@devinivy
Feb 06 2018 19:52
nothing makes you keep track of request state in standard redux any more than in SAM, does it?
Leszek Żarna
@leszarna_twitter
Feb 06 2018 19:52
Yes, I am pretty sure that’s true. When I’ve started working with SAM and rewriting to SAM ( I believe ) I came with one solution having this inside model. And you know I am so anxious to try other possibilities suggested. I am anxious to miss better solutions and stay with these solution for next several years.
Jean-Jacques Dubray
@jdubray
Feb 06 2018 19:53
@devinivy I don't disagree, though this is not touted as a "best practice". As you know it's easy to use Redux in a SAM way if you choose to, but again, the Redux community if focusing the following a "pure" functional approach.
devin ivy
@devinivy
Feb 06 2018 19:54
ah i see!
Leszek Żarna
@leszarna_twitter
Feb 06 2018 19:54
So do you think could we also have this ancillary state machines in helper model and than in state/render function push this to main model ?
I am afraid there are countless posibilities of solutions with SAM :) which is advantage of it of course
Jean-Jacques Dubray
@jdubray
Feb 06 2018 19:57
@leszarna_twitter I am not sure I understand what you mean by helper model, personally, I would implement it as:
  • action proposes API call requested (and checks if network is available)
  • model accepts proposal by translating the proposed API call into the effective one, could also reject it silently if redundant
  • nap checks if there is a call to make and triggers a new action
Leszek Żarna
@leszarna_twitter
Feb 06 2018 20:05
so when model has to choose initial condition for action, it would have to check 2 things (1) if data is already available (action rejected) or (2) if such api call is already executing in the background (action rejected) and will deliver result soon or will fail with error ( and than nap could retry this call for example ), true ? But isn’t your example moving effective call to the model ?
Jean-Jacques Dubray
@jdubray
Feb 06 2018 20:06
The calls will happen in an action that is triggered by nap.
If you know what you are doing, you can call from the model, you can create an inner ... -> nap -> dedicated_action -> ... loop, as long as it does not interferes with other actions.
On average it's just easier to reason with a single action->model->state loop, but that's not a requirement.
you can have as many as you want in parallel. You'll run into problems if the user is trying to do something while these loops are running.
Leszek Żarna
@leszarna_twitter
Feb 06 2018 20:11
so nap could trigger other action that actually performs real call and presents page of data to the model, that way async job is “outsourced” to the action and outside of model, true ?
Jean-Jacques Dubray
@jdubray
Feb 06 2018 20:11
yes, that's how I would do it.
Leszek Żarna
@leszarna_twitter
Feb 06 2018 20:11
right ! I think I got your point now
it’s very interesting, I think I could try implement this
thank you very much
Jean-Jacques Dubray
@jdubray
Feb 06 2018 20:12
you are welcome!
Leszek Żarna
@leszarna_twitter
Feb 06 2018 20:12
that’s very helpful to get other point of view I could not think myself :)
anyway my experience is that this concept of SAM is not easy to understand well and quickly at first, it took a lot of time for me despite I have some experience with state machines since school
Jean-Jacques Dubray
@jdubray
Feb 06 2018 21:20
I am always interested to hear/see what people think of it, good or bad. Happy to answer any question.
Leszek Żarna
@leszarna_twitter
Feb 06 2018 22:21
I wonder in last example if nap triggers action that does async task before presenting something to model ( api call result) how can we prevent that as result of stuttering or other action in between nap triggers same action multiple times
which would be unnecessary resource usage - same network call in this example
Leszek Żarna
@leszarna_twitter
Feb 06 2018 22:36
searching archive it seems quite common question :)
Jean-Jacques Dubray
@jdubray
Feb 06 2018 22:45
@leszarna_twitter you can present twice from the same action!
as the action starts the proposal would tell the model that the action has initiated the async call, you can use that value to avoid triggering it again. When the API call returns you present a second time with the results.
Leszek Żarna
@leszarna_twitter
Feb 06 2018 22:58
twice :) awesome solution
I was wondering how to persist this information,
solution with one action per time seems to be not efficient regarding system response if many async tasks,
present() twice to the model from one action is excellent !
devin ivy
@devinivy
Feb 06 2018 23:02
when implementing SAM in redux that's called a "thunk", and propose() is called dispatch().