I have an internal website, which is required to have file sharing links which are direct links to a shared location on the pc that the table row represents.
When accessing the links, I would like to first test if the remote pc is available, in the quickest possible fashion. I thought this would be a ping, but for some reason, timeout does not work with -w
(yes windows)
This is not allowed to take time, for some reason, it causes the web server to block on ping, even though I am using Tornado to serve Flask routes asynchronously.
Preferably, I would like to have the server continously updating the front end, with active/deactive links, allowing users to only access links with pc's online, and restrict them elsehow. Possibly even maintaining the value in a database.
Any and all advice is welcome, I've never really worked with File Sharing before.
Backend is Python 3.4, Flask & Tornado.
function is_drive_online2(sender){
hostname = sender.parentNode.parentNode.id;
$.get('Media/test',{
drive: hostname
},
function(returnedData){
console.log(returnedData[hostname]);
if(returnedData[hostname] == 0){
open("file://"+hostname+"/MMUsers");
}else{
alert("Server Offline");
}
}
);
}
@app.route('/Media/test', methods=['GET', 'POST'])
def ping_response():
before = datetime.datetime.now()
my_dict = dict()
drive = request.args.get('drive')
print(drive)
response = os.system("ping -n 1 -w 1 " + drive)
my_dict[drive] = response
after = datetime.datetime.now()
print(after-before)
return json.dumps(my_dict), 200, {'Content-Type': 'application/json'}
The ping call takes 18 seconds to resolve, even with -w 1 (or 1000)
I only need to support Internet Explorer 11. Is this even a plausible scenario? Are there hardware limitations to something like this Should the server have a long thread whose sole task is to continuously update active/deactivate links? I am not sure the best approach.
Thanks for reading.
EDIT 1:
Trying to apply the ping_response as native Tornado asynchronous response. Result is the same
class PingHandler(RequestHandler):
@asynchronous
def get(self):
dr = self.get_argument('drive')
print(dr)
b = datetime.datetime.now()
myreturn = {self.get_argument('drive'):
os.system("ping -n 1 -w 1 " + self.get_argument('drive'))}
a = datetime.datetime.now()
print(a-b)
self.write(myreturn)
wsgi = WSGIContainer(app)
application = Application([(r"/Media/test", PingHandler),
(r".*", FallbackHandler, dict(fallback=wsgi))])
application.listen(8080)
IOLoop.instance().start()
EDIT 2: Trying to Use Celery. Still blocking.
def make_celery(app):
celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
celery.conf.update(app.config)
TaskBase = celery.Task
class ContextTask(TaskBase):
abstract = True
def __call__(self, *args, **kwargs):
with app.app_context():
return TaskBase.__call__(self, *args, **kwargs)
celery.Task = ContextTask
return celery
celery = make_celery(app)
@celery.task
def ping(drive):
"""
Background Task to test is computer is online
:param drive: The drive name to test
:return: Non Zero status code for Offline boxes.
"""
response = os.system("ping -n 1 -w 1 " + drive)
return json.dumps({drive: response}), 200, {'Content-Type': 'application/json'}
@app.route('/Media/test', methods=['GET', 'POST'])
def ping_response():
before = datetime.datetime.now()
my_dict = dict()
drive = request.args.get('drive')
print(drive)
this_drive = temp_session.query(Drive).filter(Drive.name == drive).first()
address = this_drive.computer.ip_address if this_drive.computer.ip_address else this_drive.name
response = ping.apply_async(args=[address])
return response
Tornado isn't serving your Flask app asynchronously (that's impossible: asynchronousness is a property of the interface and ping_response
is a synchronous function). Tornado's WSGIContainer
is a poor fit for what you're trying to do (see the warning in its docs)
You should either use Flask with a multi-threaded server like gunicorn or uwsgi, or use native Tornado asynchronous RequestHandlers
.