[go-nuts] How to prevent net/http from canonicalizing request paths?
Hi there, the code in https://github.com/golang/go/blob/go1.8/src/net/http/server.go#L2197 is canonicalizing the request paths such that if you get /foo//bar you get a 301 redirect to /foo/bar. While this is generally what you want, I am dealing with an unfortunate case where /foo//bar and /foo/bar are not the same resource (and lot’s not argue about why) and I couldn’t find an easy way to circumvent this behavior without completely replacing the ServeMux. Am I missing something and there is a better way? I should specify also that my handler is just for the prefix /foo and that I cannot explicitly register a handler for each possible path where this problem exists under /foo. -- Benoit "tsuna" Sigoure -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] 2.5x higher memory usage with go1.8rc2
I reproduced this issue several times on Jan 24, but for some reason that still eludes me right now, I can’t reproduce it anymore. Must be PEBCAK. I’ll report back if I can reproduce it again and have some evidence to share. On Thu, Jan 26, 2017 at 1:27 PM, Aurélien Bombo <abom...@gmail.com> wrote: > Any update on this? I'm curious. > > > > > Aurélien Bombo > > 2017-01-24 23:20 GMT+01:00 tsuna <tsuna...@gmail.com>: >> >> Hi there, >> I have a linux/386 production binary that I compiled and deployed with >> go1.8rc2 and I noticed that the RSS is 2.5x of the same binary doing >> the same thing but compiled with go1.7.3. Anybody else noticed this >> already? It’s a fairly large/complex binary, so I can’t quite say >> what could be causing this without taking some more time to look at >> profiling data, which I’m happy to do if nobody else has already >> seen/reported this. >> >> Also is there a tool that can parse/summarize heap dumps produced by >> go1.8? Is the format in 1.8 still heapdump15? The last time I looked >> at this (admittedly some time ago) I couldn’t find an updated tool >> that groked heapdump15. >> >> -- >> Benoit "tsuna" Sigoure >> >> -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golang-nuts+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. > > -- Benoit "tsuna" Sigoure -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[go-nuts] 2.5x higher memory usage with go1.8rc2
Hi there, I have a linux/386 production binary that I compiled and deployed with go1.8rc2 and I noticed that the RSS is 2.5x of the same binary doing the same thing but compiled with go1.7.3. Anybody else noticed this already? It’s a fairly large/complex binary, so I can’t quite say what could be causing this without taking some more time to look at profiling data, which I’m happy to do if nobody else has already seen/reported this. Also is there a tool that can parse/summarize heap dumps produced by go1.8? Is the format in 1.8 still heapdump15? The last time I looked at this (admittedly some time ago) I couldn’t find an updated tool that groked heapdump15. -- Benoit "tsuna" Sigoure -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Re: Efficient ForEach() on a map protected by a mutex
On Sat, Jan 7, 2017 at 7:00 PM, 'Keith Randall' via golang-nuts < golang-nuts@googlegroups.com> wrote: > > > On Friday, January 6, 2017 at 5:12:54 PM UTC-8, tsuna wrote: >> >> Hi there, >> I have a struct that contains an unexported map protected by a mutex, >> let’s say something like: >> >> type Map struct { >> mtx sync.Mutex >> col map[string]interface{} >> } >> >> I want to implement a ForEach method that works in O(1) space and >> doesn’t hold the mutex while working on each entry. This is what I have: >> >> func (m *Map) ForEach(fn func(k, v interface{})) { >> m.mtx.Lock() >> for k, v := range m.col { >> m.mtx.Unlock() >> fn(k, v) >> m.mtx.Lock() >> } >> m.mtx.Unlock() >> } >> >> (runnable example: https://play.golang.org/p/tX2lCCYWxq) >> >> The language spec <https://golang.org/ref/spec#For_statements> says: >> >>> 3. The iteration order over maps is not specified and is not guaranteed >>> to be the same from one iteration to the next. If map entries that have not >>> yet been reached are removed during iteration, the corresponding iteration >>> values will not be produced. If map entries are created during iteration, >>> that entry may be produced during the iteration or may be skipped. The >>> choice may vary for each entry created and from one iteration to the next. >>> If the map is nil, the number of iterations is 0. >> >> >> With the caveats mentioned above regarding concurrent >> deletions/insertions in mind, is this implementation of ForEach correct? >> Is there a better way? >> >> > I'm not sure I understand what you're trying to guarantee. > That the code is race-free. The guarantees on data access are pretty loose – fn() could be called on a key-value pair while it’s being removed/changed by another goroutine. That’s okay. > The code you've shown looks fine, but the devil is in the details of what > fn does. > > The fundamental constraint is that you need to make sure that no two > concurrent operations, at least one of which is a write, happen to the > map. Treat iteration as a read. And it isn't one read extending for the > whole loop. It is one "instantaneous" read each time a new k,v is assigned. > So fn can read all it wants. > If fn writes, those writes must be synchronized so that they do not happen > concurrently with the ForEach goroutine iterating. > So if fn writes in the same goroutine that ForEach is running in, that is > fine. > If fn spawns other goroutines to write to the map, asks other goroutines > to write to the map via channels, etc. then those accesses must be properly > synchronized. > One way to do that is to use the same lock as you used in ForEach around > those accesses. > Yes, that’s exactly what’s happening. The contrived example I showed only included ForEach(), but I also have Get(k) and Set(k, v) methods on this struct, which can be called concurrently from other goroutines. Of course they also acquire the same mutex. Alright, so thanks for checking this wasn’t insane. The code looks weird, but it is what it is. -- Benoit "tsuna" Sigoure -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[go-nuts] Efficient ForEach() on a map protected by a mutex
Hi there, I have a struct that contains an unexported map protected by a mutex, let’s say something like: type Map struct { mtx sync.Mutex col map[string]interface{} } I want to implement a ForEach method that works in O(1) space and doesn’t hold the mutex while working on each entry. This is what I have: func (m *Map) ForEach(fn func(k, v interface{})) { m.mtx.Lock() for k, v := range m.col { m.mtx.Unlock() fn(k, v) m.mtx.Lock() } m.mtx.Unlock() } (runnable example: https://play.golang.org/p/tX2lCCYWxq) The language spec <https://golang.org/ref/spec#For_statements> says: > 3. The iteration order over maps is not specified and is not guaranteed to > be the same from one iteration to the next. If map entries that have not > yet been reached are removed during iteration, the corresponding iteration > values will not be produced. If map entries are created during iteration, > that entry may be produced during the iteration or may be skipped. The > choice may vary for each entry created and from one iteration to the next. > If the map is nil, the number of iterations is 0. With the caveats mentioned above regarding concurrent deletions/insertions in mind, is this implementation of ForEach correct? Is there a better way? Thanks. -- Benoit "tsuna" Sigoure -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.