草庐IT

google-app-engine - 在 Google App Engine 上从 main.go 传递出去时上下文值发生变化

coder 2024-07-06 原文

有一个问题,当我将 context.Context 传递给 Google App Engine 上的另一个包后,我不知道为什么会发生更改。

以下代码在 App Engine 上运行时运行良好:

package main

import (
    "net/http"
    "log"

    "google.golang.org/appengine"
)

func main() {
    http.HandleFunc("/", myHandler)

    appengine.Main()
}

func myHandler(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()
    account, err := appengine.ServiceAccount(ctx)
    if err != nil {
        log.Println("[myHandler] error:", err)
    } else {
        log.Println("[myHandler] ServiceAccount:", account)
    }   

    w.Write([]byte("ok"))
}

我在访问/时成功获取到ServiceAccount,一切正常。

但是,当我将上下文从 main.go 传递到另一个包时,函数调用不起作用。以下内容已添加到 main.go:

import (
    // other stuff
    "github.com/adlerhsieh/q_context/handlers"
)

func main() {
    http.HandleFunc("/", myHandler)

    appengine.Main()
}

func myHandler(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()
    account, err := appengine.ServiceAccount(ctx)
    if err != nil {
        log.Println("[myHandler] error:", err)
    } else {
        log.Println("[myHandler] ServiceAccount:", account)
    }   

    handlers.AnotherFunc(ctx) // <--- added this

    w.Write([]byte("ok"))
}

另一个包:

package handlers

import (
    "log"
    "context"

    "google.golang.org/appengine"
)

func AnotherFunc(ctx context.Context) {
    account, err := appengine.ServiceAccount(ctx)
    if err != nil {
        log.Println("[AnotherFunc] error:", err)
    } else {
        log.Println("[AnotherFunc] ServiceAccount:", account)
    }
}

当我在 App Engine 上运行它时,日志显示:

2019/09/04 09:36:30 [myHandler] ServiceAccount: myaccount@gmail.com
2019/09/04 09:36:30 [AnotherFunc] error: not an App Engine context

函数调用是相同的,只是在不同的包中。我深入研究了包本身,发现它使用了 key here (导致 here )来设置上下文。和 here检查该值是否设置正确。但是,该值似乎已被修改/更改,因此第二个函数调用无法获取它。即使我省略了第一个函数调用并直接进入第二个,它仍然有同样的错误。

知道为什么上下文对象在传递给另一个包时被修改了吗?

以下是我的app.yaml:

runtime: go111
service: default
instance_class: F1
automatic_scaling:
  min_idle_instances: 0
  max_idle_instances: automatic
  min_pending_latency: automatic
  max_pending_latency: automatic
  max_concurrent_requests: 30

handlers:
- url: /.*
  script: auto
  login: admin

nobuild_files:
- vendor

env_variables:
  ENV: 'dev'
  GO111MODULE: 'off'

Here is the GitHub repo link .

谢谢!

最佳答案

事实证明,我的代码确实有效。这是因为其他一些操作错误。

但是,我只会发布实际导致它的问题,以便帮助那些有同样问题的人。

使用新的 go111 运行时,它将来自非根目录或其子目录的包视为不同类型的包。这导致了“不是 App Engine 上下文”的问题。我暂时将其称为“弃儿”包(因为我不完全确定为什么会这样)。

例如:

- appengine
  - main.go
  - handlers
    - handlers.go <-- this is a regular package
- appengine
  - main.go
- handlers
  - handlers.go < -- this is an outcast package

如我的问题中所指出的,被抛弃的包在处理从 App Engine 生成的 context.Context 时会遇到问题。

App Engine 知道上下文是从 App Engine 创建的机制正在使用只能从其内部包中检索的内置值(使用未导出的指针字符串键)。将上下文传递给 outcast 包时,我们无法再从上下文中检索值。值消失的原因对我来说仍然是个谜,但这可能是因为某种 Go 编译机制。

解决方案是将 main.go 移动到项目的顶层目录,这样就不会在任何地方出现 outcast 包。

关于google-app-engine - 在 Google App Engine 上从 main.go 传递出去时上下文值发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57785973/

有关google-app-engine - 在 Google App Engine 上从 main.go 传递出去时上下文值发生变化的更多相关文章

  1. 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("

  2. ruby-on-rails - 每次我尝试部署时,我都会得到 - (gcloud.preview.app.deploy) 错误响应 : [4] DEADLINE_EXCEEDED - 2

    我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie

  3. ruby-on-rails - 如何重命名或移动 Rails 的 README_FOR_APP - 2

    当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?

  4. ruby - rails 3 redirect_to 将参数传递给命名路由 - 2

    我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use

  5. ruby-on-rails - 如何生成传递一些自定义参数的 `link_to` URL? - 2

    我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些

  6. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  7. ruby - 使用 postgres.app 在 rvm 下要求 pg 时出错 - 2

    我正在使用Postgres.app在OSX(10.8.3)上。我已经修改了我的PATH,以便应用程序的bin文件夹位于所有其他文件夹之前。Rammy:~phrogz$whichpg_config/Applications/Postgres.app/Contents/MacOS/bin/pg_config我已经安装了rvm并且可以毫无错误地安装pggem,但是当我需要它时我得到一个错误:Rammy:~phrogz$gem-v1.8.25Rammy:~phrogz$geminstallpgFetching:pg-0.15.1.gem(100%)Buildingnativeextension

  8. ruby - 如何将 Puma::Configuration 传递给 Sinatra? - 2

    这是我的网络应用:classFront我是这样开始的(请不要建议使用Rack):Front.start!这是我的Puma配置对象,我不知道如何传递给它:require'puma/configuration'Puma::Configuration.new({log_requests:true,debug:true})说真的,怎么样? 最佳答案 配置与您运行的方式紧密相关puma服务器。运行的标准方式puma-pumaCLI命令。为了配置puma配置文件config/puma.rb或config/puma/.rb应该提供(参见examp

  9. jquery - 如何将 AJAX 变量从 jQuery 传递到他们的 Controller ? - 2

    我有一个电子邮件表格。但是我正在制作一个测试电子邮件表单,用户可以在其中添加一个唯一的电子邮件,并让电子邮件测试将其发送到该特定电子邮件。为了简单起见,我决定让测试电子邮件通过ajax执行,并将整个内容粘贴到另一个电子邮件表单中。我不知道如何将变量从我的HAML发送到我的Controllernew.html.haml-form_tagadmin_email_blast_pathdoSubject%br=text_field_tag'subject',:class=>"mass_email_subject"%brBody%br=text_area_tag'message','',:nam

  10. ruby - 如何将 lambda 传递给 Hash.each? - 2

    如何将lambda传递给hash.each,以便我可以重复使用一些代码?>h={a:'b'}>h.eachdo|key,value|end=>{:a=>"b"}>test=lambdado|key,value|puts"#{key}=#{value}"end>test.call('a','b')a=b>h.each&testArgumentError:wrongnumberofarguments(1for2)from(irb):1:in`blockinirb_binding'from(irb):5:in`each'from(irb):5from/Users/jstillwell/.rv

随机推荐