Confusion about initial state, reducers and the Store.

I'm still new to Redux, so I might be missing something here.
When a reducer doesn't recognize an action, it's supposed/idiomatic to return the state given to it, right?
But when Redux is initializing the reducers, it calls them with undefined, and in that situation it's an error to return the given state.
So if the Store is given initial data, wouldn't it make sense for Redux to 'initialize' the reducers with that instead? That way we wouldn't have to worry about setting up some kind of initial state for each reducer directly.
It seems to me that Redux is trying to protect its users from themselves, and I can't help but think that's a bad idea. It's a bit like having a bicycle with training wheels you can't remove :)

Please read http://stackoverflow.com/a/33791942/458193, it should answer this question. In short:

Reducers specify their own initial state shape because they should be in control of it. State shape often changes, and you shouldn't have to remember to modify it somewhere else. Additionally some reducer composition patterns actually mean you don't have the initial state until some nested data is initialized (for example, a new entry by dynamic key). In this case you can't supply it beforehand anyway.

You can pass the whole initial state tree as a second argument when creating the store. This is useful for hydrating persisted data or data received from the server. However we never recommend building that state tree in your code. The reason is the same: to keep reducers self-sufficient and reusable.

This means when your reducers specify initial state and you also specify the initial state tree when creating the store, the state tree wins, just by the virtue of following the rules you outlined above. This lets you prefill the saved state for some reducers, and let others calculate their own initial state. This is a powerful pattern for universal apps that sometimes have initial state from the server and sometimes don't.

All of this should be covered by http://stackoverflow.com/a/33791942/458193. This isn't about protecting users, it's about keeping pieces encapsulated but having a way to hydrate the global state when needed. We find that the current solution strikes a good balance.

Hey, thanks for the response!
Again, I may be missing something here, but I still don't see why people shouldn't be free to decide if they want to use default arguments or not.

Reducers specify their own initial state shape because they should be in control of it.

This feels kind of like conflating functions with objects. Objects are meant to encapsulate state (of a certain 'shape'), but functions generally just take some arguments and return something based on them, right?
We like reducing and immutable values and stuff, so why not be "functional" about functions themselves too?
function deeplyNestedReducer(state = this.gets.kind.of.silly, action) {
  // Do something with state that's only the 'silly' part anyway.
  // Now this function gets the exact same data in two ways: 1st as the default arg,
  // and later on, as a piece of the 'state tree' given to the Store as initialState.
  // This feels highly silly.
}

If reducers didn't have to initialize their own state, then I could write:
function deeplyNestedReducer(state, action) {
  // No silliness in the function arguments, but we still have the exact same data.
  // This time it's actually passed in by another function.
  // It's like we're doing functional programming!
}

What's the 'right' initial state for this reducer?
function customer(state, action) {
  // Maybe do something to a customer
}

Obviously, we don't know what customer it will be called with. So I guess we'll initialize it with an empty object, but what exactly is the benefit in having to do that? Calling this function with no customer is going to be an error either way, so why not let everyone leave out the default argument if they feel like it?
Some people want to put default arguments everywhere, and that's perfectly fine with me. Maybe they even have a good reason. Maybe they see something I don't.
But I don't see why I shouldn't be allowed to not sprinkle default arguments everywhere, especially if it feels highly silly to me.

Hey, thanks for the response!
Again, I may be missing something here, but I still don't see why people shouldn't be free to decide if they want to use default arguments or not.

Reducers specify their own initial state shape because they should be in control of it.

This feels kind of like conflating functions with objects. Objects are meant to encapsulate state (of a certain 'shape'), but functions generally just take some arguments and return something based on them, right?
We like reducing and immutable values and stuff, so why not be "functional" about functions themselves too?
function deeplyNestedReducer(state = this.gets.kind.of.silly, action) {
  // Do something with state that's only the 'silly' part anyway.
  // Now this function gets the exact same data in two ways: 1st as the default arg,
  // and later on, as a piece of the 'state tree' given to the Store as initialState.
  // This feels highly silly.
}

If reducers didn't have to initialize their own state, then I could write:
function deeplyNestedReducer(state, action) {
  // No silliness in the function arguments, but we still have the exact same data.
  // This time it's actually passed in by another function.
  // It's like we're doing functional programming!
}

What's the 'right' initial state for this reducer?
function customer(state, action) {
  // Maybe do something to a customer
}

Obviously, we don't know what customer it will be called with. So I guess we'll initialize it with an empty object, but what exactly is the benefit in having to do that? Calling this function with no customer is going to be an error either way, so why not let everyone leave out the default argument if they feel like it?
Some people want to put default arguments everywhere, and that's perfectly fine with me. Maybe they even have a good reason. Maybe they see something I don't.
But I don't see why I shouldn't be allowed to not sprinkle default arguments everywhere, especially if it feels highly silly to me.

