I have these let variables
from os import getEnv
from strutils import parseInt, isEmptyOrWhitespace
let
SERVER_HOST* : string = block :
var host : string = "localhost" ## default host localhost
let env_host = getEnv("HOST")
if not env_host.isEmptyOrWhitespace():
host = env_host
host
SERVER_PORT* : int = block :
var port : int = 5000 ## default port 5000
let env_port = getEnv("PORT")
if not env_port.isEmptyOrWhitespace():
port = parseInt(env_port)
port
MONGO_HOST* : string = block :
var host : string = "localhost" ## default host localhost
let env_host = getEnv("MONGO_HOST")
if not env_host.isEmptyOrWhitespace():
host = env_host
host
MONGO_PORT* : int = block :
var port : int = 27017 ## default port 27017
let env_port = getEnv("MONGO_PORT")
if not env_port.isEmptyOrWhitespace():
port = parseInt(env_port)
port
RATE_LIMIT* : int = block :
var limit : int = 200 ## default limit 200 calls
let env_limit = getEnv("RATE_LIMIT")
if not env_limit.isEmptyOrWhitespace():
limit = parseInt(env_limit)
limit
LIMIT_FREQ* : int = block :
var freq : int = 60 ## default freq 60 seconds
let env_freq = getEnv("LIMIT_FREQ")
if not env_freq.isEmptyOrWhitespace():
freq = parseInt(env_freq)
freq
These variables are declared in a separate file from where they would be used because i want to avoid re declaring them again. I need to call these variables in a proc that would be spawned by the threadpool library but the nim compiler says they are not gc safe even though let variables are immutable. I also tried using the isolation library but because the isolate proc only accepts var variables i can't. Is there a reason the compiler finds let variables to not be gc safe or is this a bug? By the way here is a part of the proc from which i called the variables
proc server() {.gcsafe.} =
let mongo = newMongo[AsyncSocket](MongoUri fmt"mongodb://{MONGO_HOST}:{MONGO_PORT}/")
mongo.noSlave()
if not waitFor mongo.connect():
fatal(fmt"Failed to bind to mongodb on host {MONGO_HOST} at port {MONGO_PORT}")
info("Quiting...")
quit(QuitFailure)
let db = mongo["blog_db"]
settings:
port = Port SERVER_PORT
bindAddr = SERVER_HOST
So after going through the nim manual i found out that you can overide the compilers gc safe analysis to assign non gc safe variables to local proc variables like so
{.cast(gcsafe).}:
let
SERVER_HOST = SERVER_HOST
SERVER_PORT = SERVER_PORT
MONGO_HOST = MONGO_HOST
MONGO_PORT = MONGO_PORT
This still feels illegal though but since the global variables are immutable i think all is wellAnother option, if this is a microservice where changes in configuration can come with a recompilation:
const
SERVER_HOST* {.strdefine.} = "localhost"
SERVER_PORT* {.intdefine.} = 5000
proc test {.gcsafe.} =
echo (SERVER_HOST, SERVER_PORT)
when isMainModule:
test()