Merge pull request #1905 from ManfredKarrer/optimize-initial-data-load

Optimize initial data load
This commit is contained in:
Christoph Atteneder 2018-11-13 13:19:50 +01:00 committed by GitHub
commit 17a9d794fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 32 deletions

View file

@ -136,9 +136,7 @@ public class AccountAgeWitnessService {
} }
private void addToMap(AccountAgeWitness accountAgeWitness) { private void addToMap(AccountAgeWitness accountAgeWitness) {
log.debug("addToMap hash=" + Utilities.bytesAsHexString(accountAgeWitness.getHash())); accountAgeWitnessMap.putIfAbsent(accountAgeWitness.getHashAsByteArray(), accountAgeWitness);
if (!accountAgeWitnessMap.containsKey(accountAgeWitness.getHashAsByteArray()))
accountAgeWitnessMap.put(accountAgeWitness.getHashAsByteArray(), accountAgeWitness);
} }

View file

@ -44,13 +44,13 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.SettableFuture; import com.google.common.util.concurrent.SettableFuture;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -273,34 +273,25 @@ class RequestDataHandler implements MessageListener {
}); });
} }
// We process the LazyProcessedStoragePayload items (TradeStatistics) in batches with a delay in between. // We changed the earlier behaviour with delayed execution of chunks of the list as it caused
// We want avoid that the UI get stuck when processing many entries. // worse results as if it is processed in one go.
// The dataStorage.add call is a bit expensive as sig checks is done there. // Main reason is probably that listeners trigger more code and if that is called early at
// startup we have better chances that the user has not already navigated to a screen where the
// Using a background thread might be an alternative but it would require much more effort and // trade statistics are used for UI rendering.
// it would also decrease user experience if the app gets under heavy load (like at startup with wallet sync). // We need to take care that the update period between releases stay short as with the current
// Beside that we mitigated the problem already as we will not get the whole TradeStatistics as we // situation before 0.9 release we receive 4000 objects with a newly installed client, which
// pass the excludeKeys and we pack the latest data dump // causes the application to stay stuck for quite a while at startup.
// into the resources, so a new user do not need to request all data. log.info("Start processing {} delayedItems.", processDelayedItems.size());
long startTs = new Date().getTime();
// In future we will probably limit by date or load on demand from user intent to not get too much data. processDelayedItems.forEach(item -> {
if (item instanceof ProtectedStorageEntry)
// We split the list into sub lists with max 50 items and delay each batch with 200 ms. dataStorage.addProtectedStorageEntry((ProtectedStorageEntry) item, sender, null,
int size = processDelayedItems.size(); false, false);
int chunkSize = 50; else if (item instanceof PersistableNetworkPayload)
int chunks = 1 + size / chunkSize; dataStorage.addPersistableNetworkPayload((PersistableNetworkPayload) item, sender,
int startIndex = 0; false, false, false, false);
for (int i = 0; i < chunks && startIndex < size; i++, startIndex += chunkSize) { });
long delay = (i + 1) * 200; log.info("Processing delayedItems completed after {} sec.", (new Date().getTime() - startTs) / 1000D);
int endIndex = Math.min(size, startIndex + chunkSize);
List<NetworkPayload> subList = processDelayedItems.subList(startIndex, endIndex);
UserThread.runAfter(() -> subList.stream().forEach(item -> {
if (item instanceof ProtectedStorageEntry)
dataStorage.addProtectedStorageEntry((ProtectedStorageEntry) item, sender, null, false, false);
else if (item instanceof PersistableNetworkPayload)
dataStorage.addPersistableNetworkPayload((PersistableNetworkPayload) item, sender, false, false, false, false);
}), delay, TimeUnit.MILLISECONDS);
}
cleanup(); cleanup();
listener.onComplete(); listener.onComplete();