Cherrypy:我的ajax调用似乎有时被拒绝,而cherrypy函数没有完成

时间:2017-07-04 14:05:13

标签: javascript jquery python ajax cherrypy

我几天后就遇到了问题。

我有一个在firefox(html,jquery)中运行的Web应用程序,业务内容由cherrypy完成(应用程序是本地的,firefox和在同一台机器上运行)。所有这些都在fedora25上运行。 Web应用程序使用jquery ajax在cherrypy上调用函数。

我的应用程序的一个步骤是使用SMART进行HDD诊断。通话时间很长(约1分钟)

On" html"侧:

网络应用执行类似的ajax调用:

$.ajax({'url': 'http://127.0.0.1:8000/launch_hdd_diag?hdd_index=SYSTEM'})
    .done(one_hdd_diag_done)
    .fail(function(jqXHR, textStatus, errorThrown )
          { 
              alert("text status = [" + textStatus + "]\njqXHR.state() = [" + jqXHR.state() + "]");
              log_error("Unexpected error while SYSYTEM hdd diag.");
              one_hdd_diag_done({"status": hdd_diag_result_TECHNICAL_ERROR, "disk_index": "SYSTEM" });
          });

在樱桃一边

简化代码:

@cherrypy.expose
@cherrypy.config(**{'tools.cors.on': True})
@cherrypy.tools.json_in()
@cherrypy.tools.json_out()
def launch_hdd_diag(self, hdd_index):
    device_path = ... # here we get /dev/sda from hdd_index, for instance.
    subprocess.Popen("sudo smartctl --test=short " + device_path, shell=True, stdout=subprocess.PIPE).communicate() # short call
    is_running = True
    while is_running:
        is_running = is_short_test_running(device_name) # we have a short Popen(...).communicate() in that function
        time.sleep(5)
    status = get_test_result(device_name)
    log("finished")
    return {"disk_index": hdd_index, "status": status}

我观察到并无法解释

有时(我不知道...)ajax呼叫在 launch_hdd_diag cherrypy功能完成之前以失败结束。
警报弹出窗口显示:textStatus ="错误"和jqXHR.state()="拒绝"。
我观察到了:

    日志中的
  • :因为log_error("在日志之前记录了意外错误...("已完成")。
  • 在cherrypy调用输出中:我观察到GET请求在完成后由cherrypy记录,我可以在cherrypy记录GET请求结束前3​​0秒看到ajax失败日志。

成功通话和拒绝通话的标题完全相同(firefox开发工具)。

我的问题:

你有一些补偿提示吗?你需要额外的信息吗?你能解释一下吗?

我不再拥有(我尝试了缓存开/关,我尝试了超时,我尝试在控制台中启动cherrypy,在nohup过程中,无需控制台......)
我要改变我的代码,所以ajax查询很简短:我将从Cherrypy转移到web(从jquery方面轮询......),但我对自己的稳健性不太自信这种解决方法,因为我不了解当前的行为。

如果需要,还需要一些其他信息:

以下是我启动cherrypy服务器的方法:

config = {
    'global' : {
        'server.socket_host' : '127.0.0.1',
        'server.socket_port' : 8000,
        'server.thread_pool' : 50,
        'response.timeout'   : 7200,
        'log.error_file'     : "/my/error/log",
    }
}

def cors():
    if cherrypy.request.method == 'OPTIONS':
        # preflign request 
        # see http://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0
        cherrypy.response.headers['Access-Control-Allow-Methods'] = 'POST'
        cherrypy.response.headers['Access-Control-Allow-Headers'] = 'content-type'
        cherrypy.response.headers['Access-Control-Allow-Origin']    = '*'
        # tell CherryPy no avoid normal handler
        return True
    else:
        cherrypy.response.headers['Access-Control-Allow-Origin'] = '*'

cherrypy.tools.cors = cherrypy._cptools.HandlerTool(cors)

if __name__ == '__main__':
    cherrypy.quickstart(App(), '/', config)

非常感谢您的帮助。

0 个答案:

没有答案