Deploy Bokeh Server into production on IP address

It works for multiple users, but when loading for another user (which takes about 4-5 minutes in this case), callbacks no longer work. Plus the template doesn’t load.

@alexgrossman

To clarify, the flask_waitress_embed.py example I posted takes 4-5 minutes to load or your app derived from that does? The example I posted loads fairly quickly even on a cellphone (a few seconds) and does respond to callbacks over WiFi with a smallish lag on the phone.

I can rollback to bokeh 2.0.2 in another environment to check, but I cannot (easily) run a server under Windows.

My app derived from that. It’s the exact same outside of the bkapp function

Does the reference waitress example now work on your setup or are there issues with the template rendering there too? That’s all I can really run for comparison / testing purposes.

Once that works, the next step is to pare down your code or build up incrementally from that example within the bk_app function to see what causes breakages or very unresponsive behavior.

With the waitress example you posted I get the same error of:

RuntimeError: There is no current event loop in thread ‘Thread-1’.

I’m using Tornado 6.0.3 by the way with Bokeh 2.0.2

Could downgrading Tornado fix the issue or could that mess up what’s being output by Bokeh?

I wouldn’t go that route. First, I’m not sure that’s a problem with that per se and second, Bokeh’s release notes have specific requirements for Tornado > 5.0/5.1 for releases 2.0/2.1, respectively.

Do you have any other suggestions? Sorry for being annoying, I just spent a month building a bokeh app that doesn’t work for multiple users at once so pretty stressed about this not working no matter what I try

Also, if the application was smaller, I believe the Flask app would work. it doesn’t seem to work because since it takes 5 mins to load. The one thread can only load one user at once. We then see one user taking 10 mins to load and by the time that even happens, the user gets bounced out because the bokeh Token expires. (Plus I need the multiple threads so that it doesn’t take 30 minutes when it is 6 users, which is realistically the most that would likely ever be on this tool)

1 Like

It is certainly not annoying, so don’t worry about that.

Stressful, I get it. Deep breaths. :slight_smile:

We know it works in principle with waitress, we just need to figure out if its due to the OS where you’re running the server, package versions, etc. And, for what it’s worth, I have a fairly complex self-hosted bokeh app of my own so there is no fundamental problem jumping from the illustrative examples to real scientific or visualization problems.

If you have the ability to set up a separate Python virtual environment with the latest versions of everything, you could try that to see if the waitress example works there. If not, it seems like the only difference from your setup and mine is the OS.

I’d also look seriously into profiling where things are taking so long in the startup. If it’s computations on the server is there anything that can be done to streamline? If it is pushing complex layouts or models or whatever to the client that’s another thing to investigate.

The problem is that, in production, I can’t use a newer version of bokeh because I ran into issues as in Select options update - #19 by _jm

I also don’t have the ability to set up a new virtual environment that easily because of corporate restrictions. And I can’t really speed it up that much, it’s pulling in and manipulating a couple of Gigs of data which is what makes it slow - I already have different runs for twice a day that do a lot of pre-computations to make these runs as fast as possible.

I’m not too worried about converting the simple example into my own app, I’m just worried about getting this simple example working.

Understood. I was just suggesting this as a temporary step to isolate if the problem is due to package versions or something more fundamental like running on Windows versus Linux (or OS X).

I understand, I just would have to upgrade and then downgrade again and if it was to work, I would just be in a terrible spot anyways because I’d be stuck between picking between two versions, each of which has issues for what I need to do.

That’s why I was looking at this:

But if I was to downgrade then bokeh would no longer work so really unsure about what to do here.

@Bryan I was wondering if you have any suggestions? I saw this thread (Tornado 5.0 compatibility · Issue #7308 · bokeh/bokeh · GitHub), unsure if this still applies here or is relevant. To summarize, the flask_gunicorn_embed.py example doesn’t work on Windows, even when using waitress instead of gunicorn as I get the issue:

RuntimeError: There is no current event loop in thread ‘Thread-1’.

This seems to have been addressed in bokeh in early 2018. See https://github.com/bokeh/bokeh/pull/7329.

And bokeh 2.0.2 that you’re using is circa Q1/Q2 2020.

For what it is worth, I have been working heavily in 2.0.2 for most of my development, which involves a lot of server deployment for multiple users. But, unfortunately, I’m doing everything in Linux and sometimes OS X.

Got it. I would of course just use multiple processes on the simple flask app but since I’m on windows I can’t. I can’t really upgrade or downgrade Bokeh as I said so I’m kind of stuck. I tried using asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
as well with the example but it didn’t work either.

@alexgrossman

A poor-man’s short-term solution might be to run your flask app six times, for example, with each set up for a separate port. Then you’ll have to do the bookkeeping/management of having your users only log in to their assigned port to avoid collisions. Would that work, albeit inelegantly, until you can investigate further?

So unfortunately I have zero experience with waitress (this is the first I’ve heard of it) and not much experience with Windows either. I’ve been variously asking the community for years if anyone would like to join the project to help anchor support on Windows but to date, no one has wanted to do that.

It’s hard to make specific suggestions without knowing what your actual constraints. E.g. can you run multiple instances of the server app on different ports, and then put them behind an Nginx load balancer so that all users see one URL?

I also don’t really have context for the statements about 5, 10 minutes to load. Are you doing 10 minutes of blocking work on every session creation? Can anything be done once up front e.g in a server lifecycle hook for server start?

I think so, definitely not permanently of course, but I do get the following error when trying to do so (when using same IP but different port):

OSError: [WinError 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted