Repository: bokeh/bokeh

Issue:
Some clients send bad pong, lower log level to reduce noise
FYI.  Doesn't appear to be causing problems for users, but I'm seeing a bunch of these in the logs:

```
ERROR:bokeh.server.views.ws:received invalid integer in pong ''
Traceback (most recent call last):
  File "[...]/.local/lib/python2.7/site-packages/bokeh/server/views/ws.py", line 167, in on_pong
    self.latest_pong = int(codecs.decode(data, 'utf-8'))
ValueError: invalid literal for int() with base 10: ''
```


Discussion:
I've only ever seen this on windows, so I assume you are running windows? Agree it's annoying I've never been able to track down a cause in passing observation but it's good to have an issue.
No, running on an AWS Linux instance.  Don't have the time to troubleshoot right now, will try to circle back later.
Not viewing from windows?
The pasted output is from a process running on AWS Lin, which I am SSHed
into from OSX. I expect all of the non-me traffic to this page is coming
from Windows machines.

On Thu, Apr 20, 2017 at 10:27 AM Bryan Van de Ven <notifications@github.com>
wrote:

> Not viewing from windows?
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub
> <https://github.com/bokeh/bokeh/issues/6175#issuecomment-295824796>, or mute
> the thread
> <https://github.com/notifications/unsubscribe-auth/AHtGeE3n-Kt87N90X_IClmgUtTkL1QQSks5rx5VpgaJpZM4NDQ4Y>
> .
>

Right, to be clear: I've only seen this occur when windows clients connect. I don't think it matters what or where the server is running. I believe the cause is connecting from windows. I'm trying to nail down if that observation is incorrect. It sounds like you are saying the situation fits that description. 
I get this error when I open my Bokeh app from a smartphone, Android and iOS.

```
2017-05-19 14:25:34,294 received invalid integer in pong ''
Traceback (most recent call last):
  File "/opt/envs/virtual/local/lib/python2.7/site-packages/bokeh/server/views/ws.py", line 167, in on_pong
    self.latest_pong = int(codecs.decode(data, 'utf-8'))
ValueError: invalid literal for int() with base 10: ''
```
I'm running Bokeh 0.12.4 behind a Nginx server on a Digital Ocean VPS, Ubuntu 16.04.1 x64.
For reference, our ping implementation is two lines:
```
def send_ping(self):
    self._socket.ping(codecs.encode(str(self._ping_count), "utf-8"))
    self._ping_count += 1
```

And the corresponding pong handler is almost as short:
```
def on_pong(self, data):
    # if we get an invalid integer or utf-8 back, either we
    # sent a buggy ping or the client is evil/broken.
    try:
        self.latest_pong = int(codecs.decode(data, 'utf-8'))
    except UnicodeDecodeError:
        log.error("received invalid unicode in pong %r", data, exc_info=True)
    except ValueError:
        log.error("received invalid integer in pong %r", data, exc_info=True)
```

What the message is saying is that connected clients are sending back bad pong responses to pings. They are supposed to send back the ping data as-is exactly as they got it, but they are clearly not doing that. This seems to be an issue with certain clients and I'm not sure what we can do about that on this end. 

Alternatively, for this not to be a client issue somehow, then it would need to be the case that this: 
```
codecs.encode(str(self._ping_count), "utf-8")
``` 
is somehow generating empty strings.  Let's try to rule that out. @JulianKrick @jbrockmendel if you can reproduce this reliably, can you try editing your `send_ping` function locally?

It is located here

https://github.com/bokeh/bokeh/blob/master/bokeh/server/connection.py#L45-L47

I'd suggest this as a new version:

```
def send_ping(self):
    data = codecs.encode(str(self._ping_count), "utf-8")
    try:
        int(codecs.decode(data, 'utf-8'))
    except UnicodeDecodeError:
        log.error("generated invalid unicode in pong %r", data, exc_info=True)
    except ValueError:
        log.error("generated invalid integer in pong %r", data, exc_info=True)
    self._socket.ping(data)
    self._ping_count += 1
```

