mashingan/anonimongo

GC-safe implementation ?

UNIcodeX opened this issue · 2 comments

code:

import strformat

import jester
import json
import oids

import anonimongo

var
  connString = "mongodb://lnAdmin:testPass!@localhost:27017/DB?authSource=admin"
  mongo {.threadvar.} : Mongo
  db {.threadvar.} : Database

mongo = newMongo()

mongo = newMongo(MongoUri(connString))

if not waitfor mongo.connect:
  quit "Cannot connect to domain-host"
else:
  echo "MongoDB: Connected!"

if not waitfor mongo.authenticate[:Sha256Digest]():
  echo "MongoDB: Could not authenticate with SHA256. Trying SHA1. You should really update MongoDB!"
  if not waitfor mongo.authenticate[:SHA1Digest]():
    quit "Cannot login to domain-host"
  else:
    echo "MongoDB: Authenticated with SHA1. This is not secure."
else:
  echo "MongoDB: Authenticated with SHA256!"

db = mongo["DB"]

settings:
  port = Port(8000)
  staticDir = "static"

routes:
  get "/getColl":
    let pipeline = @[
      bson({ 
        "$match": 
          { active: true } 
        }), 
      bson({
        "$project": {
          "id": {
            "$toString": "$_id"
          },
          "_id": 0,  
          "fieldOne": 1, 
          "fieldTwo": 1
        }
      })
    ]
    let coll = mongo["DB"]["coll"]
    let res = await coll.aggregate(pipeline)
    var seqDocs: seq[JsonNode]
    for doc in res:
      seqDocs.add(parseJson($doc))
    resp %seqDocs

close mongo

building with nim c -r -d:release -d:danger --threads:on {file}.nim results in an error saying $ is not GC-safe:

/home/jedi/.nimble/pkgs/jester-0.4.3/jester.nim(1277, 9) Hint: Asynchronous route: match. [User]
/home/jedi/Repositories/sandbox/nmain.nim(43, 1) template/generic instantiation of `routes` from here
/home/jedi/.nimble/pkgs/jester-0.4.3/jester.nim(1283, 35) template/generic instantiation of `async` from here
/home/jedi/.nimble/pkgs/anonimongo-0.4.2/anonimongo/core/bson.nim(574, 6) Warning: '$' is not GC-safe as it calls '$' [GcUnsafe2]
/home/jedi/Repositories/sandbox/nmain.nim(43, 1) template/generic instantiation of `routes` from here
/home/jedi/.nimble/pkgs/jester-0.4.3/jester.nim(1283, 35) template/generic instantiation of `async` from here
/home/jedi/.choosenim/toolchains/nim-1.2.6/lib/pure/asyncmacro.nim(278, 31) Error: 'matchIter' is not GC-safe as it calls '$'

And if I comment out the following lines before the route returns to see if it works without conversion of document to string for parsing into JSON...

# commented to test no `$` conversion operations
# for doc in res:
#       seqDocs.add(parseJson($doc))

I get the following stack trace saying aggregate is not GC-safe

/home/jedi/.nimble/pkgs/jester-0.4.3/jester.nim(1277, 9) Hint: Asynchronous route: match. [User]
/home/jedi/Repositories/sandbox/nmain.nim(43, 1) template/generic instantiation of `routes` from here
/home/jedi/.nimble/pkgs/jester-0.4.3/jester.nim(1283, 35) template/generic instantiation of `async` from here
/home/jedi/.choosenim/toolchains/nim-1.2.6/lib/pure/asyncmacro.nim(318, 24) Warning: 'aggregateNimAsyncContinue' is not GC-safe as it accesses 'nameIterVar`gensym36810069' which is a global using GC'ed memory [GcUnsafe2]
/home/jedi/Repositories/sandbox/nmain.nim(43, 1) template/generic instantiation of `routes` from here
/home/jedi/.nimble/pkgs/jester-0.4.3/jester.nim(1283, 35) template/generic instantiation of `async` from here
/home/jedi/.nimble/pkgs/anonimongo-0.4.2/anonimongo/collections.nim(282, 6) Warning: 'aggregate' is not GC-safe as it calls 'aggregateNimAsyncContinue' [GcUnsafe2]
/home/jedi/Repositories/sandbox/nmain.nim(43, 1) template/generic instantiation of `routes` from here
/home/jedi/.nimble/pkgs/jester-0.4.3/jester.nim(1283, 35) template/generic instantiation of `async` from here
/home/jedi/.choosenim/toolchains/nim-1.2.6/lib/pure/asyncmacro.nim(278, 31) Error: 'matchIter' is not GC-safe as it calls 'aggregate'

removing --threads:on works fine.

The current Anonimongo implementation is indeed couldn't be said GC-safe. I'm looking a way how to do the threading with async together.

Just had a chance to look at this again, simply provided with pragma gcsafe is enough apparently, but please do report this kind of case if there are other problems. Thanks.