norm icon indicating copy to clipboard operation
norm copied to clipboard

Error: 'matchIter' is not GC-safe as it calls 'insert'

Open d0rksh opened this issue 1 year ago • 5 comments

hi i was trying to create a jester app with SQLite as a database, when i try to compile the code with --threads:on compiler throws a error

code:

post "/api/adddomain":
      var domain = parseJson(request.body)
      var domains =   domain.to(Domain)
      var ins = Monitor(domain: domains.domain ,discard_webhook:domains.hook)
      try:
          dbConn.insert(ins)
          var jsonResp = $(%*{"message": "success","id":ins.id,"domain":domains.domain,"hook":domains.hook})
          resp Http200, jsonResp

var jester1 = initJester()
jester1.serve()

error when i compile with --threads:on sr/lib/nim/pure/asyncmacro.nim(200, 31) Error: 'matchIter' is not GC-safe as it calls 'insert'

d0rksh avatar Aug 18 '22 12:08 d0rksh

I'm not entirely sure if it's on norm to deal with this, but here on how to deal with this for the time being:

d0rksh, all the compiler is seeing is that you're accessing a "global" resource ultimately with a db.exec command. We know that it is fine since the database will have locks implemented and the like, but the compiler doesn't. So we can cast the corresponding expression as gc-safe to tell the compiler that "Yeah, you found something that might not be GC-safe but I've personally figured out that it's fine".. Example: '

proc createEntry*[T: Model](connection: DbConn, entry: var T): T =
      {.cast(gcsafe).}:
          connection.insert(entry)
          result = entry

PhilippMDoerner avatar Aug 19 '22 05:08 PhilippMDoerner

thank you its working now :)

d0rksh avatar Aug 19 '22 06:08 d0rksh

@moigagoo There is a valid point in here though: Should norm's currently non-gcsafe-procs be cast as gcsafe so that the compiler doesn't notice them as gc-unsafe in multi-threaded projects of norm-users? Or is that information that we want the user to have?

PhilippMDoerner avatar Aug 19 '22 06:08 PhilippMDoerner

Should norm's currently non-gcsafe-procs be cast as gcsafe so that the compiler doesn't notice them as gc-unsafe in multi-threaded projects of norm-users?

When using Norm with Prologue, I just mark my controller procs gcsafe explicitly to make the compiler happy, for example:

proc getUpdates*(ctx: Context) {.async, gcsafe.} =

So, there is at least a less hacky way of solving the problem than cast.

moigagoo avatar Aug 23 '22 08:08 moigagoo

I entirely agree that it's an easy problem to solve it's mostly a question on whether to have this convenience factor (of making the corresponding norm procs explicitly gc-safe so users downstream don't have to make their own procs explicitly gcsafe) or not.

Am I interpreting you correctly that you're currently erring on the side of not doing it (which is perfectly valid, I myself have no preference either way, just thought it might be valid to discuss)?

PhilippMDoerner avatar Aug 23 '22 10:08 PhilippMDoerner

@PhilippMDoerner I've just tried adding {.gcsafe.} to insert and that doesn't solve the issue. You still have to mark your Plologue procs as GC-safe to make the compiler happy.

moigagoo avatar Oct 10 '22 07:10 moigagoo