I think you're being confused and you need to look closely at our examples.
There are two points of confusion I can see:
1. Reducers don't actually receive the root state. They receive the part they care about.
What you're describing is an anti-pattern:
function deeplyNestedReducer(state = this.gets.kind.of.silly, action) {
  // Do something with state that's only the 'silly' part anyway.

Reducers don't usually receive the root state object. They receive only parts of the state relevant to them, and you compose them to get the root reducer.
// state argument is *not* root state object
function counter(state = 0, action) {
  // ...
}

// state argument is *not* root state object
function todos(state = [], action) {
  // ...
}

// finally, root reducer delegates handling parts of its state
function app(state = {}, action) {
  return {
    counter: counter(state.counter, action), // only part of the state is passed
    todos: todos(state.todos, action), // only part of the state is passed
  };
}

// create with no initial state—useful for initialization
let store = createStore(app);
console.log(store.getState()); // { counter: 0, todos: [] }

// ... or create with some initial state—useful for hydration
store = createStore(app, { counter: 10 });
console.log(store.getState()); // { counter: 10, todos: [] }

2. You don't need to specify something twice.
You're saying:
  // Now this function gets the exact same data in two ways: 1st as the default arg,
  // and later on, as a piece of the 'state tree' given to the Store as initialState.
  // This feels highly silly.

Please show in my specific example where it gets the same data in two ways. I don't see any duplication. The whole point is that reducers are autonomous, their parent reducer doesn't know their data type and delegates handling of the subtrees to child reducers, and there is a way to hydrate the state.

I'm happy to continue this discussion but let's use a specific example as a basis instead of pseudocode because it's very hard to understand where exactly the confusion lies.

I think you're being confused and you need to look closely at our examples.
There are two points of confusion I can see:
1. Reducers don't actually receive the root state. They receive the part they care about.
What you're describing is an anti-pattern:
function deeplyNestedReducer(state = this.gets.kind.of.silly, action) {
  // Do something with state that's only the 'silly' part anyway.

Reducers don't usually receive the root state object. They receive only parts of the state relevant to them, and you compose them to get the root reducer.
// state argument is *not* root state object
function counter(state = 0, action) {
  // ...
}

// state argument is *not* root state object
function todos(state = [], action) {
  // ...
}

// finally, root reducer delegates handling parts of its state
function app(state = {}, action) {
  return {
    counter: counter(state.counter, action), // only part of the state is passed
    todos: todos(state.todos, action), // only part of the state is passed
  };
}

// create with no initial state—useful for initialization
let store = createStore(app);
console.log(store.getState()); // { counter: 0, todos: [] }

// ... or create with some initial state—useful for hydration
store = createStore(app, { counter: 10 });
console.log(store.getState()); // { counter: 10, todos: [] }

2. You don't need to specify something twice.
You're saying:
  // Now this function gets the exact same data in two ways: 1st as the default arg,
  // and later on, as a piece of the 'state tree' given to the Store as initialState.
  // This feels highly silly.

Please show in my specific example where it gets the same data in two ways. I don't see any duplication. The whole point is that reducers are autonomous, their parent reducer doesn't know their data type and delegates handling of the subtrees to child reducers, and there is a way to hydrate the state.

I'm happy to continue this discussion but let's use a specific example as a basis instead of pseudocode because it's very hard to understand where exactly the confusion lies.

So if the Store is given initial data, wouldn't it make sense for Redux to 'initialize' the reducers with that instead?

This is exactly what happens. They'll receive that state as state argument. In this case the optional parameter won't matter at all. Optional arguments are only used when the value is undefined. This is why I'm asking for runnable code example: it seems that we are talking past each other because of some misconception about how these pieces fit together.

So if the Store is given initial data, wouldn't it make sense for Redux to 'initialize' the reducers with that instead?

This is exactly what happens. They'll receive that state as state argument. In this case the optional parameter won't matter at all. Optional arguments are only used when the value is undefined. This is why I'm asking for runnable code example: it seems that we are talking past each other because of some misconception about how these pieces fit together.

There's a reason why I put the word 'confusion' in the topic! :)
( I'm just getting started with Redux and other stuff, so I don't have any real code to show you )

Reducers don't actually receive the root state. They receive the part they care about

We're actually in agreement here. In a comment string, I said the reducer would only receive "the 'silly' part". What I meant with that was basically what you're describing.
Some other, combined reducer would hand it the part of the state tree it's supposed to handle. The default argument "this.gets.kind.of.silly" described a hierarchy of named objects, and the last part was the 'silly' part :)
What I meant with a reducer getting the same data "in two ways" was once as the default argument, and once again from its parent reducer when the actual data (given as initialState to the Store) is being handled.
But what am I missing? If I have a 'state tree' with multiple nested levels of data, and specific nested reducers are supposed to handle specific nested parts of it, what is the right way to give them their initial state/data?
 The structure of the reducers corresponds to the structure of the data. As far as I can tell, my problem is that I can't just go straight to having the reducers handle the state tree for real, without the 'intermediate step' of the library handing undefined to them.
Imagine a server-side application with lots of functions calling other functions, and let's say most of them can't actually do anything without getting the kind of 'real arguments' they're supposed to work on.
Wouldn't it be kind of silly to intentionally pass null to them? Of course some functions need to be prepared not to explode when given null as an argument, but in some cases, you can guarantee it will never happen and then you don't need to worry about it.
Besides, even the funcs that prepare for getting nothing won't just spring some data into existence and work on that instead.
Maybe a part of my/the (:p) problem here is that 'state' kind of gets conflated with 'data'? Something like.. It may well make sense for 'empty state' to 'spring up' from the reducers, but the same doesn't apply to persistent or 'actual' data.
function customer(state, action) {
  // A customer would obviously be 'actual data'.. there's no sensible default for it.
}

What does it mean for that reducer to initialize itself with an empty object? It's supposed to get a customer, and it can't do anything without one. Not only that, but the empty object it initializes for itself has no use outside of this reducer either.

There's a reason why I put the word 'confusion' in the topic! :)
( I'm just getting started with Redux and other stuff, so I don't have any real code to show you )

Reducers don't actually receive the root state. They receive the part they care about

We're actually in agreement here. In a comment string, I said the reducer would only receive "the 'silly' part". What I meant with that was basically what you're describing.
Some other, combined reducer would hand it the part of the state tree it's supposed to handle. The default argument "this.gets.kind.of.silly" described a hierarchy of named objects, and the last part was the 'silly' part :)
What I meant with a reducer getting the same data "in two ways" was once as the default argument, and once again from its parent reducer when the actual data (given as initialState to the Store) is being handled.
But what am I missing? If I have a 'state tree' with multiple nested levels of data, and specific nested reducers are supposed to handle specific nested parts of it, what is the right way to give them their initial state/data?
 The structure of the reducers corresponds to the structure of the data. As far as I can tell, my problem is that I can't just go straight to having the reducers handle the state tree for real, without the 'intermediate step' of the library handing undefined to them.
Imagine a server-side application with lots of functions calling other functions, and let's say most of them can't actually do anything without getting the kind of 'real arguments' they're supposed to work on.
Wouldn't it be kind of silly to intentionally pass null to them? Of course some functions need to be prepared not to explode when given null as an argument, but in some cases, you can guarantee it will never happen and then you don't need to worry about it.
Besides, even the funcs that prepare for getting nothing won't just spring some data into existence and work on that instead.
Maybe a part of my/the (:p) problem here is that 'state' kind of gets conflated with 'data'? Something like.. It may well make sense for 'empty state' to 'spring up' from the reducers, but the same doesn't apply to persistent or 'actual' data.
function customer(state, action) {
  // A customer would obviously be 'actual data'.. there's no sensible default for it.
}

What does it mean for that reducer to initialize itself with an empty object? It's supposed to get a customer, and it can't do anything without one. Not only that, but the empty object it initializes for itself has no use outside of this reducer either.

( I'm just getting started with Redux and other stuff, so I don't have any real code to show you )

Create a JSBin fiddle demonstrating your confusion and share it. I imagine it wouldn't be more than 30 lines, would it?

Some other, combined reducer would hand it the part of the state tree it's supposed to handle. The default argument "this.gets.kind.of.silly" described a hierarchy of named objects, and the last part was the 'silly' part :)

What I don't understand is why you used default argument syntax for that. Yes, it will receive the part relevant to it, but you would never need to write something like state = topLevelState.bla.foo.bar to retrieve it. You'd just receive it as the state argument from the parent reducer.

But what am I missing? If I have a 'state tree' with multiple nested levels of data, and specific nested reducers are supposed to handle specific nested parts of it, what is the right way to give them their initial state/data?

Normally you let each reducer specify its initial data. However you already have that data ready for hydration (from localStorage, from the server state in a server-rendered application), you pass it to createStore, and it will be used instead. This is akin to "resuming" an application from a given "start" state, rather than letting it "boot".

 The structure of the reducers corresponds to the structure of the data. As far as I can tell, my problem is that I can't just go straight to having the reducers handle the state tree for real, without the 'intermediate step' of the library handing undefined to them.

Wouldn't it be kind of silly to intentionally pass null to them? Of course some functions need to be prepared not to explode when given null as an argument, but in some cases, you can guarantee it will never happen and then you don't need to worry about it.

Besides, even the funcs that prepare for getting nothing won't just spring some data into existence and work on that instead.

Sorry, I can't continue the discussion in this manner. It is very theoretical. What you're talking about is obvious to you, but unless you show some (even contrived) example code, I can't help you because I don't understand you. On my side, I have shown the example, and we have plenty in the docs and the repo as well, so it's your turn.

Maybe a part of my/the (:p) problem here is that 'state' kind of gets conflated with 'data'? Something like.. It may well make sense for 'empty state' to 'spring up' from the reducers, but the same doesn't apply to persistent or 'actual' data.

Yes, perhaps!

function customer(state, action) {
// A customer would obviously be 'actual data'.. there's no sensible default for it.
}

Yes there is a sensible default, **if you have a customer creation form.** For example:

```js
function customer(state = { isPublished: false, name: 'Jane Doe' }, action) {
}

When you don't have such a form just don't specify it. Nobody forces you to specify the initial state for the reducers that are called on-demand by other reducers.
function customer(state, action) {
}

We only force you to specify the reducer's initial state as default argument when you put a reducer inside combineReducers() because we don't want to throw if the store was created with undefined initial state. The client needs to be able to "boot up" without any data—at least it is the requirement we're enforcing because that's what apps need most of the time. I think you'll want your app to be able to fetch data for itself even if it was booted without pre-loaded data.

( I'm just getting started with Redux and other stuff, so I don't have any real code to show you )

Create a JSBin fiddle demonstrating your confusion and share it. I imagine it wouldn't be more than 30 lines, would it?

Some other, combined reducer would hand it the part of the state tree it's supposed to handle. The default argument "this.gets.kind.of.silly" described a hierarchy of named objects, and the last part was the 'silly' part :)

What I don't understand is why you used default argument syntax for that. Yes, it will receive the part relevant to it, but you would never need to write something like state = topLevelState.bla.foo.bar to retrieve it. You'd just receive it as the state argument from the parent reducer.

But what am I missing? If I have a 'state tree' with multiple nested levels of data, and specific nested reducers are supposed to handle specific nested parts of it, what is the right way to give them their initial state/data?

Normally you let each reducer specify its initial data. However you already have that data ready for hydration (from localStorage, from the server state in a server-rendered application), you pass it to createStore, and it will be used instead. This is akin to "resuming" an application from a given "start" state, rather than letting it "boot".

 The structure of the reducers corresponds to the structure of the data. As far as I can tell, my problem is that I can't just go straight to having the reducers handle the state tree for real, without the 'intermediate step' of the library handing undefined to them.

Wouldn't it be kind of silly to intentionally pass null to them? Of course some functions need to be prepared not to explode when given null as an argument, but in some cases, you can guarantee it will never happen and then you don't need to worry about it.

Besides, even the funcs that prepare for getting nothing won't just spring some data into existence and work on that instead.

Sorry, I can't continue the discussion in this manner. It is very theoretical. What you're talking about is obvious to you, but unless you show some (even contrived) example code, I can't help you because I don't understand you. On my side, I have shown the example, and we have plenty in the docs and the repo as well, so it's your turn.

Maybe a part of my/the (:p) problem here is that 'state' kind of gets conflated with 'data'? Something like.. It may well make sense for 'empty state' to 'spring up' from the reducers, but the same doesn't apply to persistent or 'actual' data.

Yes, perhaps!

function customer(state, action) {
// A customer would obviously be 'actual data'.. there's no sensible default for it.
}

Yes there is a sensible default, **if you have a customer creation form.** For example:

```js
function customer(state = { isPublished: false, name: 'Jane Doe' }, action) {
}

When you don't have such a form just don't specify it. Nobody forces you to specify the initial state for the reducers that are called on-demand by other reducers.
function customer(state, action) {
}

We only force you to specify the reducer's initial state as default argument when you put a reducer inside combineReducers() because we don't want to throw if the store was created with undefined initial state. The client needs to be able to "boot up" without any data—at least it is the requirement we're enforcing because that's what apps need most of the time. I think you'll want your app to be able to fetch data for itself even if it was booted without pre-loaded data.

See also how we can create reducer factories that specify the initial state. It wouldn't be encapsulated if I forced the consumer to always remember to specify the exact state shape as an argument to createStore because the state shape of that reducer is its implementation detail.
So, to clarify again, this is an anti-pattern:
const store = createStore(rootReducer, {
  customersById: {},
  customersPagination: {
    isFetching: false,
    ids: []
  }
});

Specifying an object literal as the initial state when creating a store is an anti-pattern.
When you do it this way, any time you change a reducer you also must remember to change the initial state shape. Reducers are no longer encapsulated.
So why does the second argument even exist? For hydration of pre-generated state tree. This is fine:
// warning: pseudo code, no error handling and perf
const savedState = JSON.parse(localStorage.getItem('saved-store-state'));
const store = createStore(reducer, savedState);

store.subscribe(() => {
  localStorage.setItem('saved-store-state', JSON.stringify(store.getState()));
});

This is also fine:
// warning: pseudo code, might have security problems, won't actually work as is

// server
const store = createStore(rootReducer);
store.dispatch(fetchData()).then(() =>
  response.send(`
<html>
  <body>
    ${React.renderToString(<Provider store={store}><App /></Provider>))}
    <script>window.SERVER_STATE = ${JSON.stringify(store.getState())}</script>
    <script src='/static/app.js'></script>
  </body>
</html>
  `)
);

// client
const store = createStore(rootReducer, window.SERVER_STATE);

That's what the second argument is for. Hydrating the existing state. However we never need to repeat the same initial state twice as object literal—reducers always take care of initializing the state they manage. We only use the second argument to hydrate the state that was previously generated by reducers—whether the last time the app ran, or when it was rendered on the server.

See also how we can create reducer factories that specify the initial state. It wouldn't be encapsulated if I forced the consumer to always remember to specify the exact state shape as an argument to createStore because the state shape of that reducer is its implementation detail.
So, to clarify again, this is an anti-pattern:
const store = createStore(rootReducer, {
  customersById: {},
  customersPagination: {
    isFetching: false,
    ids: []
  }
});

Specifying an object literal as the initial state when creating a store is an anti-pattern.
When you do it this way, any time you change a reducer you also must remember to change the initial state shape. Reducers are no longer encapsulated.
So why does the second argument even exist? For hydration of pre-generated state tree. This is fine:
// warning: pseudo code, no error handling and perf
const savedState = JSON.parse(localStorage.getItem('saved-store-state'));
const store = createStore(reducer, savedState);

store.subscribe(() => {
  localStorage.setItem('saved-store-state', JSON.stringify(store.getState()));
});

This is also fine:
// warning: pseudo code, might have security problems, won't actually work as is

// server
const store = createStore(rootReducer);
store.dispatch(fetchData()).then(() =>
  response.send(`
<html>
  <body>
    ${React.renderToString(<Provider store={store}><App /></Provider>))}
    <script>window.SERVER_STATE = ${JSON.stringify(store.getState())}</script>
    <script src='/static/app.js'></script>
  </body>
</html>
  `)
);

// client
const store = createStore(rootReducer, window.SERVER_STATE);

That's what the second argument is for. Hydrating the existing state. However we never need to repeat the same initial state twice as object literal—reducers always take care of initializing the state they manage. We only use the second argument to hydrate the state that was previously generated by reducers—whether the last time the app ran, or when it was rendered on the server.

Hmm, alright, thanks for going through so much effort in explaining stuff.
I must be doing something wrong because I got very confused when writing the following example code:
const data = {
    stuff: {
        innerStuff: {
            something: ["value"]
        }
    }
};

const stuff = (state, action) => {
    console.log("Stuff: " + JSON.stringify(state));
    return {
        innerStuff: innerStuff(state.innerStuff, action)
    };
};

const innerStuff = (state, action) => {
    console.log("Inner Stuff: " + JSON.stringify(state));
    return {
        something: something(state.something, action)
    }
};

const something = (state, action) => {
    console.log("Something: " + JSON.stringify(state));
    return state;
};

const rootReducer = combineReducers({
    stuff: combineReducers({
        innerStuff: combineReducers({
            something
        })
    })
});

const testStore = Redux.createStore(rootReducer);
testStore.dispatch({type: "TEST"});

Anyway, now that the something -reducer has no initial state, I get this error:
Reducer "something" returned undefined during initialization. If the state passed to the reducer is undefined, you must explicitly return the initial state. The initial state may not be undefined.

It says if the reducer gets undefined, then it "must explicitly return 'the' initial state".. but I didn't want to return any! :)  I guess my problem boils down to getting that error.
But if I change it to:
const something = (state = data.stuff.innerStuff.something, action) => {
    console.log("Something: " + JSON.stringify(state));
    return state;
};

.. The error goes away, as you might expect. That's certainly very ugly, and obviously not something I should be doing, so here I am, wondering if there's another way.
Anyway, I think I just realized that this:
const rootReducer = combineReducers({
    stuff: combineReducers({
        innerStuff: combineReducers({
            something
        })
    })
});

.. results in the other reducers not actually getting called. The innermost reducer was called strangely many times, though. So yeah.. :D Confusion.
Here's another try:
const anotherRootReducer = (state = {}, action) => {
    return {
        stuff: stuff(state.stuff, action)
    }
};

With that, and default arguments for the other reducers, things behave more like I'd expect!
But looking back at your posts, I found this:

We only force you to specify the reducer's initial state as default argument when you put a reducer inside combineReducers() because we don't want to throw if the store was created with undefined initial state.

But that's what I'd call protecting me from myself! I'm perfectly fine with getting an exception if I've made a mistake! It's my fault, and I should be more careful! :)
That's a lot like falling on a bicycle. Falling down sucks, but that doesn't mean someone should force you to use training wheels to prevent you from falling :) You just learn to be more careful.
To be fair, I'm starting to feel like initial state in reducers might be alright after all. Your example of 'reducer factories' looked reasonable and all.

It wouldn't be encapsulated if I forced the consumer to always remember to specify the exact state shape as an argument to createStore [..]

If a programmer chooses not to specify initial state for each of his reducers, and as a result has to give the exact right shape of data to createStore, who's forcing anyone to do anything?
But if I can't not specify initial state, that sounds more like a match.

[..] because the state shape of that reducer is its implementation detail

I don't get this.. how would you define 'an implementation detail' in this case? -Something that things outside of the reducer don't have to worry about? .. But it's not like a reducer can just produce whatever shape of data it wants to, right? Won't the state be used by something in a specific way, with specific expectations on its shape?

Hmm, alright, thanks for going through so much effort in explaining stuff.
I must be doing something wrong because I got very confused when writing the following example code:
const data = {
    stuff: {
        innerStuff: {
            something: ["value"]
        }
    }
};

const stuff = (state, action) => {
    console.log("Stuff: " + JSON.stringify(state));
    return {
        innerStuff: innerStuff(state.innerStuff, action)
    };
};

const innerStuff = (state, action) => {
    console.log("Inner Stuff: " + JSON.stringify(state));
    return {
        something: something(state.something, action)
    }
};

const something = (state, action) => {
    console.log("Something: " + JSON.stringify(state));
    return state;
};

const rootReducer = combineReducers({
    stuff: combineReducers({
        innerStuff: combineReducers({
            something
        })
    })
});

const testStore = Redux.createStore(rootReducer);
testStore.dispatch({type: "TEST"});

Anyway, now that the something -reducer has no initial state, I get this error:
Reducer "something" returned undefined during initialization. If the state passed to the reducer is undefined, you must explicitly return the initial state. The initial state may not be undefined.

It says if the reducer gets undefined, then it "must explicitly return 'the' initial state".. but I didn't want to return any! :)  I guess my problem boils down to getting that error.
But if I change it to:
const something = (state = data.stuff.innerStuff.something, action) => {
    console.log("Something: " + JSON.stringify(state));
    return state;
};

.. The error goes away, as you might expect. That's certainly very ugly, and obviously not something I should be doing, so here I am, wondering if there's another way.
Anyway, I think I just realized that this:
const rootReducer = combineReducers({
    stuff: combineReducers({
        innerStuff: combineReducers({
            something
        })
    })
});

.. results in the other reducers not actually getting called. The innermost reducer was called strangely many times, though. So yeah.. :D Confusion.
Here's another try:
const anotherRootReducer = (state = {}, action) => {
    return {
        stuff: stuff(state.stuff, action)
    }
};

With that, and default arguments for the other reducers, things behave more like I'd expect!
But looking back at your posts, I found this:

We only force you to specify the reducer's initial state as default argument when you put a reducer inside combineReducers() because we don't want to throw if the store was created with undefined initial state.

But that's what I'd call protecting me from myself! I'm perfectly fine with getting an exception if I've made a mistake! It's my fault, and I should be more careful! :)
That's a lot like falling on a bicycle. Falling down sucks, but that doesn't mean someone should force you to use training wheels to prevent you from falling :) You just learn to be more careful.
To be fair, I'm starting to feel like initial state in reducers might be alright after all. Your example of 'reducer factories' looked reasonable and all.

It wouldn't be encapsulated if I forced the consumer to always remember to specify the exact state shape as an argument to createStore [..]

If a programmer chooses not to specify initial state for each of his reducers, and as a result has to give the exact right shape of data to createStore, who's forcing anyone to do anything?
But if I can't not specify initial state, that sounds more like a match.

[..] because the state shape of that reducer is its implementation detail

I don't get this.. how would you define 'an implementation detail' in this case? -Something that things outside of the reducer don't have to worry about? .. But it's not like a reducer can just produce whatever shape of data it wants to, right? Won't the state be used by something in a specific way, with specific expectations on its shape?

I'm happy to continue this discussion when you show the real code you're struggling with. stuff, innerStuff, TEST obscure the nature of your problem too much, and I can't understand the real context of your issue and what you're trying to achieve. You may not think that it matters, but it really does.

I'm happy to continue this discussion when you show the real code you're struggling with. stuff, innerStuff, TEST obscure the nature of your problem too much, and I can't understand the real context of your issue and what you're trying to achieve. You may not think that it matters, but it really does.

In particular this example is very confusing:
const data = {
    stuff: {
        innerStuff: {
            something: ["value"]
        }
    }
};

const stuff = (state, action) => {
    console.log("Stuff: " + JSON.stringify(state));
    return {
        innerStuff: innerStuff(state.innerStuff, action)
    };
};

const innerStuff = (state, action) => {
    console.log("Inner Stuff: " + JSON.stringify(state));
    return {
        something: something(state.something, action)
    }
};

const something = (state, action) => {
    console.log("Something: " + JSON.stringify(state));
    return state;
};

const rootReducer = combineReducers({
    stuff: combineReducers({
        innerStuff: combineReducers({
            something
        })
    })
});

const testStore = Redux.createStore(rootReducer);
testStore.dispatch({type: "TEST"});

What is data? Why do you have it beforehand? Is it some pre-loaded data available at the application start? Where is it coming from? Does it always exist?
The example code itself seems wrong too, even though it's very hard to tell what you want to do because of stuff, innerStuff, etc. You are creating stuff and innerStuff reducer functions but you are not actually using them (check your code, they are unused variables). The only function you're actually using in your code is something so you might as well cut your code:
const data = {
    stuff: {
        innerStuff: {
            something: ["value"]
        }
    }
};

const something = (state, action) => {
    console.log("Something: " + JSON.stringify(state));
    return state;
};

const rootReducer = combineReducers({
    stuff: combineReducers({
        innerStuff: combineReducers({
            something
        })
    })
});

const testStore = Redux.createStore(rootReducer);
testStore.dispatch({type: "TEST"});

This is why other reducers are not called—you are not using them!
But again, because of the stuff, innerStuff I can't help you because I don't understand what you were really trying to do.
So far, I see that you might have confusion about how combineReducers() works. It actually generates a reducer. So it's completely redundant to write innerStuff reducer if you already generated it with combineReducers({ something }). The returned function is equivalent to what you wrote in innerStuff, and you're not passing hand-written innerStuff anywhere so it gets ignored.
From your comment I assumed you watch Egghead videos, but I suggest you to give them another try. In particular these three lessons explain what combineReducers() is, and how exactly it works:

https://egghead.io/lessons/javascript-redux-reducer-composition-with-objects?series=getting-started-with-redux
https://egghead.io/lessons/javascript-redux-reducer-composition-with-combinereducers?series=getting-started-with-redux
https://egghead.io/lessons/javascript-redux-implementing-combinereducers-from-scratch?series=getting-started-with-redux

Unfortunately I'm not ready to continue this discussion without an example showing what you are trying to do with more descriptive names and data structures than stuff.

