You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by dp...@apache.org on 2019/01/25 19:37:37 UTC

[ignite-teamcity-bot] branch ignite-10989-2 updated: IGNITE-10989 Removing in-memory caches for data presented in new TcIgnited DB

This is an automated email from the ASF dual-hosted git repository.

dpavlov pushed a commit to branch ignite-10989-2
in repository https://gitbox.apache.org/repos/asf/ignite-teamcity-bot.git


The following commit(s) were added to refs/heads/ignite-10989-2 by this push:
     new dc62ebe  IGNITE-10989 Removing in-memory caches for data presented in new TcIgnited DB
dc62ebe is described below

commit dc62ebe057d676e7c4f5a4c4f3a067cf06f79b5f
Author: Dmitriy Pavlov <dp...@apache.org>
AuthorDate: Fri Jan 25 22:37:34 2019 +0300

    IGNITE-10989 Removing in-memory caches for data presented in new TcIgnited DB
---
 .../java/org/apache/ignite/ci/db/DbMigrations.java |   3 -
 .../org/apache/ignite/ci/di/IgniteTcBotModule.java |   2 -
 .../apache/ignite/ci/web/BackgroundUpdater.java    | 213 ---------------------
 .../java/org/apache/ignite/ci/web/CtxListener.java |   6 -
 .../apache/ignite/ci/web/IBackgroundUpdatable.java |  30 ---
 .../ci/web/model/current/TestFailuresSummary.java  |   7 +-
 .../ignite/ci/web/model/current/UpdateInfo.java    |   1 +
 .../ci/web/rest/build/GetBuildTestFailures.java    |  38 ++--
 .../rest/tracked/GetTrackedBranchTestResults.java  |  25 ++-
 ignite-tc-helper-web/src/main/webapp/build.html    |  41 +++-
 10 files changed, 61 insertions(+), 305 deletions(-)

diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/db/DbMigrations.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/db/DbMigrations.java
index ec6d4db..a1a646b 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/db/DbMigrations.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/db/DbMigrations.java
@@ -205,9 +205,6 @@ public class DbMigrations {
             oldBuilds.destroy();
         });
 
-        applyRemoveCache(GetTrackedBranchTestResults.ALL_TEST_FAILURES_SUMMARY);
-
-        applyRemoveCache(GetBuildTestFailures.TEST_FAILURES_SUMMARY_CACHE_NAME);
         applyRemoveCache(Old.CURRENT_PR_FAILURES);
 
         applyDestroyIgnCacheMigration(TEST_OCCURRENCE_FULL);
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/IgniteTcBotModule.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/IgniteTcBotModule.java
index 64ecd36..d11a2fa 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/IgniteTcBotModule.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/IgniteTcBotModule.java
@@ -37,7 +37,6 @@ import org.apache.ignite.ci.tcbot.TcBotBusinessServicesModule;
 import org.apache.ignite.ci.tcbot.issue.IssueDetector;
 import org.apache.ignite.ci.teamcity.ignited.TeamcityIgnitedModule;
 import org.apache.ignite.ci.util.ExceptionUtil;
-import org.apache.ignite.ci.web.BackgroundUpdater;
 import org.apache.ignite.ci.web.TcUpdatePool;
 import org.apache.ignite.ci.web.model.hist.VisasHistoryStorage;
 import org.apache.ignite.ci.web.rest.exception.ServiceStartingException;
