mirror of
https://github.com/waku-org/nwaku.git
synced 2025-01-16 01:45:40 +00:00
115 lines
2.9 KiB
Nim
115 lines
2.9 KiB
Nim
|
import locks, macros, tables
|
||
|
from options import LogLevel
|
||
|
|
||
|
export
|
||
|
LogLevel
|
||
|
|
||
|
type
|
||
|
TopicState* = enum
|
||
|
Normal,
|
||
|
Enabled,
|
||
|
Required,
|
||
|
Disabled
|
||
|
|
||
|
TopicSettings* = object
|
||
|
state*: TopicState
|
||
|
logLevel*: LogLevel
|
||
|
|
||
|
TopicsRegisty* = object
|
||
|
topicStatesTable*: Table[string, ptr TopicSettings]
|
||
|
|
||
|
var
|
||
|
registryLock: Lock
|
||
|
gActiveLogLevel {.guard: registryLock.}: LogLevel
|
||
|
gTotalEnabledTopics {.guard: registryLock.}: int
|
||
|
gTotalRequiredTopics {.guard: registryLock.}: int
|
||
|
gTopicStates {.guard: registryLock.} = initTable[string, ptr TopicSettings]()
|
||
|
|
||
|
when compileOption("threads"):
|
||
|
var mainThreadId = getThreadId()
|
||
|
|
||
|
initLock(registryLock)
|
||
|
|
||
|
template lockRegistry(body: untyped) =
|
||
|
when compileOption("threads"):
|
||
|
withLock registryLock: body
|
||
|
else:
|
||
|
body
|
||
|
|
||
|
proc setLogLevel*(lvl: LogLevel) =
|
||
|
lockRegistry:
|
||
|
gActiveLogLevel = lvl
|
||
|
|
||
|
proc clearTopicsRegistry* =
|
||
|
lockRegistry:
|
||
|
gTotalEnabledTopics = 0
|
||
|
gTotalRequiredTopics = 0
|
||
|
for val in gTopicStates.values:
|
||
|
val.state = Normal
|
||
|
|
||
|
proc registerTopic*(name: string, topic: ptr TopicSettings): ptr TopicSettings =
|
||
|
# As long as sequences are thread-local, modifying the `gTopicStates`
|
||
|
# sequence must be done only from the main thread:
|
||
|
when compileOption("threads"):
|
||
|
doAssert getThreadId() == mainThreadId
|
||
|
|
||
|
lockRegistry:
|
||
|
gTopicStates[name] = topic
|
||
|
return topic
|
||
|
|
||
|
proc setTopicState*(name: string,
|
||
|
newState: TopicState,
|
||
|
logLevel = LogLevel.NONE): bool =
|
||
|
lockRegistry:
|
||
|
if not gTopicStates.hasKey(name):
|
||
|
return false
|
||
|
|
||
|
var topicPtr = gTopicStates[name]
|
||
|
|
||
|
case topicPtr.state
|
||
|
of Enabled: dec gTotalEnabledTopics
|
||
|
of Required: dec gTotalRequiredTopics
|
||
|
else: discard
|
||
|
|
||
|
case newState
|
||
|
of Enabled: inc gTotalEnabledTopics
|
||
|
of Required: inc gTotalRequiredTopics
|
||
|
else: discard
|
||
|
|
||
|
topicPtr.state = newState
|
||
|
topicPtr.logLevel = logLevel
|
||
|
|
||
|
return true
|
||
|
|
||
|
proc topicsMatch*(logStmtLevel: LogLevel,
|
||
|
logStmtTopics: openarray[ptr TopicSettings]): bool =
|
||
|
lockRegistry:
|
||
|
var
|
||
|
hasEnabledTopics = gTotalEnabledTopics > 0
|
||
|
enabledTopicsMatch = false
|
||
|
normalTopicsMatch = logStmtTopics.len == 0 and logStmtLevel >= gActiveLogLevel
|
||
|
requiredTopicsCount = gTotalRequiredTopics
|
||
|
|
||
|
for topic in logStmtTopics:
|
||
|
let topicLogLevel = if topic.logLevel != NONE: topic.logLevel
|
||
|
else: gActiveLogLevel
|
||
|
if logStmtLevel >= topicLogLevel:
|
||
|
case topic.state
|
||
|
of Normal: normalTopicsMatch = true
|
||
|
of Enabled: enabledTopicsMatch = true
|
||
|
of Disabled: return false
|
||
|
of Required: normalTopicsMatch = true; dec requiredTopicsCount
|
||
|
|
||
|
if requiredTopicsCount > 0:
|
||
|
return false
|
||
|
|
||
|
if hasEnabledTopics and not enabledTopicsMatch:
|
||
|
return false
|
||
|
|
||
|
return normalTopicsMatch
|
||
|
|
||
|
proc getTopicState*(topic: string): ptr TopicSettings =
|
||
|
lockRegistry:
|
||
|
return gTopicStates.getOrDefault(topic)
|
||
|
|