- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我对 go http 包进行了一些实验。
看下面的代码片段,一个非常简单的http服务器:
package main
import (
"fmt"
"github.com/codegangsta/negroni"
"github.com/gorilla/mux"
"net/http"
//"time"
)
type controller struct {
request *http.Request
response http.ResponseWriter
}
func (self *controller) send() {
fmt.Fprintf(self.response, "Request %p and Response %p \n", self.request, self.response)
}
func (self *controller) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
fmt.Println("Start controller")
self.request = r
self.response = rw
self.send()
}
func main() {
router := mux.NewRouter()
router.Handle("/", &controller{})
n := negroni.Classic()
n.UseHandler(router)
n.Run(":3000")
}
然后我向服务器发出 20 次请求:
package main
import (
"fmt"
"io"
"net/http"
"runtime"
"time"
)
func main() {
buffer := make([]byte, 100)
runtime.GOMAXPROCS(runtime.NumCPU())
for i := 0; i < 20; i++ {
go func(z int) {
//fmt.Println("Request goroutine 1 ", z)
resp, err := http.Get("http://127.0.0.1:3000")
if err != nil {
fmt.Println(err)
}
io.ReadFull(resp.Body, buffer)
fmt.Println(string(buffer))
}(i)
}
time.Sleep(time.Second * 5)
}
我收到了以下回复:
Request 0xc0820201a0 and Response 0xc082007100
Request 0xc082021380 and Response 0xc0820072c0
Request 0xc0820204e0 and Response 0xc082007740
Request 0xc082020dd0 and Response 0xc0820071c0
Request 0xc082020d00 and Response 0xc082007240
Request 0xc082021450 and Response 0xc082007400
Request 0xc082020f70 and Response 0xc082007500
Request 0xc082021110 and Response 0xc082007480
Request 0xc0820212b0 and Response 0xc082007540
Request 0xc082020b60 and Response 0xc0820075c0
Request 0xc082020750 and Response 0xc082007640
Request 0xc082020270 and Response 0xc0820076c0
Request 0xc082020c30 and Response 0xc082007840
Request 0xc082020820 and Response 0xc0820078c0
Request 0xc082020ea0 and Response 0xc082007940
Request 0xc0820211e0 and Response 0xc0820079c0
Request 0xc082021520 and Response 0xc082007a40
Request 0xc0820209c0 and Response 0xc082007ac0
Request 0xc082021040 and Response 0xc082007380
Request 0xc082020a90 and Response 0xc0820077c0
如您所见,一切正常。每个请求和响应都有不同的存储地址。
所以如果我将 http 服务器更改为:
package main
import (
"fmt"
"github.com/codegangsta/negroni"
"github.com/gorilla/mux"
"net/http"
"time"
)
type controller struct {
request *http.Request
response http.ResponseWriter
counter int
}
func (self *controller) get() {
self.counter++
if self.counter == 7 {
time.Sleep(time.Second * 4)
}
fmt.Printf("Request %p and Response %p \n", self.request, self.response)
}
func (self *controller) send() {
fmt.Fprintf(self.response, "Request %p and Response %p \n", self.request, self.response)
}
func (self *controller) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
fmt.Println("Start controller")
self.request = r
self.response = rw
self.get()
self.send()
}
func main() {
router := mux.NewRouter()
router.Handle("/", &controller{})
n := negroni.Classic()
n.UseHandler(router)
n.Run(":3000")
}
正如您在这里看到的,我添加了方法 get,当计数器达到数字 7 时,它将休眠 4 秒。
func (self *controller) get() {
self.counter++
if self.counter == 7 {
time.Sleep(time.Second * 4)
}
fmt.Printf("Request %p and Response %p \n", self.request, self.response)
}
作为输出我有
Request 0xc082021040 and Response 0xc082007100
Request 0xc0820209c0 and Response 0xc082007240
Request 0xc0820211e0 and Response 0xc082007380
Request 0xc082020270 and Response 0xc082007500
Request 0xc082020d00 and Response 0xc082007640
Request 0xc082020f70 and Response 0xc082007740
Request 0xc082020680 and Response 0xc082007840
Request 0xc082020820 and Response 0xc082007940
Request 0xc082020b60 and Response 0xc082007a40
Request 0xc082021380 and Response 0xc0820071c0
Request 0xc082021110 and Response 0xc0820072c0
Request 0xc0820208f0 and Response 0xc082007400
Request 0xc082020a90 and Response 0xc082007540
Request 0xc082020340 and Response 0xc0820076c0
Request 0xc082020750 and Response 0xc0820075c0
Request 0xc082020dd0 and Response 0xc0820077c0
Request 0xc0820212b0 and Response 0xc0820078c0
Request 0xc0820201a0 and Response 0xc0820079c0
Request 0xc082020ea0 and Response 0xc082007ac0
Request 0xc082020ea0 and Response 0xc082007ac0
可以看到最后两行的地址是一样的,也就是说request 7会覆盖request和response的地址,因为response是delay的。
我的问题是,当一个请求必须处理密集的计算时,例如调整图像大小,并且在调整大小期间另一个请求进来,来自图像调整大小过程的请求和响应将像上面那样被覆盖。然后响应将转到最后请求的客户端。在我看来,这是错误的,对吧?
我知道为每个请求创建一个新的 goroutine。
最佳答案
您正在引入数据竞赛:
router.Handle("/", &controller{})
如您所见,controller
类型只有一个实例。
self.request = r
self.response = rw
在这里你正在修改你的结构。但是 ServeHTTP()
方法会被多个 goroutines 调用。
一个选项是像这样创建一个处理程序
router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
c := &controller{request: r, response: w)
c.send()
...
})
如果您使用 -race
标志运行您的代码,它会警告您这一点。另见 http://blog.golang.org/race-detector
另一件事:不要给你的接收者命名self
。这不是惯用语。它使您的代码不可读。什么是 self
?给它一个合适的名字。
关于go - Request 和 ResponseWriter 将被覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27153811/
这两个句子有什么区别: res = requests.request('POST', url) 和 res = requests.request.post(url) 最佳答案 它们几乎是一样的:htt
我正在使用“请求对话框”来创建 Facebook 请求。为了让用户收到请求,我需要使用图形 API 访问 Request 对象。我已经尝试了大多数看起来合适的权限设置(read_requests 和
urllib.request和http.client都是python标准库。前者相关方法的文档是 here后者,here (我使用的是3.5) 有谁知道为什么标准库中有两种方法看起来做同样的事情,或者
我是 Twisted 的新手,我不明白为什么在运行我的脚本时会出现此错误。\ 基本上,该脚本由 2 个页面组成,第一个页面是一个 HTML 表单,它调用自身执行一个阻塞方法并显示结果。当请求同时发送到
我有一个客户端 JS 文件,其中包含: agent = require('superagent'); request = agent.get(url); 然后我有类似的东西 request.get(u
提前输入功能可以正常工作。但问题是,提前输入功能会在每个数据请求上发出 JSON 请求,而实际上只应针对一个特定请求发生。 我有以下 Controller : #controllers/agencie
我正在使用 Rust 开发一个小型 API,我不确定如何在两个地方访问来自 Iron 的 Request。 Authentication 中间件为 token 读取一次Request,如果路径被允许(
问题起因 今天一位网友向我们反馈,用Chrome打开某些博客文章时,会出现"Bad Request - Request Too Long. HTTP Error 400. The siz
当我从 LinkedIn 向 https://api.linkedin.com/uas/oauth/requestToken 请求请求 token 时,出现以下错误: oauth_problem=si
我只是想使用 okhttp 下载一些字节数据,但在我完成代码之前,我遇到了一个问题,android studio 报告了一个错误,说“Request(okhttp3.Request.Builder)
我正在使用 Windows 10。我想在我的系统上使用 Angular 4。当我运行 node -v 和 npm -v 时,它会显示版本。但是当我执行语句 npm install -g @angula
我正在尝试让一个简单的 Iron 示例起作用: extern crate iron; extern crate router; use iron::prelude::*; use iron::stat
我正在尝试使用嵌套字典“动态”创建一个数据输入表单(目前,我使用具有 3 个值的数组,但将来数组中的元素数量可能会有所不同)。这似乎工作正常,并且表单“正确”渲染了 html 模板(正确 = 我看到了
从 ASP.NET 中的代码隐藏访问表单或查询字符串值时,使用的优缺点是什么,例如: // short way string p = Request["param"]; 代替: // long way
我遇到了一个问题,我想知道更好的解决方法。 有五个 api 请求并行运行,第二个请求依赖于第四个请求的响应,但所有 5 个请求都已在运行。什么是更好的方法? 需要建议。提前致谢。 最佳答案 调度地面工
我收到以下错误:TypeError:序列项 0:预期字节、字节数组或具有缓冲区接口(interface)的对象、找到元组 我检查了Python文档,urllib.request.Request的参数似
当我向函数添加超时参数时,我的代码总是进入异常并打印出“我失败了”。当我删除超时参数时,代码会正常工作,并进入 try 子句。关于超时参数如何在 urllib.request 函数中工作的任何信息?
我使用 cURL 向服务器发送请求这是链接:Server Side script for cURL request我用 file_get_contents('php://input'); 读取发送的数
请大家帮帮我我正在尝试使用 NUTCH 抓取网站,但它给我错误“java.io.IOException: Job failed!” 我正在运行此命令“bin/nutch solrindex http:
在我的 AngularJS 应用程序中,我无法弄清楚如何对 then promise 的执行更改 location.url 进行单元测试。我有一个函数,登录 ,调用服务,身份验证服务 .它返回 pro
我是一名优秀的程序员,十分优秀!