@@ -74,7 +73,6 @@ public class IgniteTcBotModule extends AbstractModule {
         bind(ObserverTask.class).in(new SingletonScope());
         bind(BuildObserver.class).in(new SingletonScope());
         bind(VisasHistoryStorage.class).in(new SingletonScope());
-        bind(BackgroundUpdater.class).in(new SingletonScope());
 
         install(new TeamcityIgnitedModule());
         install(new JiraIgnitedModule());
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/BackgroundUpdater.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/BackgroundUpdater.java
deleted file mode 100644
index b029600..0000000
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/BackgroundUpdater.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.ci.web;
-
-import com.google.common.base.Stopwatch;
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-import javax.inject.Inject;
-import org.apache.ignite.ci.IgnitePersistentTeamcity;
-import org.apache.ignite.ci.analysis.Expirable;
-import org.apache.ignite.ci.tcbot.conf.ITcBotConfig;
-import org.apache.ignite.ci.user.ICredentialsProv;
-import org.apache.ignite.ci.util.ExceptionUtil;
-import org.apache.ignite.internal.util.typedef.T2;
-import org.apache.ignite.lang.IgniteClosure;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Component for storing catchable results into guava in mem-caches and get updates
- */
-@Deprecated
-public class BackgroundUpdater {
-    /** Logger. */
-    private static final Logger logger = LoggerFactory.getLogger(BackgroundUpdater.class);
-
-    /** Expire milliseconds, provide cached result with flag to update */
-    private static final long EXPIRE_MS = TimeUnit.MINUTES.toMillis(1);
-
-    /** Thread factory. */
-    private ThreadFactory threadFactory = Executors.defaultThreadFactory();
-
-    /** Scheduled updates. */
-    private final Cache<T2<String, ?>, Future<?>> scheduledUpdates
-        = CacheBuilder.<T2<String, ?>, Future<?>>newBuilder()
-        .maximumSize(100)
-        .expireAfterWrite(15, TimeUnit.MINUTES)
-        .softValues()
-        .build();
-
-    /** Data loaded. */
-    private final Cache<T2<String, ?>, Expirable<?>> dataLoaded
-        = CacheBuilder.<T2<String, ?>, Expirable<?>>newBuilder()
-        .maximumSize(100)
-        .expireAfterWrite(15, TimeUnit.MINUTES)
-        .softValues()
-        .build();
-
-    /** Service. */
-    private ExecutorService svc = Executors.newFixedThreadPool(5, r -> {
-        Thread thread = threadFactory.newThread(r);
-
-        thread.setName("bgupd-" + thread.getName());
-
-        return thread;
-    });
-
-    /** Config. */
-    @Inject private ITcBotConfig cfg;
-
-
-    /**
-     * @param prov Credentials Provoder.
-     */
-    @NotNull private String availServers(ICredentialsProv prov) {
-        StringBuffer sb = new StringBuffer();
-        sb.append("[");
-
-        cfg.getServerIds()
-            .stream()
-            .filter(prov::hasAccess)
-            .forEach(s -> sb.append(s).append(" "));
-
-        sb.append("]");
-
-        return sb.toString();
-    }
-
-    @Nullable public <K, V extends IBackgroundUpdatable> V get(String cacheName,
-        ICredentialsProv prov,
-        K key,
-        IgniteClosure<K, V> load,
-        boolean triggerSensitive) {
-        String postfix = (prov == null) ? "" : "-" + availServers(prov);
-
-        return get(cacheName + postfix, key, load, triggerSensitive);
-    }
-
-    @Nullable private <K, V extends IBackgroundUpdatable> V get(String cacheName, K key, IgniteClosure<K, V> load,
-        boolean triggerSensitive) {
-
-        final T2<String, ?> computationKey = new T2<String, Object>(cacheName, key);
-
-        //Lazy calculation of required value
-        final Callable<V> loadAndSaveCall = () -> {
-            Stopwatch started = Stopwatch.createStarted();
-            logger.info("Running background upload for [" + cacheName + "] for key [" + key + "]");
-            V val = null;  //todo how to handle non first load error
-            try {
-                val = load.apply(key);
-            }
-            catch (Exception e) {
-                logger.error("Failed to complete background upload for [" + cacheName + "] " +
-                    "for key [" + key + "], required " + started.elapsed(TimeUnit.MILLISECONDS) + " ms", e);
-
-                throw e;
-            }
-
-            logger.info("Successfully completed background upload for [" + cacheName + "] " +
-                "for key [" + key + "], required " + started.elapsed(TimeUnit.MILLISECONDS) + " ms");
-
-            return val;
-        };
-
-        //check for computation cleanup required
-        final Future<?> oldFut = scheduledUpdates.getIfPresent(computationKey);
-
-        if (oldFut != null && (oldFut.isCancelled() || oldFut.isDone()))
-            scheduledUpdates.invalidate(computationKey);
-
-        Expirable<V> expirable;
-
-        try {
-            expirable = (Expirable<V>)dataLoaded.get(computationKey,
-                () -> new Expirable<V>(loadAndSaveCall.call()));
-        }
-        catch (ExecutionException e) {
-            throw ExceptionUtil.propagateException(e);
-        }
-
-        if (isRefreshRequired(expirable, triggerSensitive)) {
-            Callable<?> loadModified = () -> {
-                try {
-                    V call = loadAndSaveCall.call();
-
-                    Expirable<Object> expirable1 = new Expirable<>(call);
-
-                    dataLoaded.put(computationKey, expirable1);
-                }
-                finally {
-                    scheduledUpdates.invalidate(computationKey); //todo race here is possible if value was changed
-                }
-
-                return computationKey;
-            };
-
-            Callable<Future<?>> startingFunction = () -> svc.submit(loadModified);
-
-            try {
-                scheduledUpdates.get(computationKey, startingFunction);
-            }
-            catch (ExecutionException e) {
-                logger.error("Scheduled update for "
-                                + computationKey + " indicated error, dropping this compaction", e);
-
-                scheduledUpdates.invalidate(computationKey);
-            }
-        }
-
-        final V data = expirable.getData();
-        data.setUpdateRequired(isRefreshRequired(expirable, triggerSensitive)); //considered actual
-        return data;
-    }
-
-    private <V extends IBackgroundUpdatable> boolean isRefreshRequired(Expirable<V> expirable, boolean triggerSensitive) {
-
-        if (triggerSensitive)
-            return !expirable.isAgeLessThanSecs(IgnitePersistentTeamcity.getTriggerRelCacheValidSecs(60));
-
-        return expirable.getAgeMs() > EXPIRE_MS;
-    }
-
-    public void stop() {
-        scheduledUpdates.asMap().values().forEach(future -> future.cancel(true));
-
-        scheduledUpdates.cleanUp();
-
-        dataLoaded.cleanUp();
-
-        svc.shutdown();
-
-        try {
-            svc.awaitTermination(10, TimeUnit.SECONDS);
-        }
-        catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-        }
-    }
-}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/CtxListener.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/CtxListener.java
index 8619355..8cae89f 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/CtxListener.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/CtxListener.java
@@ -43,10 +43,6 @@ public class CtxListener implements ServletContextListener {
         return (Injector)ctx.getAttribute(INJECTOR);
     }
 
-    public static BackgroundUpdater getBackgroundUpdater(ServletContext ctx) {
-        return getInjector(ctx).getInstance(BackgroundUpdater.class);
-    }
-
     /** {@inheritDoc} */
     @Override public void contextInitialized(ServletContextEvent sctxEvt) {
         initLoggerBridge();
@@ -82,8 +78,6 @@ public class CtxListener implements ServletContextListener {
 
         Injector injector = getInjector(ctx);
 
-        getBackgroundUpdater(ctx).stop();
-
         try {
 
             injector.getInstance(IssueDetector.class).stop();
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/IBackgroundUpdatable.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/IBackgroundUpdatable.java
deleted file mode 100644
index 30955db..0000000
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/IBackgroundUpdatable.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.ci.web;
-
-/**
- *
- */
-@Deprecated
-public interface IBackgroundUpdatable {
-    /**
-     * Sets flag indicating if update required from HTML interface, new results will be prepared by updater soon
-     * @param update update flag
-     */
-    public void setUpdateRequired(boolean update);
-}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/TestFailuresSummary.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/TestFailuresSummary.java
index f3bfa23..cc2a57e 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/TestFailuresSummary.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/TestFailuresSummary.java
@@ -20,14 +20,13 @@ package org.apache.ignite.ci.web.model.current;
 import com.google.common.base.Objects;
 import java.util.ArrayList;
 import java.util.List;
-import org.apache.ignite.ci.web.IBackgroundUpdatable;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.jetbrains.annotations.Nullable;
 
 /**
  * Summary of failures from all servers.
  */
-@SuppressWarnings("WeakerAccess") public class TestFailuresSummary extends UpdateInfo implements IBackgroundUpdatable {
+@SuppressWarnings("WeakerAccess") public class TestFailuresSummary extends UpdateInfo {
     /** Servers (Services) and their chain results. */
     public List<ChainAtServerCurrentStatus> servers = new ArrayList<>();
 
@@ -39,10 +38,6 @@ import org.jetbrains.annotations.Nullable;
     /** Tracked branch ID. */
     @Nullable private String trackedBranch;
 
-    @Override public void setUpdateRequired(boolean update) {
-        updateRequired = update;
-    }
-
     public void addChainOnServer(ChainAtServerCurrentStatus chainStatus) {
         servers.add(chainStatus);
 
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/UpdateInfo.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/UpdateInfo.java
index 84810c4..0da7985 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/UpdateInfo.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/UpdateInfo.java
@@ -38,6 +38,7 @@ import org.apache.ignite.ci.jira.pure.IJiraIntegration;
     public Integer javaFlags = 0;
 
     /** Update required, set by background updater. */
+    @Deprecated
     public boolean updateRequired = false;
 
     /** Running updates is in progress, summary is ready, but it is subject to change */
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/build/GetBuildTestFailures.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/build/GetBuildTestFailures.java
index 9d57fb9..eabf526 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/build/GetBuildTestFailures.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/build/GetBuildTestFailures.java
@@ -36,13 +36,11 @@ import org.apache.ignite.ci.teamcity.restcached.ITcServerProvider;
 import org.apache.ignite.ci.user.ICredentialsProv;
 import org.apache.ignite.ci.web.model.current.BuildStatisticsSummary;
 import org.apache.ignite.ci.web.model.hist.BuildsHistory;
-import org.apache.ignite.ci.web.BackgroundUpdater;
 import org.apache.ignite.ci.web.CtxListener;
 import org.apache.ignite.ci.web.model.current.ChainAtServerCurrentStatus;
 import org.apache.ignite.ci.web.model.current.TestFailuresSummary;
 import org.apache.ignite.ci.web.model.current.UpdateInfo;
 import org.apache.ignite.ci.web.rest.exception.ServiceUnauthorizedException;
-import org.apache.ignite.ci.web.rest.parms.FullQueryParams;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -63,56 +61,46 @@ import static com.google.common.base.Strings.isNullOrEmpty;
 @Produces(MediaType.APPLICATION_JSON)
 public class GetBuildTestFailures {
     public static final String BUILD = "build";
-    public static final String TEST_FAILURES_SUMMARY_CACHE_NAME = BUILD + "TestFailuresSummary";
 
+    /** Context. */
     @Context
     private ServletContext ctx;
 
+    /** Request. */
     @Context
     private HttpServletRequest req;
 
     @GET
     @Path("failures/updates")
     public UpdateInfo getTestFailsUpdates(
-        @QueryParam("serverId") String serverId,
+        @QueryParam("serverId") String srvId,
         @QueryParam("buildId") Integer buildId,
         @Nullable @QueryParam("checkAllLogs") Boolean checkAllLogs) throws ServiceUnauthorizedException {
-        return new UpdateInfo().copyFrom(getBuildTestFails(serverId, buildId, checkAllLogs));
+        return new UpdateInfo().copyFrom(getBuildTestFailsNoSync(srvId, buildId, checkAllLogs));
     }
 
     @GET
     @Path("failures/txt")
     @Produces(MediaType.TEXT_PLAIN)
     public String getTestFailsText(
-        @QueryParam("serverId") String serverId,
+        @QueryParam("serverId") String srvId,
         @QueryParam("buildId") Integer buildId,
         @Nullable @QueryParam("checkAllLogs") Boolean checkAllLogs) throws ServiceUnauthorizedException {
-        return getBuildTestFails(serverId, buildId, checkAllLogs).toString();
+        return getBuildTestFails(srvId, buildId, checkAllLogs).toString();
     }
 
     @GET
-    @Path("failures")
-    public TestFailuresSummary getBuildTestFails(
-        @QueryParam("serverId") String serverId,
+    @Path("failuresNoSync")
+    public TestFailuresSummary getBuildTestFailsNoSync(
+        @QueryParam("serverId") String srvId,
         @QueryParam("buildId") Integer buildId,
-        @Nullable @QueryParam("checkAllLogs") Boolean checkAllLogs)
-        throws ServiceUnauthorizedException {
-
-        final BackgroundUpdater updater = CtxListener.getBackgroundUpdater(ctx);
-
-        final ICredentialsProv prov = ICredentialsProv.get(req);
-
-        FullQueryParams param = new FullQueryParams();
-        param.setServerId(serverId);
-        param.setBuildId(buildId);
-        param.setCheckAllLogs(checkAllLogs);
-        return updater.get(TEST_FAILURES_SUMMARY_CACHE_NAME, prov, param,
-            (k) -> getBuildTestFailsNoCache(k.getServerId(), k.getBuildId(), k.getCheckAllLogs()), true);
+        @Nullable @QueryParam("checkAllLogs") Boolean checkAllLogs) {
+        return collectBuildCtxById(srvId, buildId, checkAllLogs, SyncMode.NONE);
     }
 
     @GET
-    @Path("failuresNoCache")
-    @NotNull public TestFailuresSummary getBuildTestFailsNoCache(
+    @Path("failures")
+    @NotNull public TestFailuresSummary getBuildTestFails(
         @QueryParam("serverId") String srvId,
         @QueryParam("buildId") Integer buildId,
         @Nullable @QueryParam("checkAllLogs") Boolean checkAllLogs) {
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/tracked/GetTrackedBranchTestResults.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/tracked/GetTrackedBranchTestResults.java
index a45b9c6..de1d0a8 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/tracked/GetTrackedBranchTestResults.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/tracked/GetTrackedBranchTestResults.java
@@ -19,13 +19,20 @@ package org.apache.ignite.ci.web.rest.tracked;
 
 import com.google.inject.Injector;
 import java.util.Set;
-import org.apache.ignite.ci.tcbot.conf.ITcBotConfig;
-import org.apache.ignite.ci.tcmodel.mute.MuteInfo;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
 import org.apache.ignite.ci.tcbot.chain.TrackedBranchChainsProcessor;
+import org.apache.ignite.ci.tcbot.conf.ITcBotConfig;
 import org.apache.ignite.ci.tcbot.visa.TcBotTriggerAndSignOffService;
+import org.apache.ignite.ci.tcmodel.mute.MuteInfo;
 import org.apache.ignite.ci.teamcity.ignited.SyncMode;
 import org.apache.ignite.ci.user.ICredentialsProv;
-import org.apache.ignite.ci.web.BackgroundUpdater;
 import org.apache.ignite.ci.web.CtxListener;
 import org.apache.ignite.ci.web.model.current.TestFailuresSummary;
 import org.apache.ignite.ci.web.model.current.UpdateInfo;
@@ -35,23 +42,13 @@ import org.apache.ignite.internal.util.typedef.F;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-
-import static org.apache.ignite.ci.teamcity.ignited.TeamcityIgnitedImpl.DEFAULT_PROJECT_ID;
 import static org.apache.ignite.ci.tcbot.conf.ITcBotConfig.DEFAULT_SERVER_ID;
+import static org.apache.ignite.ci.teamcity.ignited.TeamcityIgnitedImpl.DEFAULT_PROJECT_ID;
 
 @Path(GetTrackedBranchTestResults.TRACKED)
 @Produces(MediaType.APPLICATION_JSON)
 public class GetTrackedBranchTestResults {
     public static final String TRACKED = "tracked";
-    public static final String ALL_TEST_FAILURES_SUMMARY = "AllTestFailuresSummary";
 
     /** Servlet Context. */
     @Context
diff --git a/ignite-tc-helper-web/src/main/webapp/build.html b/ignite-tc-helper-web/src/main/webapp/build.html
index e27dfeb..53a729c 100644
--- a/ignite-tc-helper-web/src/main/webapp/build.html
+++ b/ignite-tc-helper-web/src/main/webapp/build.html
@@ -22,7 +22,6 @@ $(document).ready(function() {
     
     $( document ).tooltip();
     loadData();
-     //todo fix setInterval( function() { checkForUpdate(); }, 30000);
 
     $.ajax({ url: "rest/branches/version",  success: showVersionInfo, error: showErrInLoadStatus });
 });
@@ -32,17 +31,15 @@ function parmsForRest() {
     var curReqParms = "";
     var buildId = findGetParameter("buildId");
 
-        curReqParms += "?buildId=" + buildId; 
+    curReqParms += "?buildId=" + buildId;
 
     var serverId = findGetParameter("serverId");
-    if(serverId!=null) {
+    if (serverId != null) {
         curReqParms += "&serverId=" + serverId;
     }
 
-
-
     var checkAllLogs = findGetParameter("checkAllLogs");
-    if(checkAllLogs!=null) {
+    if (checkAllLogs != null) {
         curReqParms += "&checkAllLogs=" + checkAllLogs;
     }
     return curReqParms;
@@ -79,6 +76,7 @@ function loadData() {
     var curFailuresUrl = "rest/build/failures" + parmsForRest();
     
     $("#loadStatus").html("<img src='https://www.wallies.com/filebin/images/loading_apple.gif' width=20px height=20px> Please wait");
+    setTimeout(loadPartialData, 3000);
     $.ajax({
         url: curFailuresUrl,
         success: function(result) {
@@ -96,6 +94,37 @@ function loadData() {
     });
 }
 
+function loadPartialData() {
+    var curFailuresUrl = "rest/build/failuresNoSync" + parmsForRest();
+
+    if (g_shownDataHashCodeHex !== "") {
+        return;
+    }
+    $.ajax({
+        url: curFailuresUrl,
+        success: function (result) {
+            if (g_shownDataHashCodeHex !== "") {
+                return;
+            }
+
+            var validResult = true;
+            for (var i = 0; i < result.servers.length; i++) {
+                var server = result.servers[i];
+
+                if (isDefinedAndFilled(server.buildNotFound) && server.buildNotFound) {
+                    validResult = false;
+                    break;
+                }
+            }
+            if (validResult)
+                showData(result);
+
+            setTimeout(loadPartialData, 3000);
+        },
+        error: showErrInLoadStatus
+    });
+}
+
 function showData(result) {
     var txtUrl = "rest/build/failures/txt" + parmsForRest();