If you see the messages about receiving bad pongs but don't see corresponding messages about *generating* bad pings, then this is definitely a client-side issue and so probably outside our control. The best we could do is to possibly offer a configuration option to suppress bad ping log messages if desired. 
I wasn't able to reproduce this problem, yet. I will keep trying and then apply your suggestion. Thanks!
Just implemented the suggested patch, will let you know if I see anything in the logs.
@jbrockmendel great, look forward to hearing back though I suspect that ultimately the best we may be able to do is offer an option to suppress these log messages 
I am using Windows 10 Version 1703 and Bokeh 0.12.10 and I have the same issue as well.
I implemented the new version of `def send_ping(self)` but still got the error. So this does seem to be a client-side issue.

The following is my personal "patch" in the file:
`Anaconda3\lib\site-packages\bokeh\server\views\ws.py`

One solution is lowering the logging level of the error message. The default `--log-level` for Bokeh is 'info'. So if you set the message to `debug`, it will not get shown unless you start Bokeh with `--log-level debug`.
```python
def on_pong(self, data):
        # if we get an invalid integer or utf-8 back, either we
        # sent a buggy ping or the client is evil/broken.
        try:
            self.latest_pong = int(codecs.decode(data, 'utf-8'))
        except UnicodeDecodeError:
            log.debug("received invalid unicode in pong %r", data, exc_info=True)
        except ValueError:
            log.debug("received invalid integer in pong %r", data, exc_info=True)
```
Alternatively, you can start Bokeh with `--log-level critical`, then you don't have to edit the code at all - but you will not see all the "useful" infos, warnings and errors.
I get this error on bokeh server running behind IIS. Curiously, first connection establishes fine and without any errors. All subsequent connections force an error. As result I get something very strange: I see the same session in all connected browser windows. Changes made in one window are reflected in others.

So, not only there is error message, but somehow multiple connections are merged into one. Which is probably separate IIS issue, that I am still looking into.

Given the results from the patch above,I don't think there is anything we can do on our end. As it seems to be otherwise harmless, I will support lowering the log level, even to `trace`.
Thanks for looking into this, feel free to close.

TBH I've lost track of what the use case for bokeh is.  My unit tests for bokeh-using code started failing a few months ago with ImportErrors and it looked like I was supposed to use HoloViews instead, but I never got around to sorting out the "correct" stack.
Bokeh is a tool for interactive data visualization in the browser. It has many use cases. HoloViews is an even higher level API on top of Bokeh. 
I'll circle back and try again before long.  Up until version mismatch caused things to break, bokeh produced some beautiful outputs.
> I'll circle back and try again before long. Up until version mismatch caused things to break, bokeh produced some beautiful outputs.

By version mismatch are you referring to this "ping" issue? Or something else? The ping issue should be harmless, if annoying in the log output. Regarding versions, Bokeh has been under active development but we are closing in on a stable 1.0 release. 
>By version mismatch are you referring to this "ping" issue? Or something else? 

Unrelated.  Just meant to leave off on a positive note
Ok :) appreciate your feedback!

Resolving patch:
diff --git a/bokeh/server/views/ws.py b/bokeh/server/views/ws.py
--- a/bokeh/server/views/ws.py
+++ b/bokeh/server/views/ws.py
@@ -195,9 +195,9 @@ def on_pong(self, data):
         try:
             self.latest_pong = int(codecs.decode(data, 'utf-8'))
         except UnicodeDecodeError:
-            log.error("received invalid unicode in pong %r", data, exc_info=True)
+            log.trace("received invalid unicode in pong %r", data, exc_info=True)
         except ValueError:
-            log.error("received invalid integer in pong %r", data, exc_info=True)
+            log.trace("received invalid integer in pong %r", data, exc_info=True)
 
     @gen.coroutine
     def send_message(self, message):


Test patch: