草庐IT

python - 用 Python 编写的服务器的强大无限循环

coder 2023-08-13 原文

我写了一个处理事件的服务器,处理事件期间未捕获的异常不能终止服务器。

服务器是单个非线程 python 进程。

我想终止这些错误类型:

  • 键盘中断
  • 内存错误
  • ...

内置异常列表很长:https://docs.python.org/2/library/exceptions.html

我不想重新发明这种异常处理,因为我猜它以前做过几次。

如何进行?

  1. 有一个白名单:一个正常的异常列表,处理下一个事件是正确的选择
  2. 有一个黑名单:一个异常列表,表明终止服务器是正确的选择。

提示:这个问题不是关于在后台运行 unix 守护进程。这与双叉无关,也与重定向标准输入/标准输出无关:-)

最佳答案

我会按照您所想的类似方式执行此操作,使用“您不得通过” Gandalf 异常处理程序 except Exception to catch all non-system-exiting exceptions 同时创建一个列入黑名单的 set 异常,这些异常应该通过并最终被重新引发。

使用 Gandalf 处理程序 将确保 GeneratorExit , SystemExitKeyboardInterrupt (所有系统退出异常)如果调用堆栈中更高层没有其他处理程序,则传递并终止程序。您可以在这里查看 type(e)捕获的异常 e__class__ 实际上属于黑名单异常集,并且重新 raise

作为一个小演示:

import exceptions  # Py2.x only

# dictionary holding {exception_name: exception_class}
excptDict = vars(exceptions)

exceptionNames = ['MemoryError', 'OSError', 'SystemError'] # and others

# set containing black-listed exceptions
blackSet = {excptDict[exception] for exception in exceptionNames}

现在 blackSet = {OSError, SystemError, MemoryError} 包含我们希望处理的非系统退出异常的类。

try-except block 现在看起来像这样:

try:
    # calls that raise exceptions:
except Exception as e:
    if type(e) in blackSet: raise e # re-raise
    # else just handle it

示例,使用 BaseException 捕获所有异常可以帮助说明我的意思。 (这样做仅用于演示目的,以便了解这种加注最终将如何终止您的程序)。 请注意:建议您使用BaseException;我使用它是为了演示什么异常实际上会“通过”并导致终止(即 BaseException 捕获的所有内容):

for i, j in excptDict.iteritems():
    if i.startswith('__'): continue  # __doc__ and other dunders
    try:
        try:
            raise j
        except Exception as ex:
            # print "Handler 'Exception' caught " + str(i)
            if type(ex) in blackSet:
                raise ex           
    except BaseException:
        print "Handler 'BaseException' caught " + str(i)

# prints exceptions that would cause the system to exit     
Handler 'BaseException' caught GeneratorExit
Handler 'BaseException' caught OSError
Handler 'BaseException' caught SystemExit
Handler 'BaseException' caught SystemError
Handler 'BaseException' caught KeyboardInterrupt
Handler 'BaseException' caught MemoryError
Handler 'BaseException' caught BaseException

最后,为了让这个 Python 2/3 不可知,你可以尝试import exceptions,如果失败(在 Python 3 中是这样),则失败-回到进口builtins其中包含所有 Exceptions;我们按名称搜索字典,因此没有区别:

try:
    import exceptions
    excDict = vars(exceptions)
except ImportError:
    import builtins 
    excDict = vars(builtins)

我不知道是否有更聪明的方法来实际执行此操作,另一种解决方案可能不是使用 try-except 和 signle except,有 2处理程序,一个用于黑名单异常,另一个用于一般情况:

try:
    # calls that raise exceptions:
except tuple(blackSet) as be:  # Must go first, of course.
    raise be
except Exception as e:
    # handle the rest

关于python - 用 Python 编写的服务器的强大无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34951110/

有关python - 用 Python 编写的服务器的强大无限循环的更多相关文章

  1. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  2. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  3. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  4. ruby - 树顶语法无限循环 - 2

    我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He

  5. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  6. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  7. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  8. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  9. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  10. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

随机推荐