Heroku: Get localhost net::ERR_CONNECTION_REFUSED when app deployed - multithreading

I am running a app.py which has two threads, one for the dash app, and the other for HTTPServer.
app = dash.Dash(__name__)
app.layout = html.Div( ... )
#app.callback( ... )
def do_something( ... ): ...
if __name__ == '__main__':
httpd = HTTPServer(('localhost', 8000), SimpleHTTPRequestHandler)
t1 = threading.Thread(target=httpd.serve_forever)
t2 = threading.Thread(target=app.run_server, kwargs={'debug': False})
t1.start()
t2.start()
The reason to run HTTPServer is to retrieve local files with url 'localhost:8000/audios/%s.wav' % clicked_index, and use the url as the src for html.Audio. Particularly, I have .wav files in local audios/, and callback enables hover and triggers audio playback.
It runs without a problem locally with python app.py, but it does not on the deployed app - the hover only triggers part of the audios. In the screenshot, the data point with the hovered info Piano correctly play the audio, but we can see ERR_CONNECTION_REFUSED for other 'localhost:8000/audios/%s.wav' % clicked_index in the right bottom which don't play audio. This doesn't happen locally.
When I check the files with heroku run bash --app myapp, all wav files are there in the audios/.
And if I run python -m http.server 8000 locally, the deployed app runs without problem; no missing audio playback.
I appreciate anyone who enlightens me in this subject which I just started.

According to https://devcenter.heroku.com/articles/s3, Heroku seems to be unable to host static files, and the s3 public bucket satisfies my need.

Related

node js server deployment on heroku

we are working on a video call application, we used nodejs and socket io for the server. We have arrived at the deployment phase. When deploying the server on heroku it displays Build succeeded but when I launch the link or I click on open app leads to a white page where is written :
Cannot GET /
Any help please
I tried to replace the port process.env.SOCKET_BACKEND_URL || "http://localhost:5000"
bye by the link given while deployment:
process.env.SOCKET_BACKEND_URL ||"https://appname.herokuapp.com/"

paths for deploying flask/wsgi differ from development

I am developing an app and the development setup was really easy.
I run it locally with:
$ . .venv/bin/activate
(.venv) $
(.venv) $ python -m flask run
* Serving Flask app 'app'
* Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:8080
Press CTRL+C to quit
* Restarting with stat
* Debugger is active!
* Debugger PIN: -###-###
and I have configured apache2 on my (ubuntu) laptop with:
ProxyPass / http://127.0.0.1:8080
My code is structured like:
app.py
pages/scc_main/scc.html
...
The code has this:
import re
import jinja2
from flask import Flask
from flask import request
import data
app = Flask(__name__)
env = jinja2.Environment(loader=jinja2.FileSystemLoader("pages"))
#app.route('/')
def hello_world():
return '<h2>Hello, World!</h2>'
#app.route('/contracts/scc')
#app.route('/contracts/scc/')
def contracts_main():
main = env.get_template('scc_main/scc.html')
context = data.build('scc_main')
return main.render(**context)
And everything works great. As in:
$ curl 'http://localhost/'
<h2>Hello, World!</h2>$
But when I deploy. Wow. I set my site's root to point to the app. That is actually working. I can hit https://opencalaccess.org/ and it gets my static content.
I have:
import sys
import logging
logging.basicConfig(
level=logging.DEBUG,
filename='/var/www/<full-path>/logs/contracts_scc.log',
format='^(asctime)s %(message)s')
sys.path.insert(0, '/var/www/<full-path>')
sys.path.insert(0, '/var/www/<full-path>/.venv/lib/python3.8/site-packages')
And https://opencalaccess.org/contracts/scc works. But only after I change the Environment call above to:
env = jinja2.Environment(loader=jinja2.FileSystemLoader("/var/www/full-path>/pages"))
Now, any link which is just a link is fine. But anything that looks at the flask.request.path gives me:
The browser (or proxy) sent a request that this server could not understand.
What the heck? Setting up the dev environment was so easy. What do you have to do to get this working in deployment? Any suggestions?
ADDED:
Well, it seems clear that it is the WSGI part that is having the problem. My script is not receiving the request structure and so it cannot read any parameters. I have all my parameters on the URL, so my data building method reads the request.path to see what to do.
So, where to go from here. We will see.
I am no longer able to reproduce this.

Pycharm does not reload the changes I make to the Flask project (yes I have tried all previous StackOverflow suggestions)

This seems like a problem a lot of folks have.
I completely changed my index.html page. Then saved changes, stopped and re-ran server.py which has the following code:
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def home():
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True)
I have saved changes, stopped and re-run flask from terminal using >> set FLASK_APP=server.py >> flask run.
I have also tried clearing browser cache and retried on multiple browsers. I have tried shift+reload
Previously it used to work on completely closing Pycharm and restarting. However even that isn't working anymore.
Apart from displaying text that no longer exists in index.html, the Debugger Console is also showing the following error:
127.0.0.1 - - [22/Jul/2021 17:29:58] "GET /favicon.ico HTTP/1.1" 404 -
My pointer to the file location is correct:
But just to make sure I copy pasted favicon.ico in every damn folder in the project.
I have tried "save all" on my project several times. Stopped and started debugger several times. Any other solution I left out?

child_process.fork not starting an express server inside of packaged electron app