In particular this example is very confusing:
const data = {
    stuff: {
        innerStuff: {
            something: ["value"]
        }
    }
};

const stuff = (state, action) => {
    console.log("Stuff: " + JSON.stringify(state));
    return {
        innerStuff: innerStuff(state.innerStuff, action)
    };
};

const innerStuff = (state, action) => {
    console.log("Inner Stuff: " + JSON.stringify(state));
    return {
        something: something(state.something, action)
    }
};

const something = (state, action) => {
    console.log("Something: " + JSON.stringify(state));
    return state;
};

const rootReducer = combineReducers({
    stuff: combineReducers({
        innerStuff: combineReducers({
            something
        })
    })
});

const testStore = Redux.createStore(rootReducer);
testStore.dispatch({type: "TEST"});

What is data? Why do you have it beforehand? Is it some pre-loaded data available at the application start? Where is it coming from? Does it always exist?
The example code itself seems wrong too, even though it's very hard to tell what you want to do because of stuff, innerStuff, etc. You are creating stuff and innerStuff reducer functions but you are not actually using them (check your code, they are unused variables). The only function you're actually using in your code is something so you might as well cut your code:
const data = {
    stuff: {
        innerStuff: {
            something: ["value"]
        }
    }
};

const something = (state, action) => {
    console.log("Something: " + JSON.stringify(state));
    return state;
};

const rootReducer = combineReducers({
    stuff: combineReducers({
        innerStuff: combineReducers({
            something
        })
    })
});

const testStore = Redux.createStore(rootReducer);
testStore.dispatch({type: "TEST"});

This is why other reducers are not called—you are not using them!
But again, because of the stuff, innerStuff I can't help you because I don't understand what you were really trying to do.
So far, I see that you might have confusion about how combineReducers() works. It actually generates a reducer. So it's completely redundant to write innerStuff reducer if you already generated it with combineReducers({ something }). The returned function is equivalent to what you wrote in innerStuff, and you're not passing hand-written innerStuff anywhere so it gets ignored.
From your comment I assumed you watch Egghead videos, but I suggest you to give them another try. In particular these three lessons explain what combineReducers() is, and how exactly it works:

https://egghead.io/lessons/javascript-redux-reducer-composition-with-objects?series=getting-started-with-redux
https://egghead.io/lessons/javascript-redux-reducer-composition-with-combinereducers?series=getting-started-with-redux
https://egghead.io/lessons/javascript-redux-implementing-combinereducers-from-scratch?series=getting-started-with-redux

Unfortunately I'm not ready to continue this discussion without an example showing what you are trying to do with more descriptive names and data structures than stuff.

I'm happy to continue this discussion when you show the real code you're struggling with. stuff, innerStuff, TEST obscure the nature of your problem too much, and I can't understand the real context of your issue and what you're trying to achieve.

Yeah, it's confusing. But as I believe I mentioned, I don't have any real application code with Redux yet. So basically what I'm struggling with is starting to use Redux, hopefully in a sane way that also happens to be comfortable for me personally.

What is data? Why do you have it beforehand? Is it some pre-loaded data available at the application start? Where is it coming from? Does it always exist?

I'd imagine it would be some persistent application data from the server (and database), which I'd use to "initialize" Redux when the page loads. Then I suppose it would be modified through Redux, and saved to the server as appropriate, etc.

The returned function is equivalent to what you wrote in innerStuff

Yeah, I was trying to make it equivalent, hoping to avoid any potential problems that I might have caused by using combineReducers wrong somehow.
Anyhow, I'm open to the idea that I'm Doin' It Wrong :P  and it's understandable that you'd need to see a real-world example of code to be able to see what's wrong etc.
But I believe you could address the latter part of my post, since that's not related to any specific code anymore:

We only force you to specify the reducer's initial state as default argument when you put a reducer inside combineReducers() because we don't want to throw if the store was created with undefined initial state.

But that's what I'd call protecting me from myself!

-What's your take on that, and the rest? Obviously, I have a problem if I don't specify default arguments, without giving the Store any initial state either..
But I've been feeling like it's also a problem if I can't not specify default arguments for reducers when I do give initial state to the Store. In this case, reducers won't be called with undefined when actually handling the actual state (or data, as the case may be). They're called with it only by Redux itself, when "asserting the sanity" of the reducers.
That's what this whole thread was originally about. I may well be using reducers in a silly way, but I don't see how that's related to having the option of not specifying default arguments for reducers when you feel like they're unnecessary (with regard to one's actual application).

I think we're finally getting to the root of this issue.
combineReducers() assumes that you want your code to run fine without any initial state passed to the store as the second argument. Otherwise your app becomes fragile. What if some particular key isn't specified in some cases (for example when the user is logged out)? It's hard to remember to always fill all possible state tree keys because the client relies on a specific prepared tree on the server. Moreover different pages will need different data so you can't prepare all of it. And undoubtedly people will open pages dynamically at which point you want to load more data.. So in addition to data you'll have to prepare empty "placeholders" for every possible state field because otherwise your app will crash! Add to this the fact that there are multiple possible initial states (logged in user, anonymous user, etc), and it's very hard to make sure you don't crash in some weird case.
Your argument presumes that on the server you would assemble a state tree by hand to pass to the client. However this is not at all what we suggest. It is still error-prone to assemble that tree by hand. Instead we suggest to create a store object on the server, fire async actions, and let reducers handle them like usual. Those reducers that handle relevant parts will fill the relevant state according to those initial actions. Then you would just pass that state to the client. No need to create a state tree by hand.
This is why we make an opinionated choice in combineReducers() that your app should be able to boot without any externally supplied predetermined state tree. It should be able to initialize and slowly accumulate the data as it becomes available, regardless of the initial state. That's the decision we made for reasons above.
You are completely free to opt out of this behavior by not using combineReducers(). The checks live there. You are free to write your own root reducer by hand and manage the state in any way you like, if you don't agree with our opinion expressed in the design of combineReducers().
Finally you asked what I mean by encapsulation of state shape in reducers. Sure, in many examples components rely on state shape but that's because not all our examples are good enough. We will fix them. In the meantime please look at shopping-cart example. There, we define "selectors" alongside reducers in the same file. This is how you keep the state shape an implementation detail. The only code relying on that state shape would be in that file, and it would be safe to change without changing anything else.

@jugimaster It is often easier to figure out a new
function/library/framework by implementing something real rather than
abstract. Dan has been amazingly patient in providing guidance to you and
pointing out the many examples that he has devoted his time to preparing.
Time to start coding a real app.
On 1 January 2016 at 19:08, Dan Abramov<EMAIL_ADDRESS>wrote:

I think we're finally getting to the root of this issue.
combineReducers() assumes that you want your code to run fine without any
initial state passed to the store as the second argument. Otherwise your
app becomes fragile. What if some particular key isn't specified in some
cases (for example when the user is logged out)? It's hard to remember to
always fill all possible state tree keys because the client relies on a
specific prepared tree on the server. Moreover different pages will need
different data so you can't prepare all of it. And undoubtedly people will
open pages dynamically at which point you want to load more data.. So in
addition to data you'll have to prepare empty "placeholders" for every
possible state field because otherwise your app will crash! Add to this the
fact that there are multiple possible initial states (logged in user,
anonymous user, etc), and it's very hard to make sure you don't crash in
some weird case.
Your argument presumes that on the server you would assemble a state tree
by hand to pass to the client. However this is not at all what we suggest.
It is still error-prone to assemble that tree by hand. Instead we suggest
to create a store object on the server, fire async actions, and let
reducers handle them like usual. Those reducers that handle relevant parts
will fill the relevant state according to those initial actions. Then you
would just pass that state to the client. No need to create a state tree by
hand.
This is why we make an opinionated choice in combineReducers() that your
app should be able to boot without any externally supplied predetermined
state tree. It should be able to initialize and slowly accumulate the data
as it becomes available, regardless of the initial state. That's the
decision we made for reasons above.
You are completely free to opt out of this behavior by not using
combineReducers(). The checks live there. You are free to write your own
root reducer by hand and manage the state in any way you like, if you don't
agree with our opinion expressed in the design of combineReducers().
Finally you asked what I mean by encapsulation of state shape in reducers.
Sure, in many examples components rely on state shape but that's because
not all our examples are good enough. We will fix them. In the meantime
please look at shopping-cart example. There, we define "selectors"
alongside reducers in the same file. This is how you keep the state shape
an implementation detail. The only code relying on that state shape would
be in that file, and it would be safe to change without changing anything
else.
—
Reply to this email directly or view it on GitHub
https://github.com/rackt/redux/issues/1189#issuecomment-168360742.

I'm trying to keep this brief, so I may come off as more argumentative than I actually am, but here goes.. :)

combineReducers() assumes that you want your code to run fine without any initial state passed to the store as the second argument. Otherwise your app becomes fragile. What if some particular key isn't specified in some cases (for example when the user is logged out)?

I don't know that allowing people to choose whether to define default arguments for their reducers would necessarily result in fragility. How do you know?
Besides, the future of front-end data handling seems to involve something like Relay/GraphQL and Falcor etc, where data is queried and received in a hierarchical way, which seems like a good fit for (potentially deeply) nested reducers too.
When using Relay/GraphQL, the shape for your data is largely defined by the queries themselves. Then you'd adjust your reducers to match it. In your model, it seems the reducers define the shape of the data with their default arguments.
Obviously both can't be the authoritative definition for the data's shape at the same time, and they need to be kept in sync anyway, so I don't see why people shouldn't be free to leave the default arguments out if they want to, while still retaining the benefit of reduced boilerplate that combineReducers gives you.
If you're using Relay, then leaving out the default arguments for your reducers could be seen as being explicit about having the shape of your client-side data defined by the queries specifically, just like you're supposed to. But now you can't do that, while using combineReducers, and that seems a bit problematic to me.

Instead we suggest to create a store object on the server, fire async actions, and let reducers handle them like usual.

Speaking of presumptions, I'm actually not using Node on the server! :) Neither are a lot of other people who will still have to do front-end development too, and who'd presumably(!) want to enjoy using Redux while at it!
I've recently been ranting about the strange state of front-end development, now that it's somehow completely dependent on Node-based tools. We're writing JavaScript to be run on the client-side, but first we use ~'server-side' tools to "build" it, just because "we" insist on using language features that aren't widely enough supported by browsers yet.

In the meantime please look at shopping-cart example. There, we define "selectors" alongside reducers in the same file. This is how you keep the state shape an implementation detail.

Alright, but it seems like now the 'unit of encapsulation' is a file, instead of a reducer function. Files certainly contain 'state' / data / 'shape' etc, but functions generally don't. Anyway, I don't think that results in the state being 'an implementation detail' of the functions.

The only code relying on that state shape would be in that file, and it would be safe to change without changing anything else.

Yeah, that seems like a good idea. But please let people make mistakes and learn from them. It might even result in discovering a new way of doing things that's even better than yours! :)

Oh, and I generally detest the idea of 'forcing' people to do something 'for their own good'.
Here's a brief example:

Carrots are good for you.
Therefore, not eating carrots is bad for you (relative to eating them).
Therefore, everyone should be eating carrots.
We can't let people not eat carrots, because it's bad for them and we want to protect them from themselves.
Therefore, the government should criminalize not eating carrots, for everyone's own good!
We are great moral people because we are forcing people to do what's good for them.

But despite this kind of mentality being widespread in a lot of different ways, no one would be happy about a doctor personally forcing them to eat carrots or exercise. In that case, the coercion would be seen as immoral.

I don't know that allowing people to choose whether to define default arguments for their reducers would necessarily result in fragility. How do you know?

It's my guess as a library author that comes from my experience building a complex client-side app, as well as from the issues and questions I've been answering here before for the past several months.

Besides, the future of front-end data handling seems to involve something like Relay/GraphQL and Falcor etc, where data is queried and received in a hierarchical way, which seems like a good fit for (potentially deeply) nested reducers too.

Obviously both can't be the authoritative definition for the data's shape at the same time, and they need to be kept in sync anyway, so I don't see why people shouldn't be free to leave the default arguments out if they want to, while still retaining the benefit of reduced boilerplate that combineReducers gives you.

When using Relay/GraphQL, the shape for your data is largely defined by the queries themselves. Then you'd adjust your reducers to match it. In your model, it seems the reducers define the shape of the data with their default arguments.

This library is not Relay. The vast majority of Redux users doesn't use Relay. People who use Relay tend to switch to it fully, or use Relay for data entities while only keeping Redux for the local state. I agree declarative data fetching is the future—but I just don't see your pain point.
I can't see the connection between having undefined as the initial state of some reducers, and using Falcor or Relay. (I've read the rest of your message and I still don't understand it. Maybe because you don't offer any specific examples :-) Somehow reducer in redux-falcor project starts with initial state of {} and later updates that object, and it's not a problem for them. I've also never heard about this problem from people who integrated Redux and Relay before.

Speaking of presumptions, I'm actually not using Node on the server! :) Neither are a lot of other people who will still have to do front-end development too, and who'd presumably(!) want to enjoy using Redux while at it!

That's not what I'm presuming. I'm trying to support a very popular use case which used to be hard to implement with traditional Flux. I understand not everybody uses Node on the server (in fact I don't, as I use Python).
It's the first time you mentioned that you don't use Node in the whole issue. It would've helped if you said it before because I have a very specific answer for this use case:

If you for some reason don’t use Redux on server but you want to prefill the data anyway (e.g. maybe you use something other than Node), the approach with dispatching actions is your next best bet because it doesn’t require your backend to know the state shape. In this case, you should pass those actions as JSON to the client, and dispatch() all of them right after the store is created.

I hope this helps.

I've recently been ranting about the strange state of front-end development, now that it's somehow completely dependent on Node-based tools. We're writing JavaScript to be run on the client-side, but first we use ~'server-side' tools to "build" it, just because "we" insist on using language features that aren't widely enough supported by browsers yet.

I feel for you but how is this even remotely related to Redux? You can write Redux code in ES5, use a global window.Redux variable, and be happy. This issue is starting to go off the rails.

Yeah, that seems like a good idea. But please let people make mistakes and learn from them. It might even result in discovering a new way of doing things that's even better than yours! :)

Thanks. This is exactly what I try to do. However I learn from issues and questions people post when working on real apps so I can understand their real problem better from the code, rather than the problems they perceive.
These warnings were gradually refined through several releases based on how people used Redux and the issues, misunderstandings and real problems they had. I'm happy to come back to this discussion after you've built an app with Redux and have some real code to share and discuss.

But despite this kind of mentality being widespread in a lot of different ways, no one would be happy about a doctor personally forcing them to eat carrots or exercise. In that case, the coercion would be seen as immoral.

I'm afraid this thread is going off the rails. I am closing it, as I believe I justified my choices and offered workarounds:

Write your own combineReducers()
Write (state = {}, action) or (state = null, action) when you don't know the state shape

I also offered you a few suggestions:

Let reducers manage their own shape, define selectors alongside them to keep the state shape implementation detail
Instead of prepopularing the state tree from non-Node backend, prepopulate a list of actions and pass them to the client so the server stays ignorant of the state shape

I hope this helps.
This discussion is taking a lot of my time, and it's too theoretical for me to take lessons from it.
I'm closing because it has largely devolved into philosophical debate and rants about unrelated topics.
I thank you for your time, and I hope that you try to build something with Redux and let us know your experiences, as well as the pain points you accumulated after you've got something working.

That library is "forcing" you to do something is a strange way to view open source. We are talking about 10 line utility function. As a library we made a choice to add this warning because adding = {} or = null when you mean it won't hurt you. However allowing undefined to be returned from reducers caused myriad of issues when people forgot to add a default case to their switch statements, and thus reset their state on every unknown action because of implicit return. As a library we make choices, and if you don't agree with them please feel free to copy the parts that you like and make your own library and helpers. Without sanity checks Redux is 99 lines so it shouldn't be too difficult: https://gist.github.com/gaearon/ffd88b0e4f00b22c3159


App crashing when loading filters

Good evening everyone.
Since my last topic was closed I'm creating the new one with additional information.
Here's the link to me previous topic with the same problem: https://github.com/MetalPetal/MetalPetal/issues/38
I have photo editing application which is based on MetalPetal framework. The main question is why this application crashes for people who have iPhone 7 or iPhone 8 and better one. But for mine iPhone SE and my friend iPhone 6 it's working just great.
UPDATE:
Now I can tell you that this problem is 100% not because of the memory. I simply can't even IMAGINE why application crashes on iPhone 7 but works great on my iPhone SE.
So now I will tell you all the details to make sure you understand how everything works.
First of all, user picks image from the camera roll. Then he sends it to another screen which is the main screen. (in my case viewController). Then there's one imageView which is the main one and 9 buttons. When user clicks on the button then filter is applied to UIImage. (You can see the example image1 which is UIImage) and then this UIImage is applied to imageView ( which is called in my case "pagrindinis". ( Also you can notice that I'm checking if user clicks on the filter the first time or not. Just to save memory when user clicks only on one filter and when he clicks again then there's no need to apply filter again because we already have UIImage. But that's not important I guess. )
So, the problem is that somehow something is not working when I'm trying to apply filter on UIImage. (You can see the error that application found nil while unwrapping.)
Maybe now there's any chance to help me? I would appreciate any help because you guys rock!
Now there's a screenshots of my error (first image) and the code where I apply image. ALSO, I will add code snippets to be easier to understand.

