pass pillar to reactor from a state - salt-stack

I have one orchestrator which applying some stuff on a bunch of minions.
Also, have a reactor that is listening for a certain event to be returned from a state, "- fire_event: my custom tag".
What I need is somehow to pass pillar data to the reactor from the state, is it possible at all?

The best method would be to include the pillar data in the event you are sending. If you are using event.send state to send the event, you can include with_pillar: true in the state, to include all pillar data. If you don't want to include all pillars, you can use jinja to render the pillars you do want into the data section.
event sending:
event.send:
- name: event/tag/like/normal
- data:
item1: {{salt["pillar.get"]('thing1')}}
item2: {{salt["pillar.get"]('etc')}}
Things in data will be included in the event that gets to the reactor.

Related

What happens to the old state in redux on dispatch of action resulting in new state

In Redux once we dispatch an action we get a new state with the updated values . What happens to the previous old state ?
The old state is discarded. If you want to save it, you need to incorporate it as part of your state. One way to do that is explained here: Implementing Undo History.
Another option is to use an "Event Sourcing" model. Where your primary state is merely an array of all actions that have transpired and you have a derivative state that reduces the array in the primary state into a "current app state." Here's an explanation of the idea for Elm: Elm and Event Sourcing
Redux state is nothing but a javascript object in your memory. There is only one version of the state, which is your latest one.
When you dispatch an action, the action handler (reducer) is a pure function which will convert your old state to new state. state should be immutable, which means the action handler does not change the old state, but get the copy of it, and then change it depends on your action type, then return it. It will looks like ("--->" means dispatch):
initial state ---> state 1 ---> state 2 ---> state 3 ....
You can install the redux plugin in chrome, and you will see the whole history of the state.
So basically, redux does not save any old state, if you wanna trace the history, you have to do it yourself by using Stack or using some other libs.
I actually implement the event tracing using data structure stack, when state changes, you push to stack, when you wanna go back to previous state, you just pop the state and dispatch a special action to change the state, this special dispatch should not trigger push, very rough idea though.

Redux / Flux Pattern for Fetching Data When Store Updates

I have what I believe is a very common scenario... I'm building a dashboard of components that will be driven by some datasource. At the top of the view would be a series of filters (e.g. a date range). When the date range is updated, the components on the screen would need to update their data based on the selected range. This would in turn force the individual components that are slave to that picker to need to fetch new data (async action/XHR) based on the newly selected range.
There can be many components on the screen and the user may wish to add/remove available displays, so it is not as simple as always refreshing the data for all components because they may or may not be present.
One way I thought to handle this was in the action dispatched when a new date range is selected was to figure out what components are on screen (derived from the Store) and dispatch async actions to fetch the data for those components. This seems like a lot of work will go into the DATE_CHANGED action.
Another alternative might be to detect date range changes in store.subscribe() callbacks from each of the components. This seems to decouple the logic to fetch the data from the action that caused this to happen. However, I thought it was bad practice (or even an error) to dispatch while dispatching. Sure I can wrap it in a setTimeout, but that feels wrong too.
Third thing that came to mind was just doing fetch calls directly in the component's store.subscribe() and dispatching when those return, but I thought this breaks the connect model.
This seems like a common pattern to fetch based on state changes, but I don't know where its best to put those. Any good documentation / examples on the above problem?
Don't use store.subscribe for this. When DATE_CHANGED reaches the reducer it's meant for, simply change the application state (I'm assuming the date range is part of the store somehow). So you have something like state.rangeStart and state.rangeEnd.
You didn't mention what view rendering library you're using, so I can only describe how this is typically done with React:
The components know wether they are currently mounted (visible) or not, so redux doesn't need to be concerned with that. What you need is a way to detect that state.rangeStart or state.rangeEnd changed.
In React there is a lifecycle hook for that (componentWillReceiveProps or getDerivedStateFromProps in the newest release). In this handler you dispatch async redux actions that fetch the data the component needs. Your view library will probably have something similar.
The components display some kind of "empty" or "loading" state while you're waiting for the new data typically. So a good practice is to invalidate/clear data from the store in the reducer that handles the DATE_CHANGED action. For example, if state.listOfThings (an array) entirely depends on the date range, you would set it to an empty array as soon as the date changes: return { ...state, listOfThings: [] }. This causes the components to display that data is being fetched again.
When all the async redux actions went through the REQUEST -> SUCCESS/FAILURE cycle and have populated the store with the data, connected components will automatically render it. This is kind of its own chapter, look into redux async actions if you need more information.
The tricky part are interdependencies between the components and the application they're rendering. If two different dashboard components for example want to fetch and render state.listOfThings for the current date range, you don't want to fetch this data twice. So there needs to be a way to detected that 1) the data range has changed but also 2) a request to fetch listOfThings is already on its way. This is usually done with boolean flags in the state: state.isFetchingListOfThings. The async actions fetching this data cause the reducer to set this flag to true. Your components need to be aware of this and dispatch actions conditionally: if (props.rangeStart !== nextProps.rangeStart && !nextProps.isFetchingListOfThings) { props.fetchListOfThings(); }.

Asynchronously maintaining state integrity in Redux

Suppose I have a Redux store. Its state has the userCoordinates field
with the user's current coordinates:
{
userCoordinates: [3.1457, 2.1728],
...
}
Then suppose the store has 20 more fields with data that depends on the
coordinates:
{
...
nearbyFriends: ["Bob", "Jimmy"],
nearbyShops: ["Point & Click tools", "Bobby Ray's"],
address: "42 Enth Street, Townsville, Countryland",
weather: "Cloudy",
...
}
Values in all of these fields are loaded over HTTP from
various services, one separate request for each field.
Now suppose the user's geolocation is updated, and an action is dispatched that
changes the value of userCoordinates:
dispatch(updateCoords([1.6180, 1.4142]));
Now userCoordinates has new coordinates and all 20 other fields have invalid data.
If the goal is just to keep all the fields "eventually" valid, where do I make the requests to fetch the new data?
How the method changes if I use React-Redux and there are lots of components using many different combinations of these fields, with some fields used by more than one component and some fields not used at all?
Depending on how this is architected, I would do one of two things.
1: Compare states in your reducer. If there is a change in the user coordinates in the state, you could add something to the store like updateNeeded: true, then have a check wherever you are loading your other data so that if updateNeeded is true, you fire an ajax call to go get new data from the server.
2: If it is set up the right way, you could used componentWillReceiveProps to compare the props. If there is a change in userCoordinates, dispatch an action to go get the other data fields.
Of course, this would just be easier if you could just get all the data with one call...

ngrx, How to have a starting state from an api?

I have my reducer with a starting state of an empty array:
folderReducer(state:Array<Folder> = [], action: Action)
I'd like to populate the starting state, so when I do
store.subscribe(s => ..)
The first item I get comes from the database. I assume the way of doing this is with ngrx/effects, but I'm not sure how.
Your store always has the initial state, that you define in the reducer-function. The initial states main purpose is to ensure that the application is able to start up and not run into any null-pointer-exceptions. And also it sets up your application to start making the first api-calls ect. - so you can think of it as a technical initial state.
If you want to fill your store with api-data on the startup, you would do that on the same way that you add/modify data during any other action - just that the action of "initially loading data" is not triggered by some user-interaction but through:
either when your root-component loads
or as part of a service in the constructor
In case you want to prevent specific components from showing anything until your API-call is done, you would have to adjust the display-components to display or hide data based on your state (e.g. by implementing a flag in your satet initialDataLoaded).
A dynamic initial state is now supported, see: https://github.com/ngrx/platform/blob/master/docs/store/api.md#initial-state-and-ahead-of-time-aot-compilation
Also see: https://github.com/ngrx/platform/issues/51
I would only do this if the database is local, otherwise the request will hold up loading of the application.

Listen for state changes from redux-thunk action creator

I can't see a clear way to know when a particular action has fired or particular state has updated from the context of a redux-thunk action creator.
I want to do something like this:
Dispatch an action
Detect a possible recoverable error condition
Error condition dispatches a different action signalling recovery process initiating
Wait for recovery to complete
Proceed with current action or re-dispatch it
Concrete example:
User interaction triggers API call action
Note that API call failed, needs login
Dispatch 'LOGIN_REQUIRED' action, which pops up a <dialog> for user.
Wait for logged in state to change (or LOGIN_SUCCESS action to occur, whatever).
Make same API call again
If you want to check for a specific action to be dispatched, you'll need middleware.
If you want to, in effect, "subscribe a given bit of state", Redux doesn't provide a built-in way to do that. There are, however, a number of utilities that implement that kind of logic for you. See the Redux FAQ at http://redux.js.org/docs/FAQ.html#store-setup-subscriptions , and also the list of store subscription addons in my Redux addons catalog. (The list of Redux middlewares may also have something useful for the "listen for an action" scenario.)
for visualizing what happens in store you can use:
import {composeWithDevTools} from 'redux-devtools-extension';
and create your store as: (for instance with thunk middleware)
const store = `createStore(rootReducer,composeWithDevTools(applyMiddleware(thunk)));`
then you can use the extention in browser.
you can have access to your state by {connect} from 'react-redux' as props.
your actions then will change the state via reducers, this will cause your component receive new props so you can have your logic in
componentWillReceiveProps(nextProps) {/*your business logic*/}

Resources