Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backend][Reentrant] Introduce Reentrant Backend #96

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

nplanel
Copy link
Contributor

@nplanel nplanel commented Mar 27, 2016

Level and memory backend are read mostly, so atomic value can a very
limited effect on performance; Only write map acces need to be done under
Mutex.

Now Backend loggers could be called from multiple goroutine.

Tests validated with : go test -v -race ./...

nplanel added 2 commits March 24, 2016 19:33
atomic.SwapPointer() is the only way to retrieve the old value atomically.
Level and memory backend are read mostly, so atomic value can a very
limited effect on performance; Only write map acces need to be done under
Mutex.

Now Backend loggers could be called from multiple goroutine.

Tests validated with : go test -v -race ./...
@nplanel
Copy link
Contributor Author

nplanel commented Mar 27, 2016

It's seems you testing your code with very old golang version, atomic.Value request Golang >= 1.4

@nplanel
Copy link
Contributor Author

nplanel commented Apr 7, 2016

@op : Did you have time to look my patch ?

@op
Copy link
Owner

op commented Apr 20, 2016

@nplanel Sorry for the silence. Been very busy lately. Will try to get some time.

@nplanel
Copy link
Contributor Author

nplanel commented Apr 21, 2016

@op ok no pb, If you look at the commit, one is a bugfix that you can apply/cherry-pick today.

@nplanel
Copy link
Contributor Author

nplanel commented Jun 2, 2016

@op Any update ?

levels := l.levels.Load().(moduleLeveledMap)
l.lock.Lock()
levels[module] = level
l.lock.Unlock()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could be wrong, but looks like the levels map is being modified, yet the reader in GetLevel is not underneath a lock so this can race the read and the write.

Maybe there's a way to even get rid of the map lookup in regular logging. Maybe GetLevel needs to return a pointer or sync.Value. And the IsEnabledFor can cache that (it is never removed)

@driskell
Copy link

I thought I'd help out with some reviewing. Really would love to be able to set levels for all the loggers from a single routine. I'm thinking reloading configuration to enable debug logging - that would make diagnostics so much easier when a problem is happening.

I did have some concern with the handling though as it seems there may still be a race on the levels map. Not sure best way to get around that - but my first thought is why do we need to map lookup? Maybe each Logger need to pull in the level via sync.Value and it can access it there. Then it is fine to wrap the map in sync.Mutex since it'll only ever be used to lookup and set levels initially, and never during actual log calls (I think!)

sync.end.Add(10)
sync.start.Add(10)
for i := 0; i < 10; i++ {
go testConcurrent_Log(i, sync, &lvlBackend, log)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concurrent use of GetLevel with SetLevel is not under test here I think. Thus why the go test -race probably isn't picking up the concurrent read/write access to the levels map

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants