Search code examples
javaspring-bootspring-mvccassandraspring-data

com.datastax.oss.driver.api.core.DriverTimeoutException: Query timed out after PT2S


Using spring boot v2.7.3 and Spring Data Cassandra dependency to connect to the Cassandra database. Application is running successfully. When I click on graph, its showing .... Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback.

@Controller
public class MachineController {

    @Autowired
    MachineReportRepository reportRepository;

    @Autowired
    MachineService MachineService;

    @GetMapping("/data/Machine/all")
    public String getMachineGraph(Model model) {

        List<Integer> consumed = new ArrayList<>();
        List<Integer> voltage = new ArrayList<>();
        List<MachineReportData> reports = reportRepository.findAll();
       
        if (reports.size() > 0) {
            reports.forEach(report -> {
                if(report.getConsumed() < 8000) {
                    consumed.add(report.getConsumed());
                    voltage.add(report.getVoltage());
            });

            model.addAttribute("consumed", consumed);
            model.addAttribute("voltage", voltage);

        }
        return "Machineplot";
@Component
public class MachineService {

    @Autowired
    MachineReportRepository machineReports;

    List<MachineReportData> allStates = new ArrayList<>();
    Long allStatesTimer = 0L;

    // Cache for 15 min
    final Integer CACHE_TIMER = 1000 * 60 * 15;

    private void reloadAllStates() {
        if (allStates == null || System.currentTimeMillis() > allStatesTimer) {
            allStatesTimer = System.currentTimeMillis() + CACHE_TIMER;
            allStates = MachineReports.findAll();
            System.out.println("Caching States count: " + allStates.size());
        }
    }

    public List<MachineReportData> getMachineReportData() {
        reloadAllStates();
        return allStates;
    }
@Repository
public class MachineReportRepository {

    protected final CqlSession session;

    private final PreparedStatement psFindAll;
    private final PreparedStatement psfindByDeviceLabel;

    private static final String KEYSPACE = "nodemetrics";
    private static final String TABLE_NAME = "node_Machine_data";
    private static final String COLUMN_GIID = "giid";
    private static final String COLUMN_INSTALLATION_ID = "installationId";
    private static final String COLUMN_DEVICE_LABEL = "nodeLabel";
    private static final String COLUMN_CONSUMED = "consumed";
    private static final String COLUMN_VOLTAGE = "voltage";



    public MachineReportRepository(CqlSession session) {
        this.session = session;

        psFindAll = session.prepare(selectFrom(KEYSPACE, TABLE_NAME)
                .all()
                .build()
                .setConsistencyLevel(LOCAL_QUORUM)
                .setIdempotent(true));

        psfindByDeviceLabel = session.prepare(selectFrom(KEYSPACE, TABLE_NAME)
                .all()
                .whereColumn(COLUMN_DEVICE_LABEL).isEqualTo(bindMarker())
                .build()
                .setConsistencyLevel(LOCAL_QUORUM)
                .setIdempotent(true));
    }

    public List<MachineReportData> findAll() {
        BoundStatement boundStatement = psFindAll.bind()
                .setConsistencyLevel(ONE);

        return getListOfMachineReport(boundStatement);
    }

stack trace

2023-10-03 15:12:52,392 [http-nio-8080-exec-3] ERROR org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet] (:) - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is com.datastax.oss.driver.api.core.DriverTimeoutException: Query timed out after PT2S] with root cause
com.datastax.oss.driver.api.core.DriverTimeoutException: Query timed out after PT2S
    at com.datastax.oss.driver.api.core.DriverTimeoutException.copy(DriverTimeoutException.java:34) ~[java-driver-core-4.14.1.jar:?]
    at com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures.getUninterruptibly(CompletableFutures.java:149) ~[java-driver-core-4.14.1.jar:?]
    at com.datastax.oss.driver.internal.core.cql.MultiPageResultSet$RowIterator.maybeMoveToNextPage(MultiPageResultSet.java:99) ~[java-driver-core-4.14.1.jar:?]
    at com.datastax.oss.driver.internal.core.cql.MultiPageResultSet$RowIterator.computeNext(MultiPageResultSet.java:91) ~[java-driver-core-4.14.1.jar:?]
    at com.datastax.oss.driver.internal.core.cql.MultiPageResultSet$RowIterator.computeNext(MultiPageResultSet.java:79) ~[java-driver-core-4.14.1.jar:?]
    at com.datastax.oss.driver.internal.core.util.CountingIterator.tryToComputeNext(CountingIterator.java:91) ~[java-driver-core-4.14.1.jar:?]
    at com.datastax.oss.driver.internal.core.util.CountingIterator.hasNext(CountingIterator.java:86) ~[java-driver-core-4.14.1.jar:?]
    at com.datastax.oss.driver.shaded.guava.common.collect.Iterators.addAll(Iterators.java:357) ~[java-driver-shaded-guava-25.1-jre-graal-sub-1.jar:?]
    at com.datastax.oss.driver.shaded.guava.common.collect.Iterables.addAll(Iterables.java:320) ~[java-driver-shaded-guava-25.1-jre-graal-sub-1.jar:?]
    at com.datastax.oss.driver.api.core.PagingIterable.all(PagingIterable.java:113) ~[java-driver-core-4.14.1.jar:?]
    at com.xxxxxxxxxx.nodemetricextractor.cassandra.keyspace.nodemetrics.MachineReportRepository.getListOfMachineReport(MachineReportRepository.java:79) ~[classes/:?]
    at com.xxxxxxxxxx.nodemetricextractor.cassandra.keyspace.nodemetrics.MachineReportRepository.findAll(MachineReportRepository.java:65) ~[classes/:?]
    at com.xxxxxxxxxx.nodemetricextractor.cassandra.keyspace.nodemetrics.MachineReportRepository$$FastClassBySpringCGLIB$$2714661f.invoke(<generated>) ~[classes/:?]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.22.jar:5.3.22]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793) ~[spring-aop-5.3.22.jar:5.3.22]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.22.jar:5.3.22]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) ~[spring-aop-5.3.22.jar:5.3.22]
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[spring-tx-5.3.22.jar:5.3.22]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.22.jar:5.3.22]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) ~[spring-aop-5.3.22.jar:5.3.22]
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708) ~[spring-aop-5.3.22.jar:5.3.22]
    at com.xxxxxxxxxx.nodemetricextractor.cassandra.keyspace.nodemetrics.MachineReportRepository$$EnhancerBySpringCGLIB$$9805d40.findAll(<generated>) ~[classes/:?]
    at com.xxxxxxxxxx.nodemetricextractor.web.MachineController.getMachineGraphAll(MachineController.java:118) ~[classes/:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.22.jar:5.3.22]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.22.jar:5.3.22]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.22.jar:5.3.22]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.22.jar:5.3.22]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.22.jar:5.3.22]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.22.jar:5.3.22]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1070) ~[spring-webmvc-5.3.22.jar:5.3.22]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.22.jar:5.3.22]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.22.jar:5.3.22]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.22.jar:5.3.22]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[tomcat-embed-core-9.0.65.jar:4.0.FR]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.22.jar:5.3.22]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.65.jar:4.0.FR]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.65.jar:9.0.65]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.22.jar:5.3.22]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.22.jar:5.3.22]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96) ~[spring-boot-actuator-2.7.3.jar:2.7.3]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.22.jar:5.3.22]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
    at java.lang.Thread.run(Thread.java:834) ~[?:?]
2023-10-03 15:12:52,400 [http-nio-8080-exec-3] INFO  com.xxxxxxxxxx.nodemetricextractor.web.CommonAttributeInterceptor (:) - [preHandle][org.apache.catalina.core.ApplicationHttpRequest@21c85603][GET]/error



Solution

  • So, I don't actually see a question here. But I can tell you why this is happening:

    List<MachineReportData> reports = reportRepository.findAll();
    

    Behind the scenes, the findAll() method is likely doing something like this:

    SELECT * FROM report;
    

    In Cassandra, we call that an unbound query. There isn't a WHERE clause, so the driver cannot figure out which node has the data. So, it picks a "coordinator node," which then polls all of the other nodes in the cluster for data, assembles and returns the result set.

    That's a lot for one node to do. Often, the node gets to a point where it can't allocate any more resources for the query and times-out. Obviously, this problem gets worse as the overall dataset and number of nodes increase. This is why this behavior is discouraged with Cassandra.

    Remember that Spring Data was first written for relational databases. Now while it does a pretty good job with Cassandra, it still has methods that shouldn't ever be used such as:

    • count()
    • saveAll()
    • findAll()

    Basically, if you find a delivered Spring Data method that ends in All(), it should be avoided.