草庐IT

go - HTTP.Server 关闭导致运行时错误

coder 2024-07-12 原文

我有一个在 darwin/amd64 上用 Go 1.9.2 编写的 goroutine,它会导致运行时错误:无效的内存地址或 nil 指针取消引用。我认为这是因为某种与例程退出顺序相关的竞争条件,但我不确定。

主应用程序正在做几件事,所以我将网络服务器作为 goroutine 启动,然后监听来自父进程的退出信号并尝试在返回之前彻底关闭所有内容。

函数如下:

// WebServer defines the handler endpoints and launches the web server listener
func WebServer(wg *sync.WaitGroup) {

    // Make sure the exit is noted
    defer wg.Done()

    // Endpoint, handler function
    http.HandleFunc("/version", WebShowVersion)

    // Go forth and serve
    // Define the server struct
    srv := &http.Server{Addr: ":8080"}

    // Now go serve
    chnToLogger <- "Launching web server on port 8080"
    go func() {
        err := srv.ListenAndServe()
        if err != nil &&
            err.Error() != "http: Server closed" {

            // There...was an error
            chnToLoggerError <- "Error launching web server: " + err.Error()
        }
    }()

    // Listen for a shutdown
    for {
        select {
        case <-chnQuitNow:

            // Shut down the process
            chnToLogger <- "Shutting down web server process"
            if err := srv.Shutdown(nil); err != nil {

                // There was a problem shutting down gracefully
                chnToLoggerError <- "Error shutting down web server: " + err.Error()
                return
            }

            // Done
            chnToLogger <- "Web server has shut down now"
            return

        default:
            continue
        }
    }

    // Done
    return
}

panic 状态:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x28 pc=0x11f7e61]

goroutine 10 [running]:
net/http.(*Server).Shutdown(0xc420158000, 0x0, 0x0, 0x0, 0x0)
    /usr/local/go/src/net/http/server.go:2506 +0x1b1
main.WebServer(0xc4200164a0)
    /Users/me/go/src/testproj/webhandling.go:45 +0x146
created by main.main
    /Users/me/go/src/testproj/main.go:94 +0x3d6

webhandling.go中第45行是:

if err := srv.Shutdown(nil); err != nil {

虽然它的触发并不一致,但它似乎只有在我启动程序并使用 Web 客户端多次拉取 localhost:8080/version 时才会发生,这让我想知道 srv.Shutdown(nil) 是否是试图关闭具有引用但已经退出的连接?

1) 是否有可能让服务器在从 goroutine 返回之前安全和完全地关闭 web 服务器进程?

2) 是什么导致触发不一致的运行时错误?

最佳答案

切勿使用 nil 上下文。使用 context.Background()context.TODO() .

关于go - HTTP.Server 关闭导致运行时错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47394452/

有关go - HTTP.Server 关闭导致运行时错误的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  3. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  4. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  5. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  6. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  7. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

  8. ruby-on-rails - 迷你测试错误 : "NameError: uninitialized constant" - 2

    我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test

  9. ruby-on-rails - 如何在 Rails View 上显示错误消息? - 2

    我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c

  10. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

随机推荐