title: Pinging a remote PC with Flask, causing server to block
body: <p>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.</p>
  
  <p><a href="https://i.stack.imgur.com/FKqRw.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/FKqRw.png" alt="enter image description here"></a></p>
  
  <p>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 <code>-w</code> (yes windows) </p>
  
  <p>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.</p>
  
  <p>Preferably, I would like to have the server <strong>continously</strong> 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. </p>
  
  <p>Any and all advice is welcome, I've never really worked with File Sharing before.</p>
  
  <p>Backend is Python 3.4, Flask &amp; Tornado. </p>
  
  <h2>The Ajax Call</h2>
  
  <pre><code>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");
              }
          }
     );
  }
  </code></pre>
  
  <h2>The Response (Flask route)</h2>
  
  <pre><code>@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'}
  </code></pre>
  
  <p>The ping call takes 18 seconds to resolve, even with -w 1 (or 1000)
  <a href="https://i.stack.imgur.com/iAGDK.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/iAGDK.png" alt="enter image description here"></a></p>
  
  <p>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. </p>
  
  <p>Thanks for reading.</p>
  
  <p>EDIT 1:</p>
  
  <p>Trying to apply the ping_response as native Tornado asynchronous response. Result is the same</p>
  
  <pre><code>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()
  </code></pre>
  
  <p>EDIT 2: Trying to Use Celery. Still blocking.</p>
  
  <pre><code>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
  </code></pre>