My code snippet where I apply filter with MetalPetal:
`func pirmas() {
guard let thumbnail2 = original else { return } // "original" is my UIImage from camera roll
guard let cgImage = thumbnail2.cgImage else { return }
guard let lookupimage1 = UIImage(named: "lookup_amatorka.png") else { return } // my lookup
guard let cgImage1 = lookupimage1.cgImage else { return }
let filter1 = MTIColorLookupFilter()
filter1.inputImage = MTIImage(cgImage: cgImage, options: [MTKTextureLoader.Option.SRGB: false])
filter1.inputColorLookupTable = MTIImage(cgImage: cgImage1, options: [MTKTextureLoader.Option.SRGB: false])
filter1.intensity = 0.6

if let device = MTLCreateSystemDefaultDevice(),
let outputImage = filter1.outputImage { //cia
    do {
        let context = try MTIContext(device: device)
        let filteredImage = try context.makeCGImage(from: outputImage)
        image1 = UIImage(cgImage: filteredImage) // here's UIImage which I use later

    } catch {
        print(error)
    }
}

}`
Here you can see code snippet where I apply filter when user clicks on the button:
 @IBAction func teal1(_ sender: Any) {         if firstTime == false {             pirmas() // Here I call function which you can see above             firstTime = true         }         self.pagrindinis.image = image1! // Here I get ERROR that my UIImage is nil         pavadinimas = 1 }
Someone please tell me why this solution is working with iPhone SE and iPhone 6 but not with iPhone 7 and higher.
If you need more information please tell me. I will tell you everything.
Thank you so much!!!

You need to figure out why the image is nil. Step into the pirmas function and see where it quits, or does it run into the catch block and what is the error it prints out.

@YuAo Excuse me for the new topic. It’s new for me.
Speaking about the problem, I can’t understand how iPhone model can affect that image is nil?

Can you debug? Step into the pirmas function and see where it quits, or does it run into the catch block and what is the error it prints out.
The iPhone model is not important, you should first figure out how your code executes.

@YuAo
I believe there's not much what I can do with this problem. I guess there's a problem with this framework. Did you tried colorlookuptables by yourself on iPhone 7 or 8?
For me, it's not crashing anymore but it still don't work on iPhone 7.

We have all models of iPhone from 5s to X tested. Works perfectly. Maybe you can attach a sample project to demonstrate the problem?

@YuAo Oh then I'm confused.
Yes, that would be perfect. Here's my sample project:
SimplyPerf.zip

Two problems.

There's a problem about the color lookup table image. It uses a 16bpc(bit per component) pixel format. The MTKTextureLoader may not be able to load a cgimage in 16bpc format.

The color lookup table should be marked as alphaIsOne. Because it does not contain any transparent or semi-transparent pixel. This will save a unpremultiply operation.

I re-exported the color lookup table, make it a 8bpc, 72pixel/inch png image. And added the alpha type notation to your code. The modified project is attached. Everything should work fine now.
SimplyPerf 2.zip


Translation Connectors

This could include:

[ ] Crowdin
[ ] Google
[ ] Microsoft

Multilingual translation in the code may not be applicable,
Because the translation dictionary does not contain the context.
AI needs context to translate accurately

I forgot to tell you that I will provide a UI to translate the strings

Sounds cool, so can the translation file be exported directly for sharing?
I remember NopCommerce can also trade translation files


Init Seq vs List ambiguous overload

Whereas pattern matching scala.meta.Init works with last parameter argss as Nil - i.e., a List[List[Term]] -, when creating Init, there is the primary constructor that uses argClauses which is a Seq[Term.ArgClause], and a secondary constructor, so gives this error:
Ambiguous overload. The overloaded alternatives of method apply in object Init with types
 (tpe: scala.meta.Type, name: scala.meta.Name, argss: List[List[scala.meta.Term]]): scala.meta.Init
 (tpe: scala.meta.Type, name: scala.meta.Name, argClauses: Seq[scala.meta.Term.ArgClause]): scala.meta.Init
both match arguments (scala.meta.Type.Select, scala.meta.Name.Anonymous, (Nil scala.collection.immutable.Nil.type))

Working textually at the metaprogramming level, I have to use sed to replace Nil with Seq() before pasting the constructor, e.g., Init(Type.Name(...), Name.Anonymous(), Seq()). But trying to find the occurrence of Nil is a no go.
It is the only exception of this case afik. (EDIT: Ctor.Primary(Nil, Name.Anonymous(), Nil) is also the case)
Pointing only at scala.meta.Trees.scala#1084, a quick fix is to add a ("another"?) secondary constructor:
def this(tpe: Type, name: Name, _nil: Nil.type) = this(tpe, name, Seq())

but isn't it cumbersome?! ;)

Thanks for reporting. This is a problem that was caused by making sure we maintain binary compatibility. Once we release a new 5.0.0 version (which is becoming more and more tempting), the additional methods should disappear.
For now you can either type it fully via List.empty[ArgClause] or use named arguments.

Two more peculiarities pop up:
"var c = 'a'".parse[Stat].get.structure
"var c = 'a".parse[Stat].get.structure

give Lit.Char(a) and not Lit.Char('a'), respectively, Lit.Symbol(Symbol(a)) and not Lit.Symbol(Symbol("a")).
I don't know if the problem you refer to is the same as this issue  - which poses in fact a question a lot more simpler.
The documentation mentions:
This document lists examples of how Scala source code maps to Scalameta tree nodes.

It does not specify whether pasting unmodified the string yielded by the parser in, say, the evaluation line of REPL, gives back the AST, not programmatically  "type"d by the user - because I don't want to "type" it.
With me - besides the REPL example, there is also the case of pipelines which use the parser output without modifications redirected to a .scala file, and then process the entire Source(...) AST "as if" "type"d - but it's pasted, not typed.
Will the output of the parser be directly usable as an AST in next versions?

Will the output of the parser be straightly usable as an AST in next versions?

This could be fixed before, looks like a bug.


version info of dependent libs

For contribution to further development it might be helpfull to know the versions of the externals:

https://github.com/libimobiledevice/libplist/releases
http://xmlsoft.org/news.html

used currently as basis and if it is modified.

Yea, i will add this info with a new release of plugin. Hard to know what version we are using now :cuba:

I'll add task to my short-list, to finish soon, but could not fit this in this release.

In a new [https://github.com/azerg/NppBplistPlugin/releases/tag/2.0.0](2.0.0 release), added exact versioning of dependencies/ Going to register plugin update ASAP


prometheus: Improve metrics and stop reconciling on no update

Introduce the 'prometheus_operator_prometheus_reconcile_errors_total'
Prometheus metric counter, differentiated in label dimensions:

triggered_by

monitoringv1.PrometheusesKind
monitoringv1.ServiceMonitorsKind
monitoringv1.PrometheusRuleKind
"ConfigMap"
"Secret"
"StatefulSet"
"Namespace"

action

"add"
"delete"
"update"

Add increase hooks of above mentioned metric to all Kubernetes
informer handlers and add simple log line on debug level.

Add condition to Kubernetes informer update handlers to only preceed
when previous resource version is not equal to new resource version.
This will prevent triggering a reconciliation loop on informer resyncs.

Relates to https://github.com/coreos/prometheus-operator/issues/1659.

This should partially reduce the CPU footprint of the Prometheus Operator. I can not tell if it eliminates the root cause for https://github.com/coreos/prometheus-operator/issues/1659.

I don't think the rbac changes are necessary, otherwise lgtm

Thanks for the review @brancz, removed the rbac changes.


Refactoring docs

Third time is a charm ...

Same as previous PR.

strange, I will double check. Is it OK to add the version from main?

@nuin Yeah, the one in main should be good


[BUG] Invalid Release version 7.0.0 on Mac M1

Is there an existing issue for this?

[X] I have searched the existing issues

Current Behavior
I downloaded the latests version 7.0.0 and installed it. When launch application a message error es throwing.
Error: Cannot find module 'ajv/dist/runtime/equal' ...
It's about "ajv" node module. I tried to modify app.asar with npm install ajv, but not operation is permitted.

Uncaught Exception:
Error: Cannot find module 'ajv/dist/runtime/equal'
Require stack:
- /Applications/Altair GraphQL Client.app/Contents/Resources/app.asar/node_modules/altair-graphql-core/build/validate-partial-settings.js
- /Applications/Altair GraphQL Client.app/Contents/Resources/app.asar/dist/settings/main/store.js
- /Applications/Altair GraphQL Client.app/Contents/Resources/app.asar/dist/settings/main/events.js
- /Applications/Altair GraphQL Client.app/Contents/Resources/app.asar/dist/app/window.js
- /Applications/Altair GraphQL Client.app/Contents/Resources/app.asar/dist/app/index.js
- /Applications/Altair GraphQL Client.app/Contents/Resources/app.asar/dist/index.js
-
at node:internal/modules/cjs/loader:1084:15
at Function._resolveFilename (node:electron/js2c/browser_init:2:117419)
at node:internal/modules/cjs/loader:929:27
at Function._load (node:electron/js2c/asar_bundle:2:13377)
at Module.require (node:internal/modules/cjs/loader:1150:19)
at require (node:internal/modules/cjs/helpers:110:18)
at Object.<anonymous> (/Applications/Altair GraphQL Client.app/Contents/Resources/app.asar/node_modules/altair-graphql-core/build/validate-partial-settings.js:1:2777)
at Module._compile (node:internal/modules/cjs/loader:1271:14)
at Object..js (node:internal/modules/cjs/loader:1326:10)
at Module.load (node:internal/modules/cjs/loader:1126:32)

Expected Behavior
Nodejs module "ajv" needs to pack into app.asar on electron application download. Version 6.4.2 works perfectly but 7.0.0 does not work.
If you update 6.4.2 into application the result is the same.
Steps To Reproduce

Download Altair 7.0.0 Mac M1 (arm64) DMG
Install it (transfer to /Applications)
Open it (does not work)

Environment
- OS: MacOs
- Browser: Electron
- Platform: ARM 64
- Version: 7.0.0

Additional context
It is the same from brew install

Thanks for flagging! I had it as a dev dependency so it works fine for me. I'll fix this asap.

FYI it was fixed in 7.0.1


Font for "de" prefix does not seem to be as described

On my system, with Montserrat v7.200 OTF font, in Inkscape 1.1.2, I get the following result (blue "e") with Montserrat Normal 14pt:

With Montserrat Light 14pt, I get the following:

@baender do you have any clue what I could be doing wrong?
I started from https://github.com/DE-RSE/logo-association/blob/master/de-RSE-logo-only-colour.svg

Editing the Prefix_editable, I get exactly the same result as my initial attempt, so I guess something is wrong with my system.


lure: group host should check connectivity to lure service when creating lure link

If a group host cannot communicate with the lure service, the following can happen:

Group host creates lure link for their group
They share that link to users
Users click that link and end up at a "group not found page"

This happens because the lure service (currently hosted by us on ~loshut-lonreg) does not have the metadata for the lure link because the user's group host ship cannot communicate with it (recently this was because a bunch of galaxies were offline).
Proposal:

When a user enables the lure link, the system should check for connectivity to the lure service (which is set in the landscape settings).
If the group host cannot contact the lure service, it should throw a red warning in the UI and tell the user the lure link could not be created because the lure service was not accessible.

@midsum-salrux I though you'd be a good candidate for this one, but feel free to pull @tomholford in for any help with the UI warning bit.
Also if you have a better proposal for this that's great too (this was just my first thought).
This was one of the things that came out of the discussion about how to avoid edge cases with lure failures (we'll share the doc broadly).

This all makes sense. We track whether we've gotten a poke-ack from the bait service already, so we can just expose this in the UI.

Happy to pull this in for 3.1.0 if it's not a lot of investigative effort

Reopening this since we've seen it not work.

Latest is in https://github.com/tloncorp/landscape-apps/pull/2444 - it sounded like it was on binnec/marnec but not yet deployed? I asked some questions on that PR

I think we're good - closing out based on the questions answered in the PR.


Add Derivative: Dungeons (for Adventurers)

Dungeons
Randomly generated Dungeons made with the support of Realms creator. Tilemaps and room descriptions for future game development are included. Each Dungeon can be connected to a Realm.
Etherscan link: https://etherscan.io/address/0x6174723900c8c3646fC43AA40a3B42E722e9FCD9
OpenSea: https://opensea.io/collection/lootdungeons
Twitter announcement: https://twitter.com/tikireyiam/status/1434851389981745160
Technical details:

Custom generator, Nano ID seed. Multiple levels. Multiple traits. Simple API with JSON files containing tilemap arrays and room descriptions for those who want to create MUD, D&D, 2D/3D games (example IPFS: QmVjvvmPvEFjkxDZ1v2eSPWjwUtUGCL2zA3gPy25VvxBfQ/1). All assets used are licensed with MIT, CC-0 or bought on Itch.
Special thanks to Realms creator for ideas, technical support and encouragement.

Could you please add your entry according to alphabetical sorting by the "name" field? Thanks!

HI @tikirey are you still working on this?

Closing this PR. Feel free to re open.


Update to edition 2018

This crate is one of the last ones on the edition 2015.

Thanks!

Looks like this needs a MSRV-specific Cargo.lock that has to be maintained manually for the foreseeable future :cry:


Rancher cluster memory metrics mismatch grafana cluster metrics on v2.2.0-rc3

What kind of request is this (question/bug/enhancement/feature request):
Possible bug
Steps to reproduce (least amount of steps as possible):

Create kubernetes cluster via RKE on Rancher OS
Install Rancher v2.2.0-rc3 in HA mode via helm
Enable monitoring and leave for a while

Result:

Environment information
v2.2.0-rc3 in HA mode on Rancher OS 1.5.1

Cluster information

Cluster type (Hosted/Infrastructure Provider/Custom/Imported):
RKE created single node

Machine type (cloud/VM/metal) and specifications (CPU/memory):
Virtual Box, 2 CPU, 4 Gb ram

Kubernetes version (use kubectl version):
v1.13.4

Docker version (use docker version):

Client:
 Version:           18.06.1-ce
 API version:       1.38
 Go version:        go1.10.3
 Git commit:        e68fc7a
 Built:             Tue Aug 21 17:20:43 2018
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.06.1-ce
  API version:      1.38 (minimum version 1.12)
  Go version:       go1.10.3
  Git commit:       e68fc7a
  Built:            Tue Aug 21 17:28:38 2018
  OS/Arch:          linux/amd64
  Experimental:     false

I have exactly the same issue on rancher v2.2.3.
I am using single install with AWS cloud provider.
RancherOS:
version v1.5.1 from os image rancher/os:v1.5.1
(ami-04c6caa71c063e2a2)
The Issue only occours on the grafana cluster dashboard. When switching to the node dashboard all values a reasonable.


fix(api): control workers initialization through channels

Closed in favor of https://github.com/shellhub-io/shellhub/pull/3176.
The new pull request, cited above, is simpler and, essentially, does the same.


[Feature Request] 64bit Windows build

Would love to get a 64bit version of Atom for Windows, too since Linux and OS X already have it :)

Agreed.

Duplicate of #4881, please subscribe there for updates.

Oh oops, sorry.


Added common abstraction between JSON serializers

The idea for this stems from #422 , though this has been split off due to PR scope issues.
This adds two new modules that will act as abstraction layer modules to allow implementations to define their own JSON serializers to use whilst end users can simply use JSON (de)serialization without needing to depend on a specific library's implementation.

Can you verify that none of the changes made are breaking, and if they are, fix this PR so that it doesn't include breaking changes? See this japi report for info.

As the Moshi serializer pull request was rejected, and also because alternative serializers are not really a requirement, nor an investment that is really worth it for now, I am henceforth closing this pull request, as the use case it used to serve no longer exists.
If anyone wants to play around with this or use this code on their own, feel free to use it, as I am henceforth releasing this in to the public domain.


Project fails to load when model names contain backticks, asterisk or quotes

First of all, thanks for tackling this integration.  This is huge!
--
I'm trying it out with our sqlmesh project and it fails due to some of our (external) models having unusual naming.
The external model is actually a set of tables named:

analytics_12345.events_20240925
analytics_12345.events_20240926
...

So far, nothing unusual here, but to facilitate local development we mock these tables as a single table in duckdb.  And to make our external-model schema work in both cases (multiple tables in bigquery vs a single table in duckdb), we declare it as:
# file: external_models/bigquery_ga4_export_schema.yaml
- name: 'analytics_12345.`events_*`'
  columns:
[...]

(The table in duckdb actually contains an * in its name, and not as a wildcard.)
That's when things get messy (we also had trouble with sqlmesh initially, but it now supports these).
In short, our external models contain backticks, stars and quotes (when normalized by sqlmesh).
I've checked that replacing these extra characters makes our project load just fine.  I'm happy to contribute a patch, but first would like to know how you'd want these handled.  Just naively adding more string replacements to sqlmesh_model_name_to_key and key_to_sqlmesh_model_name seems like a recipe for disaster.
--
Error message:
dagster._core.errors.DagsterInvalidDefinitionError: "analytics_12345_dot__`events_*`" is not a valid name in Dagster. Names must be in regex ^[A-Za-z0-9_]+$.

Actually upon looking at this a little more. I realize what I need to do is actually use the provided SQLMeshDagsterTranslator for any final connection from sqlmesh to a dagster asset. This should give the correct flexibility. I think the two functions you mentioned (sqlmesh_model_name_to_key and key_to_sqlmesh_model_name) are actually flawed. What we should be doing is internally using exactly the string we have from sqlmesh, but then allow the user to decide whatever the asset name might be in the dagster representation. I'll need to do some refactoring but I think we can make your issue mostly a non-issue (though to get a nice looking name you would need to override the translator). Right now I think things aren't exactly wired in an ideal way mostly because we spent a bit of time figuring out if we could even make this work properly.


api: add pending flag to Device

when adding a new device it will be waiting the user aproval before
allow connections
created routes to allow a new device and list only pending devices

@gustavosbarreto can you check the UI?


Bug on detecting a unavailable video

In some cases, we have to refresh the page in order for the extension to work. We have to analyze it further to find out the cause and fix it.

It looks like the problem is solved. If it happens again, we will just reopen this. But it won't happen :)

It happened! Issue is reopened.
Slow connection on UFPA, we have to figure out what's going on.

You know what, I learned my lesson. This is will probably happen again. And if/when it does, we will find a way through. Like we always do.


fix(deps): update gomod

This PR contains the following updates:

Package
Type
Update
Change

github.com/IBM/platform-services-go-sdk
require
minor
v0.66.0 -> v0.67.0

github.com/IBM/vpc-go-sdk
require
minor
v0.51.0 -> v0.57.0

go (source)
toolchain
minor
1.22.4 -> 1.23.0

Release Notes

IBM/platform-services-go-sdk (github.com/IBM/platform-services-go-sdk)
v0.67.0
Compare Source
Features

Partner Center Sell: add new service to project (#349) (523201c)

IBM/vpc-go-sdk (github.com/IBM/vpc-go-sdk)
v0.57.0
Compare Source
NEW FEATURES

Support VirtualNetworkInterface in response of DeleteVirtualNetworkInterfaces function
Support VirtualNetworkInterface in InstanceNetworkAttachmentReference
Support VirtualNetworkInterface in BareMetalServerNetworkAttachmentReference
Support VirtualNetworkInterface in FlowLogCollectorTarget

BREAKING CHANGES

None

CHANGES

None

BUG FIXES

None

v0.56.0
Compare Source
NEW FEATURES

Support for os reload/replace for BareMetalServer

Introduction of ReplaceBareMetalServerInitializationOptions struct
Introduction of ReplaceBareMetalServerInitialization function
Introduction of reinitializing status in BareMetalServer

BREAKING CHANGES

None

CHANGES

None

BUG FIXES

None

v0.55.0
Compare Source
NEW FEATURES

Support for Firmware  update for BareMetalServer

Introduction of BareMetalServerFirmware, UpdateFirmwareForBareMetalServerOptions structs
Introduction of UpdateFirmwareForBareMetalServer function
Introduction of Firmware in BareMetalServer

BREAKING CHANGES

None

CHANGES

api version 2024-07-09

BUG FIXES

None

v0.54.0
Compare Source
NEW FEATURES

Support for Cross Account File Share Access

BREAKING CHANGES

None

CHANGES

api version 2024-07-02

BUG FIXES

None

v0.53.0
Compare Source
NEW FEATURES

Support for UserDataFormat in Image struct
Support for UserDataFormat filter in ListImagesOptions
Support for AllowUserImageCreation and UserDataFormat in OperatingSystem

BREAKING CHANGES

None

CHANGES

api version 2024-06-11

BUG FIXES

None

v0.52.0
Compare Source
NEW FEATURES

Billing plan for InstanceCatalogOffering
Support for ProtocolStateFilteringMode in ShareMountTargetVirtualNetworkInterfacePrototype
Support for ConfidentialComputeMode for Instances/InstanceTemplates (InstanceProfile) {select availability in us-south only}
Support for Instance in Dns(LoadBalancer)
Support for CatalogOffering in Snapshot, Volume,

BREAKING CHANGES

None

CHANGES

api version 2024-06-04
go version 1.20

BUG FIXES

None

Configuration
📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.

[ ] If you want to rebase/retry this PR, check this box

This PR has been generated by Renovate Bot.

/run pipeline

:tada: This issue has been resolved in version 1.37.2 :tada:
The release is available on GitHub release
Your semantic-release bot :package::rocket:


Getting Razor completion after @inject DateT| results in bad completion with the new modern APIs in dev16

Describe the bug
Razor Document Mappings of the same type (Html + C#) should not be adjacent. In the case mentioned in the title you end up sitting between two C# mappings. A marker C# and the DateT C#. Because of this Roslyn attempts to find completions for two different locations. We should be smarter about where we generate adjacent mappings and do our best to prevent that.

Handled this via the modern completion work going on. Turns out we can't easily handle adjacent C# projections because of cases such as<EMAIL_ADDRESS>


WebHook recieved but not triggering event.

Webhook set for github repository and the receiving 200 back from jenkins server.  Logs look like this:
Mar 04, 2016 8:16:48 AM org.jenkinsci.plugins.ghprb.GhprbWebHook checkSignature INFO: Signatures checking OK Mar 04, 2016 8:16:48 AM org.jenkinsci.plugins.ghprb.GhprbWebHook handleWebHook INFO: Got payload event: push Mar 04, 2016 8:16:48 AM org.jenkinsci.plugins.ghprb.GhprbWebHook handleWebHook WARNING: Request not known Mar 04, 2016 8:16:48 AM org.jenkinsci.plugins.ghprb.GhprbWebHook checkSignature INFO: Signatures checking OK Mar 04, 2016 8:16:48 AM org.jenkinsci.plugins.ghprb.GhprbWebHook handleWebHook INFO: Got payload event: push Mar 04, 2016 8:16:48 AM org.jenkinsci.plugins.ghprb.GhprbWebHook handleWebHook WARNING: Request not known Mar 04, 2016 8:16:48 AM org.jenkinsci.plugins.ghprb.GhprbWebHook checkSignature INFO: Signatures checking OK Mar 04, 2016 8:16:48 AM org.jenkinsci.plugins.ghprb.GhprbWebHook handleWebHook INFO: Got payload event: push Mar 04, 2016 8:16:48 AM org.jenkinsci.plugins.ghprb.GhprbWebHook handleWebHook WARNING: Request not known
Have another project with the exact same configurations and this is what the logs look like for it.
 Triggering  #457 Mar 04, 2016 8:13:12 AM jenkins.plugins.slack.SlackNotifier$SlackJobProperty prebuild INFO: Invoking Started... Mar 04, 2016 8:13:12 AM jenkins.plugins.slack.ActiveNotifier getChanges INFO: Entry hudson.plugins.git.GitChangeSet@8584ed66 Mar 04, 2016 8:13:12 AM jenkins.plugins.slack.StandardSlackService publish INFO: Posting: to #engineering on odentech using https://odentech.slack.com/services/hooks/jenkins-ci?token=F4m37RrBsfd9myItg0J4IA4B: DevOdenDal - #457 Started by changes from sam.flint (1 file(s) changed) (<http://github-jenkins-652346236.us-west-2.elb.amazonaws.com/job/DevOdenDal/457/|Open>) good Mar 04, 2016 8:13:12 AM jenkins.plugins.slack.StandardSlackService publish INFO: Posting succeeded Mar 04, 2016 8:13:25 AM hudson.model.Run execute INFO: DevOdenDal #457 main build action completed: SUCCESS Mar 04, 2016 8:13:25 AM jenkins.plugins.slack.StandardSlackService publish INFO: Posting: to #engineering on odentech using https://odentech.slack.com/services/hooks/jenkins-ci?token=F4m37RrBsfd9myItg0J4IA4B: DevOdenDal - #457 Success after 15 sec (<http://github-jenkins-652346236.us-west-2.elb.amazonaws.com/job/DevOdenDal/457/|Open>) No Tests found. good Mar 04, 2016 8:13:26 AM jenkins.plugins.slack.StandardSlackService publish INFO: Posting succeeded
The differences start with :
org.jenkinsci.plugins.github.webhook.subscriber.DefaultPushGHEventSubscriber onEvent INFO: Received POST for https://github.com/OdenTech/oden_dal
I am not sure what is looking for this event but I also compared the payloads from github and they look identical except for the repo names and etc.    I have the "Build when a change is pushed to GitHub"  checked for both of these projects.   The only difference I can see between them is the GitHub project name.

It looks like GitHub is sending the wrong kind of events.  The plugin only accepts pull_request and issue_comment events.  GitHub is sending a push event, so I am not sure but you might have configured the webhook using a different plugin??  Check your master config and make sure you are only telling the job triggers to use webhooks.  Also, make sure you have checked the box in each job you want that says to build using webhooks.

Hi - I'm cleaning up old issues. It looks like this is either abandoned or resolved, so  I am closing.

It's happing again, unfortunately

I'm having the same issues

I'm having the same issues

Facing the same issue!

facing the same issue


getWindows returns only one window from the system (0.7.0 npm package)

Hello!
We are experiencing the issue with method from the npm package node-window-manager. Method getWindows() from dist/index.js does not return all windows but the first in the system. Our purpose is to find certain window via known process id.
As for now we fixed it directly in the package by adding return true in the ffi.Callback like so

this.getWindows = () => {
const windows = [];
const callback = ffi.Callback("bool", ["int64", "int64"], (hwnd, lParam) => {
windows.push(new window_1.Window(hwnd));
return true // this line was modified
});
windows_1.user32.EnumWindows(callback, 0);
return windows;
};

Is it possible to update the npm package (include the method in newer versions)? I also saw getWindows is not supported in latest version

Fixed in 9d47a5cf8f79ac80504d62dffbe27dd9ebefda12


HDDS-7380. Remove expired certificates from SCM DB

What changes were proposed in this pull request?
Periodically remove expired certificates from scm rocksdb just as housekeeping
HDDS-7380
How was this patch tested?
Added unit test and robot test and also observed it in a local cluster

@ChenSammi thank you Sammi for the review comments, I've addressed them, PTAL

Thanks @Galsza , the last patch LGTM +1.


Better README/docs

The README file is temporary, and probably will be removed soon.
This issue is about a replacement to the legacy README file. Feel free to work on this.

The new README might include a quick tutorial, installation & execution, and a link to the wiki.

I want to do it

The pull request has been approved. Is there anything else that needs to be added that you have not closed this issue? @cyan-ice

Sorry, I had two very busy school weeks.
@BDadmehr0


Performance logging and counters:

Tally and duration counters for Job Queue tasks and RPC calls optionally
rendered by server_info and server_state, and optionally printed to a
distinct log file. Tally each Job Queue task as it is queued,
starts, and finishes running. Track total duration queued and running.
Tally each RPC call as it starts and either finishes successfully or
throws an exception. Track total running duration for each.
Track currently executing Job Queue tasks and RPC methods along with
durations.
Json-formatted performance log file written by a dedicated thread,
for above-described data.
New optional parameter, "counters", for server_info and server_state.
If set, render Job Queue and RPC call counters as well as currently
executing tasks.
New configuration section, "[perf]", to optionally control performance
logging to a file.
Support optional sub-second periods when rendering human-readable
time points.

Jenkins Build Summary
Built from this commit
Built at 20180213 - 00:50:51
Test Results

Build Type
Result
Status

Found some warnings using clang:
/Users/howardhinnant/Development/rippled/src/ripple/basics/impl/PerfLogImp.cpp:279:14: warning: unused variable 'startTime' [-Wunused-variable]
        auto startTime = std::chrono::steady_clock::now();
             ^
In file included from /Users/howardhinnant/Development/rippled/src/ripple/basics/impl/PerfLogImp.cpp:20:
/Users/howardhinnant/Development/rippled/src/ripple/basics/impl/PerfLogImp.h:147:18: warning: private field 'app_' is not used
      [-Wunused-private-field]
    Application& app_;
                 ^
/Users/howardhinnant/Development/rippled/src/ripple/rpc/impl/RPCHandler.cpp:205:10: warning: unused variable 'start' [-Wunused-variable]
    auto start = std::chrono::steady_clock::now();
         ^
/Users/howardhinnant/Development/rippled/src/ripple/rpc/impl/ServerHandlerImp.h:88:20: warning: private field 'perfLog_' is not used
      [-Wunused-private-field]
    perf::PerfLog& perfLog_;
                   ^

@HowardHinnant Fixed on all accounts. I wonder why gcc doesn't show me those warnings? Maybe I need to add a flag to cmake in the build process. Also, I realized only after the fact that my math was wrong because of lack of preceding 0's so thanks for pointing that out. Also, I tried previously to do something with diffing the second but I couldn't figure out the right incantation. Thanks for clarifying. As I use chrono more and more, I like it and understand what you were going for with it.

@nbougalis @scottschurr @HowardHinnant @mellery451
Except where I've commented, I've fixed the issues that you brought up, except for the suggestion to import date.h. I may still do next that but the other stuff has been fixed.

@scottschurr I fixed the usings  that you found in global scope. Thanks.
@HowardHinnant I simplified to_string(Duration) like you suggested.

The commit message for the commit at the base of this branch is really informative.  Thanks for that.  Github seems to handle the formatting just fine.  But git runs the first line of the message together with the contents of the following paragraph which can be really messy and hard to read.  In order to improve the formatting for git you'll need to add a blank line between the heading and the body.  Like this:
Performance logging and counters:

  * Tally and duration counters for Job Queue tasks and RPC calls optionally
    ...

Thanks.

Codecov Report

Merging #2383 into develop will decrease coverage by 1.02%.
The diff coverage is 54.13%.

@@             Coverage Diff             @@
##           develop    #2383      +/-   ##
===========================================
- Coverage     70.3%   69.28%   -1.03%
===========================================
  Files          703      705       +2
  Lines        53671    55538    +1867
===========================================
+ Hits         37735    38479     +744
- Misses       15936    17059    +1123

Impacted Files
Coverage Δ

src/ripple/app/ledger/impl/LedgerToJson.cpp
88.09% <ø> (ø)
:arrow_up:

src/ripple/rpc/impl/Handler.h
20% <ø> (ø)
:arrow_up:

src/ripple/app/misc/SHAMapStore.h
100% <ø> (ø)
:arrow_up:

src/ripple/app/main/Application.h
100% <ø> (ø)
:arrow_up:

src/ripple/basics/date.h
22.34% <ø> (ø)

src/ripple/core/impl/Workers.h
100% <ø> (ø)
:arrow_up:

src/ripple/core/Config.h
100% <ø> (ø)
:arrow_up:

src/ripple/app/misc/NetworkOPs.h
100% <ø> (ø)
:arrow_up:

src/ripple/core/JobQueue.h
100% <ø> (ø)
:arrow_up:

src/ripple/app/main/Main.cpp
35.8% <ø> (ø)
:arrow_up:

... and 42 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 6230204...f7091eb. Read the comment docs.

@scottschurr Unit tests are not useful here. Most of the bugs you found have to do with synchronization and I don't think we do multi-threaded unit tests. Further, this is just for diagnostics. Nothing going on here has any affect on how the server functions.

Hi @mtrippled, here is a commit that adds PerfLog unit tests and fixes a few bugs identified while writing the tests: https://github.com/scottschurr/rippled/commit/0121880a7f30f0d3c8c6043576463a3d0e86b2b6.  You can either cherry-pick that commit or use it as the basis for your own unit tests.
Oh, and you should probably rebase to the latest develop sometime soon.  You'll get improved CI with that rebase thanks to @mellery451.
I'm probably over-invested in this pull request at this point.  And, besides, I'll have limited availability for the next week or so.  So I'll suggest that you remove me as a reviewer and pick a different reviewer to fill my spot.  I think we're getting close.  Thanks for your patience.

@scottschurr I've cherry-picked your unit test commit. Also added @seelabs as a reviewer. I can't seem to figure out how to remove you as a reviewer as reqeusted. So, @mellery451 and Scott D, can you please review this PR?

@seelabs I've fixed most of the issues you've brought up, and I think Scott S answered your questions about the unit tests.

Thanks @mtrippled I'll take a look tomorrow.

@mtrippled Looks good. However, the unused lambda capture in PerfLog_test.cpp (line 813) needs to be addressed (it generates an warning on clang otherwise).