# Multiple data sources

Let's see how we can add multiple data sources and what happens when data is requested.

```java
// Create validators
Validator<UsersRes> ageValidator = AgeValidator.create(TimeUnit.MINUTES.toMillis(2));
Validator<UsersRes> persistentDiskValidator = (key, item) -> Objects.nonNull(item) && !item.getItems().isEmpty();
​
// Builds an instance of Livebox using LiveboxBuilder class.
Livebox<UsersRes, Users> usersBox = new LiveboxBuilder<UsersRes, Users>()
                    .withKey("get_users")
                    .fetch(api::getUserList, UsersRes.class)
                    .addSource(Sources.MEMORY_LRU, ageValidator)
                    .addSource(Sources.DISK_PERSISTENT, persistentDiskValidator)
                    .addConverter(UsersRes.class, usersRes -> Optional.of(Users.fromUsersRes(usersRes)))
                    .retryOnFailure()
                    .build();
```

In this example we add two [data sources](https://sserra.gitbook.io/livebox/livebox-components/local-data-sources) to Livebox instance. This is what happens when the client subscribes the observable.

1. We iterate the list of data sources and ask each one if they have data stored for key "get\_users".  Iteration is done by added order, so in the above example we first ask in-memory LRU data source and then disk persistent data source.
2. If no data source has data available [fetcher](https://sserra.gitbook.io/livebox/livebox-components/fetcher) instance is called to fetch data.
3. When a data source has available data, then call the data source validator to check if the data is still valid. Maybe the data is too old, or is not valid anymore for some other reason. If data is available and it's valid its emitted by the Observable.

{% hint style="info" %}
When the option `.refresh()` is used, even if there's valid data stored locally we still hit the server to refresh it. In this case the Observable will emit twice, first with the local data, that can be used to immediately show content to the user and then with remote data received from fetcher.&#x20;
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sserra.gitbook.io/livebox/how-to-use-it/multiple-data-sources.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