I have an electron app where I need not only to run the interface to the user but also start an express server that will serve files for people connected through the network.
I have everything working if I start both electron and the express server normally, but I'm pretty confident that I will need the server running in a different thread to avoid slugish interface and even problems with the server.
For that matter I tried to run my express server using the child_process.fork and it worked when I use npm start, but when I use electron-builder to create an .exe, the installed program doesn't start the express server.
I tried to run my server right away using:
require('child_process').fork('app/server/mainServer.js')
I tried several changes, prefixing the file with __dirname, process.resourcesPath and even hard coding the generated file path; changing the fork options to pass cwd: __dirname, detached: true and stdio: 'ignore'; and even tried using spawn with process.execPath, which will also work with npm start but won't when packaged (it keeps opening new instances of my app, seems obvious after you do hehe)
Note: If I don't fork and require the server script right away, using require('server/mainServer.js') it works on the packaged app, so the problem most like isn't the express itself.
Note 2: I have asar: false to solve other problems, so this is not the problem solver here.
I put up a small git project to show my problem:
https://github.com/victorivens05/electron-fork-error
Any help will be highly appreciated.
With the great help from Samuel Attard (https://github.com/MarshallOfSound) I was able to solve the problem (he solved for me actually)
As he said:
the default electron app will launch the first file path provided to it
so `electron path/to/thing` will work
in a packaged state, that launch logic is not present
it will always run the app you have packaged regardless of the CLI args passed to it
you need to handle the argument manually yourself
and launch that JS file if it's passed in as the 1st argument
The first argument to fork simply calls `process.execPath` with the first
argument being the path provided afaik
The issue is that when packaged Electron apps don't automatically run the
path provided to them
they run the app that is packaged within them
In other words. fork is actually spawn being executed with process.execPath and passing the fork's first argument as the second for spawn.
What happens in a packaged app is that the process.execPath isn't electron but the packaged app itself. So if you try to spawn, the app will be open over and over again.
So, what Samuel suggest was implemented like this:
if (process.argv[1] === '--start-server') {
require('./server/mainServer.js')
return
}
require('./local/mainLocal.js')
require('child_process').spawn(process.execPath, ['--start-server'])
That way, the first time the packaged app will be executed, the process.argv[1] will be empty, so the server won't start. It will then execute the electron part (mainLocal in my case) and start the app over, but this time passing the argv. Next time the app starts, it will start the server and stop the execution, so the app won't open again because spawn is never reached.
Huge thanks to Samuel.

Having trouble running Phantomjs + node on Heroku

I've successfully got Phantomjs to work on Heroku but now I'm hitting issues with the phantomjs-node interface for node.js (see https://github.com/sgentle/phantomjs-node).
When I'm attempting to initialize Phantom I'm seeing a 10-15 second delay and then:
> phantom stdout: ReferenceError: Can't find variable: socket
phantom stdout: phantomjs://webpage.evaluate():1
phantomjs://webpage.evaluate():1
phantomjs://webpage.evaluate():1
You can reproduce the problem with the following steps or by pulling down my test app at https://github.com/matellis/phantom-test
git init phantom-test
cd phantom-test
heroku apps:create
# create node app as per Heroku instructions here https://devcenter.heroku.com/articles/nodejs
# copy bin and lib folders from http://phantomjs.googlecode.com/files/phantomjs-1.6.1-linux-x86_64-dynamic.tar.bz2 into root of your new project
# if you don't do this step you'll get an error "phantom stderr: execvp(): No such file or directory"
git add .
git commit -m "init"
git push heroku
Test your app has come up, the third to last line will tell you the URL, it should read like:
http://fathomless-ravine-5563.herokuapp.com deployed to Heroku
If successful you should see Hello World! in your browser.
Now from the same folder as your Heroku application run:
heroku run node
At the node prompt try the following:
phantom = require('phantom');
x = phantom.create();
Wait 10-15 seconds and you should see the error. Nothing works from this point on.
This should output file foo.png:
x = phantom.create(function(ph){ph.createPage(function(page){ page.open('http://bbcnews.com', function(status){ page.render('foo.png', function(result) {ph.exit()}); }); }); });
To validate Phantomjs is working fine on Heroku, try the following using my test project:
>heroku run bash
Running `bash` attached to terminal... up, run.1
~ $ phantomjs test.js http://bbcnews.com foo.png
~ $ ls *.png
foo.png
I cannot reproduce any of these problems locally but there are other issues reported where folks may have hit this issue locally.
The problem seems to originate in shim.js line 1637:
s.on('request', function(req) {
var evil;
evil = "function(){socket.emit('message', " + (JSON.stringify(JSON.stringify(req))) + " + '\\n');}";
return controlPage.evaluate(evil);
});
I've tried variations of versions of node, phantom, etc. with no luck.
I've also tried a custom buildpack that sets the DYLD variable, see http://github.com/tecnh/heroku-buildpack-nodejs with no luck either.
Anyone who has got Phantom + Node playing together nicely on Heroku please let me know. There are several references to this on Stackoverflow but nobody is saying "I got it to work, here's how".
I've never used the phantomjs node module, but I do have an app running both node and phantomjs on Heroku.
You need to use custom buildpacks in order to get this to work. My .buildpacks file looks like
http://github.com/heroku/heroku-buildpack-nodejs.git
http://github.com/stomita/heroku-buildpack-phantomjs.git
You should then be able to run phantomjs scripts in a child process:
var script = app.get('root') + '/scripts/rasterize.js' //the phantomjs script to run
, bin = app.get('phantom') //normally this would just be the string "phantomjs"
, spawn = require('child_process').spawn;
// set up args to the phantom cli
// (run the phantomjs command in your terminal to see options/format)
var args = [];
// ...
var phntm = spawn(bin, args);
phntm.stdout.on('data', function (data) { /* do something */ });
phntm.stderr.on('data', function (data) { /* do something */ });
phntm.on('exit', function (code) { /* handle exit */ });
Heroku does not support WebSockets. With Socket.io it has a workaround. Not sure about dnode, which phantomjs-node uses.
I had a problem with WebSockets on Heroku too and I switched to Nodejitsu, which solved it for me.

Resources