atoti / atoti

atoti issue tracking
Apache License 2.0
214 stars 22 forks source link

Exception caused Jupyter lab to crash #147

Closed HuifangYeo closed 3 years ago

HuifangYeo commented 3 years ago

Steps to reproduce

Referring to the attached notebook. I have no issue running it on atoti 0.4.2. However, upon upgrading to 0.4.3, Jupyter lab kept crashing. Speed of processing also seems to be longer. Twitter and Cryptocurrency - jupyterlab.zip

Environment

Logs (if relevant)

INFO: [ActivePivotManager]: Started
Sep 03, 2020 2:20:40 PM com.qfs.rest.server.impl.JsonExceptionMapper log
WARNING: Failed to complete REST request: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token
 at [Source: (org.apache.cxf.transport.http.AbstractHTTPDestination$1); line: 1, column: 39] (through reference chain: com.qfs.pivot.json.query.JsonMdxQuery["context"]->java.util.LinkedHashMap["Twitter_Cyptocurrency"])
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token
 at [Source: (org.apache.cxf.transport.http.AbstractHTTPDestination$1); line: 1, column: 39] (through reference chain: com.qfs.pivot.json.query.JsonMdxQuery["context"]->java.util.LinkedHashMap["Twitter_Cyptocurrency"])
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1442)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1216)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1126)
    at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:63)
    at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:10)
    at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringKeyMap(MapDeserializer.java:527)
    at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:364)
    at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:29)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
    at com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:1682)
    at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:977)
    at com.fasterxml.jackson.jaxrs.base.ProviderBase.readFrom(ProviderBase.java:814)
    at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBodyReader(JAXRSUtils.java:1429)
    at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBody(JAXRSUtils.java:1381)
    at org.apache.cxf.jaxrs.utils.JAXRSUtils.processRequestBodyParameter(JAXRSUtils.java:896)
    at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:832)
    at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:214)
    at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:78)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
    at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
    at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:267)
    at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234)
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208)
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160)
    at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:225)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:301)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:220)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:276)
    at org.springframework.web.servlet.mvc.ServletWrappingController.handleRequestInternal(ServletWrappingController.java:166)
    at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:177)
    at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:52)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at com.qfs.pivot.servlet.impl.ContextValueFilter.doFilter(ContextValueFilter.java:67)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:92)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1639)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:834)
rcolle commented 3 years ago

I had to fix it in your notebook when I checked it out last time for another issue. One of your visualize widget has a Twitter_Cyptocurrency context value (which doesn't exist) in its state. Not sure how it got there.

HuifangYeo commented 3 years ago

hmm... I'm pretty sure I didn't add in any context value. However, what is weird is that it's working in 0.4.2 but not in 0.4.3

HuifangYeo commented 3 years ago

The Jupyter lab still crashes after I removed the context value

fabiencelier commented 3 years ago

Do you have any error log in the Jupyter lab process ?

HuifangYeo commented 3 years ago

There's no exception in the log: subprocess.log

tibdex commented 3 years ago

Hi Hui Fang, it's the query in your third cube.visualize() that returns a huge cellset.

MDX query
SELECT
  NON EMPTY Crossjoin(
    Hierarchize(
      Union(
        Hierarchize(
          DrilldownLevel(
            [Hierarchies].[date].[ALL].[AllMember]
          )
        ),
        [Hierarchies].[date].[ALL].[AllMember].[2020-02-28]
      )
    ),
    Hierarchize(
      DrilldownLevel(
        [Hierarchies].[tweet_id].[ALL].[AllMember]
      )
    )
  ) ON ROWS,
  NON EMPTY Crossjoin(
    Hierarchize(
      DrilldownLevel(
        [Hierarchies].[coin_symbol].[ALL].[AllMember]
      )
    ),
    {
      [Measures].[polarity.VALUE],
      [Measures].[contributors.COUNT]
    }
  ) ON COLUMNS
  FROM (
    SELECT
    Filter(
      [Hierarchies].[date].[date].Members,
      IsDate(
        [Hierarchies].[date].CurrentMember.MemberValue
      ) AND (
        CDate(
          [Hierarchies].[date].CurrentMember.MemberValue
        ) >= CDate(
          "2020-08-15"
        ) AND CDate(
          [Hierarchies].[date].CurrentMember.MemberValue
        ) < CDate(
          "2020-08-26"
        )
      )
    ) ON COLUMNS
    FROM [Twitter_Cyptocurrency]
  )
  CELL PROPERTIES VALUE, FORMATTED_VALUE, BACK_COLOR, FORE_COLOR, FONT_FLAGS

If you look at the 0.4.3 changelog, you'll see this item:

The first MDX query ran by an atoti widget in JupyterLab is now executed in Python and its resulting cell set is outputted to the corresponding notebook cell. It allows to ensure that the data displayed by the widget reflects the expected state of the cube without having to block the IPython kernel in a fragile way.

So this MDX query is executed in the Python side and its whole cellset is outputted in the notebook cell, crashing JupyterLab.

It used to work in 0.4.2 because it was ActiveUI that was executing the MDX request and telling the server to only get back the first 200 positions out of the 248066 existing ones (using ranges).

Ranges are not supported on the Python side because it requires using the WebSocket API instead of the classic REST API and also because there would be no easy way to tell the server to load the other positions (like it's possible in ActiveUI by listening to the scrolling events).

Can you add some filters to your query so that its resulting cellset is smaller?

HuifangYeo commented 3 years ago

Hi @tibdex, Just thinking aloud on the following:

  1. I cannot modify the query without executing the cell. Once I execute the cell, it crash. I have to recreate another data viz.
  2. supposed I accidentally added a wrong field, and didn't realize it's going to be too many rows. It doesn't feel good if it causes the whole Jupyter lab to crash and I have to restart the browser again? It also defeats the idea of data exploration right?
  3. then is the lazy loading function of the UI pointless now?
  4. what is the number of rows that could trigger a crash?
  5. Is there anyway to throw error message instead of crashing?

Cheers,

rcolle commented 3 years ago

FYI @tibdex is working on this.

tibdex commented 3 years ago

In the next release, the query will be executed client-side again so it will support ranges and that will fix this issue.